geänderte Daten aus Textboxen in einer DatenTabelle in eine Datenbank updaten

  • WPF

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    geänderte Daten aus Textboxen in einer DatenTabelle in eine Datenbank updaten

    Es geht um fehlenden UPDAT Code (am Ende)
    Ich habe eine DataGridView, die in einigen Zellen Zahlen mit einem # enthalten.
    Das sind die Zellen, die auf Datensätze verweisen.
    Diese Datensätze sollen geändert werden.
    Das DataGridView ist auf der linken Seite.

    Text-, Combo-Boxen und DateTimePickes auf der rechten Seite.

    45# | 890# | empty cell |cell ..........
    ----------------------------------------------------------

    Globale Definitionen

    VB.NET-Quellcode

    1. Public Class frmKalenderAnzeigen
    2. Private BindingSource As New BindingSource
    3. Private DataAdapter1 As New Odbc.OdbcDataAdapter
    4. Dim myTable As New DataTable
    5. Dim conn As New OdbcConnection


    Im Form-Load Event binde ich die Text-/Combo-Boxen und DataTimePickers an eine Tabelle, myTable. Die Daten kommen von einer MySql Datenbank, die über eine ODBC Verbindung an das Programm angebunden ist
    conn.ConnectionString = "Dsn=mis"

    ...........

    Das Load-Ereignis des Formulars

    VB.NET-Quellcode

    1. [/b]Dim strSql As String = "SELECT * FROM tbl_kal_termine limit 1"
    2. DataAdapter1 = New OdbcDataAdapter(strSql, conn)
    3. DataAdapter1.Fill(myTable)
    4. txtID.DataBindings.Add("TEXT", myTable, "terID")
    5. txtVon.DataBindings.Add("TEXT", myTable, "terVon")
    6. txtBis.DataBindings.Add("TEXT", myTable, "terBis")
    7. txtWas.DataBindings.Add("TEXT", myTable, "terWas")
    8. txtWo.DataBindings.Add("TEXT", myTable, "terWo")
    9. txtMehr.DataBindings.Add("TEXT", myTable, "terKommentar")
    10. DateTimePicker.DataBindings.Add("TEXT", myTable, "terDatum")
    11. cboAuftrag.DataBindings.Add("TEXT", myTable, "terAuftragId")
    12. cboWer.DataBindings.Add("TEXT", myTable, "terWerID")
    13. myTable.Clear()[b]


    Jetzt kann man in eine Zelle in der DataGridView anklicken –
    sollte eine Zahl, die mit einem # endet, dann soll dies Zahl dazu dienen,
    den zu ändernen Datensatz zu finden und in die Felder auf der rechten Seite anzeigen.

    Der Anwender kann jetzt die Daten ändern.

    VB.NET-Quellcode

    1. Private Sub dataGridView1_CellClick(ByVal sender As Object,
    2. ByVal e As DataGridViewCellEventArgs) _
    3. Handles DataGridView1.CellClick
    4. ' this event comes from a klick on a dataGridView cell.
    5. ' either the cell is empty or has not number followed by a #, We do not need to continue
    6. Dim cell As String
    7. ' an empty cell?
    8. Try
    9. cell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
    10. Catch ex As Exception
    11. 'an empty cell!
    12. myTable.Clear()
    13. Exit Sub
    14. End Try
    15. 'If a cell has a number with a # in it, We will continuge
    16. If cell.ToString.IndexOf("#") < 0 Then
    17. myTable.Clear()
    18. Exit Sub
    19. End If
    20. ' The table has been created in the load event of the form.
    21. ' all textboxes, comboboxes and datetimepickers have been linked to this table
    22. ' because I will focus on a total different set for the table, I need to clear the table first
    23. myTable.Clear()
    24. 'Set up the SQL String to the record and retrieve it from the odbc Database.
    25. Dim strSql As String = "SELECT * FROM tbl_kal_termine where terID = " & cell.Substring(0, cell.IndexOf("#"))
    26. ' fill myTable using the sql-String
    27. DataAdapter1 = New OdbcDataAdapter(strSql, conn)
    28. DataAdapter1.Fill(myTable)
    29. 'Erstelle einen Commandbuilder für Insert, Update und Delete
    30. 'Dim commandbuilder1 As New OdbcCommandBuilder(DataAdapter1)
    31. If myTable.Rows.Count <> 0 Then
    32. ' all textboxes, comboboxes and datetimepickers are filled!
    33. BindingSource1.DataSource = myTable
    34. 'Allow the table to accept changes from the textboxes, comboboxes and datetimepickers
    35. myTable.AcceptChanges()
    36. Else
    37. MsgBox("no data")
    38. End If

    Bis hier ist alles in Ordnung.
    Nach der Änderung der Daten drückt der Benutzer den Update-Button

    VB.NET-Quellcode

    1. Private Sub Update_Click(sender As Object, e As EventArgs) Handles Update.Click
    2. 'to test what Is in row And each cell in the table myTable
    3. 'I see the changes I made in the myTable table / in each cell
    4. Dim txt As String = ""
    5. For Each row In myTable.Rows
    6. For Each column In myTable.Columns
    7. Console.Write(vbTab & row(column.ColumnName).ToString)
    8. txt = row(column.ColumnName).ToString
    9. Next
    10. Next row
    11. ' Ich sehe, dass alle Veränderungen in MyTable enthalten sind
    12. ' #########################################
    13. ' Welchen Code brauche ich um ein Update durchzuführen?
    14. #########################################
    15. End Sub


    Ich zeige lieber nicht meine Versuche – sie waren alle nicht erfolgreich


    Vielen Dank für Hilfe

    Bruno
    Das Dgv_CellClick-Gedöhns brauchst du nicht.
    Bei Databinding geschieht das alles automatisch - gradezu durch zauberhand. Lösch den ganzen Kram - du wirst sehen.

    Zum Updaten wäre von deim Kram ausgehend am einfachsten, du würdest mit deinem DataAdapter einen CommandBuilder erstellen. So ein CommandBuilder tut nichts - allein durch das Erstellen legt er das richtige Update-Command in deinem DataAdapter an.

    Updaten geht dann so:

    VB.NET-Quellcode

    1. DataAdapter1.Update(myDataTable)


    Evtl. gehen dann die Probleme aber erst los, nämlich die Datenbank muss Primärschlüssel definiert haben, sonst kann prinzipiell kein Datensatz geupdated werden.

    Ein anderes Problem entsteht beim Inserten neuer Datensätze - aber eins nach dem anderen - jetzt erstmal updaten.
    Kommt beim Coden auch immer bischen drauf an, wo bestimmte Codezeilen stehen.
    Und das kann ich mangels hellseherischer Fähigkeiten grad nicht so gut erkennen.

    Sorry - bin gemein :evil:

    Also zu Code kann man am besten was sagen, wenn ich die Deklarationen der Objekte sehe, und die Methoden, wo sie dann initialisiert und konfiguriert, und die anderen Methoden, wo sie dann verwendet werden.
    Am liebsten ganze Methoden.
    Konkret spreche ich vom DataAdapter - wie du ihn mittm CommandBuilder konfigurierst sieht übrigens nicht verkehrt aus.

    Dem entgegen steht gelegentlich die pure Masse, aber bei som klein "lade Daten / speicher Daten" Förmchen denkich, dasses machbar ist.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    VB.NET-Quellcode

    1. Imports System.Data.Odbc
    2. Public Class frmKalenderAnzeigen
    3. Private BindingSource As New BindingSource
    4. Private DataAdapter1 As New Odbc.OdbcDataAdapter
    5. Dim myTable As New DataTable
    6. Dim conn As New OdbcConnection
    7. 'Dim commandBuilder2 As OdbcCommandBuilder
    8. Private Sub ZurückToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ZurückToolStripMenuItem.Click
    9. conn.Close()
    10. Me.Close()
    11. End Sub
    12. Private Sub frmKalenderAnzeigen_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    13. FlowLayoutPanelLeft.Width = Me.Width * 0.7
    14. With DataGridView1
    15. .Top = FlowLayoutPanelLeft.Top + 2
    16. .Left = FlowLayoutPanelLeft.Left + 2
    17. .Width = FlowLayoutPanelLeft.Width - 16
    18. .Height = FlowLayoutPanelLeft.Height - 16
    19. End With
    20. Try
    21. 'build up a connection
    22. conn.ConnectionString = "Dsn=mis"
    23. conn.Open()
    24. Catch ex As Exception
    25. MsgBox("Error on Connection" & vbCrLf & ex.Message)
    26. Me.Close()
    27. End Try
    28. ' Fülle Kalender
    29. get_Calendar() 'conn will be set there
    30. ' +++++++++++++++++++++++++++++++ rechte Seite
    31. ' cboWer wird gefüllt
    32. 'Dim strSql As String = " "
    33. 'Dim DataReader As OdbcDataReader
    34. 'strSql = "SELECT * from tbl_kal_wer"
    35. 'With cboWer
    36. ' Using cmd As New OdbcCommand(strSql, conn)
    37. ' DataReader = cmd.ExecuteReader
    38. ' ' Jeden einzelnen Datensatz abarbeiten
    39. ' While DataReader.Read
    40. ' .Items.Add(DataReader("wer_ID").ToString)
    41. ' End While
    42. ' .SelectedIndex = 1
    43. ' End Using
    44. 'End With
    45. '' Auftraggeber füllen
    46. 'strSql = "SELECT * from tbl_kal_Auftraggeber"
    47. 'With cboAuftrag
    48. ' Using cmd As New OdbcCommand(strSql, conn)
    49. ' DataReader = cmd.ExecuteReader
    50. ' ' Jeden einzelnen Datensatz abarbeiten
    51. ' While DataReader.Read
    52. ' .Items.Add(DataReader("aufAuftragID").ToString)
    53. ' End While
    54. ' .SelectedIndex = 1
    55. ' End Using
    56. 'End With
    57. 'cboWerkTag.SelectedItem = 1
    58. ' rechten Teil binden
    59. Dim strSql As String = "SELECT * FROM tbl_kal_termine limit 1"
    60. DataAdapter1 = New OdbcDataAdapter(strSql, conn)
    61. DataAdapter1.Fill(myTable)
    62. txtID.DataBindings.Add("TEXT", myTable, "terID")
    63. txtVon.DataBindings.Add("TEXT", myTable, "terVon")
    64. txtBis.DataBindings.Add("TEXT", myTable, "terBis")
    65. txtWas.DataBindings.Add("TEXT", myTable, "terWas")
    66. txtWo.DataBindings.Add("TEXT", myTable, "terWo")
    67. txtMehr.DataBindings.Add("TEXT", myTable, "terKommentar")
    68. DateTimePicker.DataBindings.Add("TEXT", myTable, "terDatum")
    69. cboAuftrag.DataBindings.Add("TEXT", myTable, "terAuftragId")
    70. cboWer.DataBindings.Add("TEXT", myTable, "terWerID")
    71. myTable.Clear()
    72. End Sub
    73. Sub get_Calendar()
    74. ' table headerHeader
    75. Dim Table As New DataTable
    76. With Table.Columns
    77. .Add(New DataColumn("KW", GetType(String)))
    78. .Add(New DataColumn("Wer", GetType(String)))
    79. .Add(New DataColumn("Mo", GetType(String)))
    80. .Add(New DataColumn("Di", GetType(String)))
    81. .Add(New DataColumn("Mi", GetType(String)))
    82. .Add(New DataColumn("Do", GetType(String)))
    83. .Add(New DataColumn("Fr", GetType(String)))
    84. .Add(New DataColumn("Sa", GetType(String)))
    85. .Add(New DataColumn("So", GetType(String)))
    86. End With
    87. 'für jede Datumszeile den Inhalt holen (steht in tbl_kal_wochen
    88. Dim strSql As String = "SELECT * FROM tbl_kal_woche "
    89. Dim DataReader As OdbcDataReader
    90. Dim Row As DataRow = Table.NewRow
    91. Using cmd As New OdbcCommand(strSql, conn)
    92. DataReader = cmd.ExecuteReader
    93. ' Jeden einzelnen Datensatz abarbeiten
    94. Dim off As Integer = 7
    95. While DataReader.Read
    96. Row("kw") = DataReader(0).ToString
    97. Row("Mo") = DataReader(1 + off).ToString
    98. Row("Di") = DataReader(2 + off).ToString
    99. Row("Mi") = DataReader(3 + off).ToString
    100. Row("Do") = DataReader(4 + off).ToString
    101. Row("Fr") = DataReader(5 + off).ToString
    102. Row("Sa") = DataReader(6 + off).ToString
    103. Row("So") = DataReader(7 + off).ToString
    104. ' Diese Zeile der Tabellehinzufügen
    105. Table.Rows.Add(Row)
    106. ' fülle array
    107. ' gibt es zu dieser Woche Termine
    108. Dim Result As New ArrayList()
    109. Result = Termine_Fuer_Diese_KW(DataReader(0).ToString)
    110. ' Alle Datensätze verarbeiten, also Pro Jahr, Woche, Wer
    111. 'finde den ersten Datensatz
    112. Dim bolFirst As Boolean = True ' Erster Datensatz?
    113. Dim bolAdded As Boolean = False ' es wurde was hinzugefügt
    114. Dim tmpWer As String = ""
    115. For Each Rec As Dictionary(Of String, Object) In Result
    116. If bolFirst Then 'den ersten Datensatz finden und dort den Inhalt von WER abspeichern
    117. tmpWer = Rec("terWerId").ToString
    118. Row = Table.NewRow
    119. bolFirst = False
    120. End If
    121. If tmpWer <> Rec("terWerId").ToString Then ' Neue Zeile in Ausgabe
    122. tmpWer = Rec("terWerId").ToString
    123. Table.Rows.Add(Row)
    124. Row = Table.NewRow
    125. bolAdded = False
    126. End If
    127. Row("kw") = Rec("kw").ToString
    128. Row("wer") = Rec("terWerId").ToString
    129. ' die ID eintragen
    130. Dim KalDatum As Date = CDate((Rec("terDatum").ToString))
    131. Row(KalDatum.ToString("ddd")) = Row(KalDatum.ToString("ddd")) & Rec("terID") & "#"
    132. ' für das add(Row) nach dem Next.
    133. bolAdded = True
    134. Next
    135. If bolAdded Then ' Nur wenn was einer Row hinzugefügt wurde
    136. Table.Rows.Add(Row)
    137. End If
    138. ' neue Wochen Zeile
    139. Row = Table.NewRow
    140. End While
    141. End Using
    142. 'Tabelle an Datagridview
    143. With Me.DataGridView1
    144. .DataSource = Table
    145. '.AutoSizeRowsMode = DataGridViewAutoSizeRowMode.AllCellsExceptHeader
    146. .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader
    147. End With
    148. ' Farbe hinzufügen
    149. Dim arrBackground() As String = {"vblightYellow", "vblightblue", "vblightgreen"}
    150. Dim Yesterday As Byte = 32
    151. Dim CurMonthColor As Color = Color.LightYellow
    152. Dim CurMonthColor1 As Color = Color.LightBlue
    153. Dim CurMonthColor2 As Color = Color.LightGreen
    154. With DataGridView1
    155. For rowIndex = 0 To .RowCount - 2
    156. For colIndex = 2 To .ColumnCount - 1
    157. If CDbl(.Rows(rowIndex).Cells(0).Value) > 60 Then ' also nur Kalender-Header
    158. 'DataGridView1.Rows(rowIndex).Cells(colIndex).ToolTipText = DataGridView1.Rows(rowIndex).Cells(colIndex).Value.ToString
    159. ' Gibt es einen Monatswechsel?
    160. If CByte(.Rows(rowIndex).Cells(colIndex).Value.ToString.Substring(0, 2)) < Yesterday Then
    161. CurMonthColor = IIf(CurMonthColor = CurMonthColor1, CurMonthColor2, CurMonthColor1)
    162. Yesterday = 1
    163. Else
    164. Yesterday = CByte(.Rows(rowIndex).Cells(colIndex).Value.ToString.Substring(0, 2))
    165. End If
    166. 'If colIndex >= 2 Then ' CurMonth Color
    167. If colIndex >= 7 Then
    168. 'Wochenende
    169. .Rows(rowIndex).Cells(colIndex).Style.BackColor = Color.DeepSkyBlue
    170. Else
    171. ' Mo - Fr
    172. .Rows(rowIndex).Cells(colIndex).Style.BackColor = CurMonthColor
    173. End If
    174. 'ein Feiertag?
    175. If .Rows(rowIndex).Cells(colIndex).Value.ToString.IndexOf(":") > 0 Then
    176. .Rows(rowIndex).Cells(colIndex).Style.BackColor = Color.LightSalmon
    177. End If
    178. Else
    179. 'das ist eine WER Zeile
    180. .Rows(rowIndex).Cells(colIndex).Style.BackColor = Color.LightYellow
    181. End If
    182. ' toolTip
    183. With .Rows(rowIndex).Cells(colIndex)
    184. ' gibt es hier einen Termin? Wenn ja, fülle die Zelle
    185. If .Value.ToString.IndexOf("#") > 0 Then
    186. Dim termineID As String = ""
    187. termineID = .Value.ToString.Substring(0, .Value.ToString.IndexOf("#"))
    188. Dim curDayContent As String = getCalendarCellContent(termineID)
    189. ' toolTip
    190. .ToolTipText = curDayContent
    191. End If
    192. End With
    193. Next colIndex
    194. Next rowIndex
    195. End With
    196. ' das war's
    197. End Sub
    198. Function getCalendarCellContent(termineId As String) As String
    199. Dim strSql As String = "SELECT * FROM tbl_kal_termine where terID = " & termineId
    200. Dim DataReader As OdbcDataReader
    201. Dim SQLInhalt As String = ""
    202. Using cmd As New OdbcCommand(strSql, conn)
    203. DataReader = cmd.ExecuteReader
    204. ' Jeden einzelnen Datensatz abarbeiten
    205. While DataReader.Read
    206. SQLInhalt = DataReader("terWas").ToString
    207. End While
    208. End Using
    209. Return SQLInhalt
    210. End Function
    211. Function Termine_Fuer_Diese_KW(KW As String) As ArrayList
    212. Dim DataReader As OdbcDataReader
    213. Dim strSql As String = "SELECT *, WEEK(terDatum,1) as kw, year(terDatum) as y FROM tbl_kal_Termine " &
    214. "WHERE WEEK(terDatum,1) = '" & KW.Substring(4, 2) & "' and year(terDatum) = '" & KW.Substring(0, 4) &
    215. "' ORDER BY y, kw, terWerId , terDatum "
    216. Dim Result As New ArrayList()
    217. Using cmd As New OdbcCommand(strSql, conn)
    218. DataReader = cmd.ExecuteReader
    219. ' Jeden einzelnen Datensatz abarbeiten
    220. ' Add each entry to array list
    221. While DataReader.Read()
    222. ' Insert each column into a dictionary
    223. Dim dict As New Dictionary(Of String, Object)
    224. For count As Integer = 0 To (DataReader.FieldCount - 1)
    225. dict.Add(DataReader.GetName(count), DataReader(count))
    226. Next
    227. ' Add the dictionary to the ArrayList
    228. Result.Add(dict)
    229. End While
    230. End Using
    231. Return Result
    232. DataReader.Close()
    233. End Function
    234. Private Sub dataGridView1_CellClick(ByVal sender As Object,
    235. ByVal e As DataGridViewCellEventArgs) _
    236. Handles DataGridView1.CellClick
    237. ' this event comes from a klick on a dataGridView cell.
    238. ' either the cell is empty or has not number followed by a #, We do not need to continue
    239. Dim cell As String
    240. ' an empty cell?
    241. Try
    242. cell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
    243. Catch ex As Exception
    244. 'an empty cell!
    245. myTable.Clear()
    246. Exit Sub
    247. End Try
    248. 'If a cell has a number with a # in it, We will continuge
    249. If cell.ToString.IndexOf("#") < 0 Then
    250. myTable.Clear()
    251. Exit Sub
    252. End If
    253. ' The table has been created in the load event of the form.
    254. ' all textboxes, comboboxes and datetimepickers have been linked to this table
    255. ' because I will focus on a total different set for the table, I need to clear the table first
    256. myTable.Clear()
    257. 'Set up the SQL String to the record and retrieve it from the odbc Database.
    258. Dim strSql As String = "SELECT * FROM tbl_kal_termine where terID = " & cell.Substring(0, cell.IndexOf("#"))
    259. ' fill myTable using the sql-String
    260. DataAdapter1 = New OdbcDataAdapter(strSql, conn)
    261. DataAdapter1.Fill(myTable)
    262. 'Erstelle einen Commandbuilder für Insert, Update und Delete
    263. 'Dim commandbuilder1 As New OdbcCommandBuilder(DataAdapter1)
    264. If myTable.Rows.Count <> 0 Then
    265. ' all textboxes, comboboxes and datetimepickers are filled!
    266. BindingSource1.DataSource = myTable
    267. 'Allow the table to accept changes from the textboxes, comboboxes and datetimepickers
    268. myTable.AcceptChanges()
    269. Else
    270. MsgBox("no data")
    271. End If
    272. End Sub
    273. Private Sub Update_Click(sender As Object, e As EventArgs) Handles Update.Click
    274. 'to test what Is in row And each cell in the table myTable
    275. 'I see the changes I made in the myTable table / in each cell
    276. Dim txt As String = ""
    277. For Each row In myTable.Rows
    278. For Each column In myTable.Columns
    279. Console.Write(vbTab & row(column.ColumnName).ToString)
    280. txt = row(column.ColumnName).ToString
    281. Next
    282. Next row
    283. Dim commandbuilder1 As New OdbcCommandBuilder(DataAdapter1)
    284. DataAdapter1.Update(myTable)
    285. End Sub
    286. End Class

    Ich bin kein Experte was DataBinding angeht. Das beim Update "nix" passiert könnte evtl. daran liegen das du im Load Event die Tabelle leerst?

    -> myTable.Clear()
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „mrMo“ ()

    Entdecker des Rades: sinnvoll könnte ich mir den CommandBuilder in Zeile 321 vorstellen

    ne - update geht auch nicht

    Mr Mo_ in den Zeilen 344 bis 349 überprüfe ich den Inhalt der Tabelle my_table.
    Ab 320ff wird der data-adapter neu gefüllt.

    ich habe den CommandBuilder global gemacht:

    VB.NET-Quellcode

    1. Public Class frmKalenderAnzeigen
    2. Private BindingSource As New BindingSource
    3. Private DataAdapter1 As New Odbc.OdbcDataAdapter
    4. Dim myTable As New DataTable
    5. Dim conn As New OdbcConnection
    6. Dim commandbuilder1 As New OdbcCommandBuilder


    und Zeile 327

    VB.NET-Quellcode

    1. Dim strSql As String = "SELECT * FROM tbl_kal_termine where terID = " & cell.Substring(0, cell.IndexOf("#"))
    2. ' fill myTable using the sql-String
    3. DataAdapter1 = New OdbcDataAdapter(strSql, conn)
    4. DataAdapter1.Fill(myTable)
    5. 'Erstelle einen Commandbuilder für Insert, Update und Delete
    6. commandbuilder1 = New OdbcCommandBuilder(DataAdapter1)


    vor dem update sagt mir
    ?commandbuilder1.DataAdapter.Update
    error BC30516: Fehler bei der Überladungsauflösung, da keine zugreifbare "Update" diese Anzahl von Argumenten akzeptiert.


    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „dh1sbg“ ()

    dh1sbg schrieb:

    in den Zeilen 344 bis 349 überprüfe ich den Inhalt der Tabelle my_table.
    Ab 320ff wird der data-adapter neu gefüllt.


    Ah, diese Information bzw. deinen kompletten Code hatte ich zur Zeit meines Posts noch nicht. :)

    P.S. Er ist der @ErfinderDesRades nicht der EntdeckerDesRades :)
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Jo, schon grenzwertig viel.
    jdfs. das mit dem Commandbuilder ist Konfiguration - das musste also da machen, wo der DataAdapter erzeugt wird, nicht, wo er benutzt wird.
    Weil er wird ja mehrmals benutzt, abr nur einmal konfiguriert - und zwar bevor er das erste mal benutzt wird.
    also im Form_Load.
    du füllst myTable im Form_Load, und letzte Zeile der Methode ist dann wieder myTable.Clear() - komisch, oder? ;)

    Und dein getCalendar befüllt eine andere DataTable als die myTable, die oben im Form deklariert ist - naja, das ist vlt. beabsichtigt.

    Und das Updaten wie gesagt so:

    VB.NET-Quellcode

    1. DataAdapter1.Update(myTable)
    Und niemals!! myTable.AcceptChanges() aufrufen!
    Diese Methode ist für interne Benutzung durch den DataAdapter vorbehalten, pfusch dem da nicht rein, die Methode macht was anneres als was du denkst.
    Ich tippe weiterhin auf eine leere/falsche DataTable im Update_Click Event. Setzte einen BreakPoint und schau mal zur Laufzeit was da drin ist wenn du das hier machst: DataAdapter1.Update(myTable). Deine Überprüfung gibt lediglich den Namen der Columns aus, nicht den Inhalt der Rows.

    Allgemein ist dein Code leicht wirr und daher schlecht nachvollziehbar was/wann/wie passiert. Meine Empfehlung an dich: Trenne deine Businesslogik von der GUI, lagere diese besser in separate Klassen aus.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    getCalendar füllt das DataGridView auf der linken Seite. Hier spielt die Variable "table" eine Rolle.

    In den Zeilen 299 ff überprüfe ich jede einzelne Zelle und sehe, dass Änderungen vorliegen.

    Erfinder des Rades:
    in Zeile 39, dort wo der DataAdapter zum ersten mal erscheint, steht der Command-Builder.

    ich habe einen zweiten DataAdapterRechts eingefügt, der sich nur um den rechten Teil des Formulars kümmert.
    Immer noch nichts im Update.

    Muss ich den CommandBuilderRechts global deklarieren?

    Zur Rekapitulation
    Kurz vor dem dataadapterrechts.update enthält die Tabelle myTable alles, was ich rechts geändert habe.

    kann ich irgendwie sehen, welchen sql-String überhaupt abgeschickt wurde?



    VB.NET-Quellcode

    1. Imports System.Data.Odbc
    2. Public Class frmKalenderAnzeigen
    3. Private BindingSource As New BindingSource
    4. Private DataAdapter1 As New Odbc.OdbcDataAdapter
    5. Private DataAdapterRechts As New Odbc.OdbcDataAdapter
    6. Dim myTable As New DataTable
    7. Dim conn As New OdbcConnection
    8. Private Sub ZurückToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ZurückToolStripMenuItem.Click
    9. conn.Close()
    10. Me.Close()
    11. End Sub
    12. Private Sub frmKalenderAnzeigen_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    13. FlowLayoutPanelLeft.Width = Me.Width * 0.7
    14. With DataGridView1
    15. .Top = FlowLayoutPanelLeft.Top + 2
    16. .Left = FlowLayoutPanelLeft.Left + 2
    17. .Width = FlowLayoutPanelLeft.Width - 16
    18. .Height = FlowLayoutPanelLeft.Height - 16
    19. End With
    20. Try
    21. 'build up a connection
    22. conn.ConnectionString = "Dsn=mis"
    23. conn.Open()
    24. Catch ex As Exception
    25. MsgBox("Error on Connection" & vbCrLf & ex.Message)
    26. Me.Close()
    27. End Try
    28. ' Fülle Kalender
    29. get_Calendar() 'conn will be set there
    30. ' rechten Teil binden, also die Text- combo und datetimepicker
    31. Dim strSql As String = "SELECT * FROM tbl_kal_termine limit 1"
    32. dataAdapterRechts = New OdbcDataAdapter(strSql, conn)
    33. Dim commandbuilderRechts As New OdbcCommandBuilder(DataAdapterRechts)
    34. DataAdapterRechts.Fill(myTable)
    35. txtID.DataBindings.Add("TEXT", myTable, "terID")
    36. txtVon.DataBindings.Add("TEXT", myTable, "terVon")
    37. txtBis.DataBindings.Add("TEXT", myTable, "terBis")
    38. txtWas.DataBindings.Add("TEXT", myTable, "terWas")
    39. txtWo.DataBindings.Add("TEXT", myTable, "terWo")
    40. txtMehr.DataBindings.Add("TEXT", myTable, "terKommentar")
    41. DateTimePicker.DataBindings.Add("TEXT", myTable, "terDatum")
    42. cboAuftrag.DataBindings.Add("TEXT", myTable, "terAuftragId")
    43. cboWer.DataBindings.Add("TEXT", myTable, "terWerID")
    44. myTable.Clear() ' Because the customer has not clicked into a cell on the left side.
    45. ' Textboxes represent a click into the datagridview of the left side.
    46. End Sub
    47. Sub get_Calendar()
    48. ' table headerHeader
    49. Dim Table As New DataTable
    50. With Table.Columns
    51. .Add(New DataColumn("KW", GetType(String)))
    52. .Add(New DataColumn("Wer", GetType(String)))
    53. .Add(New DataColumn("Mo", GetType(String)))
    54. .Add(New DataColumn("Di", GetType(String)))
    55. .Add(New DataColumn("Mi", GetType(String)))
    56. .Add(New DataColumn("Do", GetType(String)))
    57. .Add(New DataColumn("Fr", GetType(String)))
    58. .Add(New DataColumn("Sa", GetType(String)))
    59. .Add(New DataColumn("So", GetType(String)))
    60. End With
    61. 'für jede Datumszeile den Inhalt holen (steht in tbl_kal_wochen
    62. Dim strSql As String = "SELECT * FROM tbl_kal_woche "
    63. Dim DataReader As OdbcDataReader
    64. Dim Row As DataRow = Table.NewRow
    65. Using cmd As New OdbcCommand(strSql, conn)
    66. DataReader = cmd.ExecuteReader
    67. ' Jeden einzelnen Datensatz abarbeiten
    68. Dim off As Integer = 7
    69. While DataReader.Read
    70. Row("kw") = DataReader(0).ToString
    71. Row("Mo") = DataReader(1 + off).ToString
    72. Row("Di") = DataReader(2 + off).ToString
    73. Row("Mi") = DataReader(3 + off).ToString
    74. Row("Do") = DataReader(4 + off).ToString
    75. Row("Fr") = DataReader(5 + off).ToString
    76. Row("Sa") = DataReader(6 + off).ToString
    77. Row("So") = DataReader(7 + off).ToString
    78. ' Diese Zeile der Tabellehinzufügen
    79. Table.Rows.Add(Row)
    80. ' fülle array
    81. ' gibt es zu dieser Woche Termine
    82. Dim Result As New ArrayList()
    83. Result = Termine_Fuer_Diese_KW(DataReader(0).ToString)
    84. ' Alle Datensätze verarbeiten, also Pro Jahr, Woche, Wer
    85. 'finde den ersten Datensatz
    86. Dim bolFirst As Boolean = True ' Erster Datensatz?
    87. Dim bolAdded As Boolean = False ' es wurde was hinzugefügt
    88. Dim tmpWer As String = ""
    89. For Each Rec As Dictionary(Of String, Object) In Result
    90. If bolFirst Then 'den ersten Datensatz finden und dort den Inhalt von WER abspeichern
    91. tmpWer = Rec("terWerId").ToString
    92. Row = Table.NewRow
    93. bolFirst = False
    94. End If
    95. If tmpWer <> Rec("terWerId").ToString Then ' Neue Zeile in Ausgabe
    96. tmpWer = Rec("terWerId").ToString
    97. Table.Rows.Add(Row)
    98. Row = Table.NewRow
    99. bolAdded = False
    100. End If
    101. Row("kw") = Rec("kw").ToString
    102. Row("wer") = Rec("terWerId").ToString
    103. ' die ID eintragen
    104. Dim KalDatum As Date = CDate((Rec("terDatum").ToString))
    105. Row(KalDatum.ToString("ddd")) = Row(KalDatum.ToString("ddd")) & Rec("terID") & "#"
    106. ' für das add(Row) nach dem Next.
    107. bolAdded = True
    108. Next
    109. If bolAdded Then ' Nur wenn was einer Row hinzugefügt wurde
    110. Table.Rows.Add(Row)
    111. End If
    112. ' neue Wochen Zeile
    113. Row = Table.NewRow
    114. End While
    115. End Using
    116. 'Tabelle an Datagridview
    117. With Me.DataGridView1
    118. .DataSource = Table
    119. '.AutoSizeRowsMode = DataGridViewAutoSizeRowMode.AllCellsExceptHeader
    120. .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader
    121. End With
    122. ' Farbe hinzufügen
    123. Dim arrBackground() As String = {"vblightYellow", "vblightblue", "vblightgreen"}
    124. Dim Yesterday As Byte = 32
    125. Dim CurMonthColor As Color = Color.LightYellow
    126. Dim CurMonthColor1 As Color = Color.LightBlue
    127. Dim CurMonthColor2 As Color = Color.LightGreen
    128. With DataGridView1
    129. For rowIndex = 0 To .RowCount - 2
    130. For colIndex = 2 To .ColumnCount - 1
    131. If CDbl(.Rows(rowIndex).Cells(0).Value) > 60 Then ' also nur Kalender-Header
    132. 'DataGridView1.Rows(rowIndex).Cells(colIndex).ToolTipText = DataGridView1.Rows(rowIndex).Cells(colIndex).Value.ToString
    133. ' Gibt es einen Monatswechsel?
    134. If CByte(.Rows(rowIndex).Cells(colIndex).Value.ToString.Substring(0, 2)) < Yesterday Then
    135. CurMonthColor = IIf(CurMonthColor = CurMonthColor1, CurMonthColor2, CurMonthColor1)
    136. Yesterday = 1
    137. Else
    138. Yesterday = CByte(.Rows(rowIndex).Cells(colIndex).Value.ToString.Substring(0, 2))
    139. End If
    140. 'If colIndex >= 2 Then ' CurMonth Color
    141. If colIndex >= 7 Then
    142. 'Wochenende
    143. .Rows(rowIndex).Cells(colIndex).Style.BackColor = Color.DeepSkyBlue
    144. Else
    145. ' Mo - Fr
    146. .Rows(rowIndex).Cells(colIndex).Style.BackColor = CurMonthColor
    147. End If
    148. 'ein Feiertag?
    149. If .Rows(rowIndex).Cells(colIndex).Value.ToString.IndexOf(":") > 0 Then
    150. .Rows(rowIndex).Cells(colIndex).Style.BackColor = Color.LightSalmon
    151. End If
    152. Else
    153. 'das ist eine WER Zeile
    154. .Rows(rowIndex).Cells(colIndex).Style.BackColor = Color.LightYellow
    155. End If
    156. ' toolTip
    157. With .Rows(rowIndex).Cells(colIndex)
    158. ' gibt es hier einen Termin? Wenn ja, fülle die Zelle
    159. If .Value.ToString.IndexOf("#") > 0 Then
    160. Dim termineID As String = ""
    161. termineID = .Value.ToString.Substring(0, .Value.ToString.IndexOf("#"))
    162. Dim curDayContent As String = getCalendarCellContent(termineID)
    163. ' toolTip
    164. .ToolTipText = curDayContent
    165. End If
    166. End With
    167. Next colIndex
    168. Next rowIndex
    169. End With
    170. End Sub
    171. Function getCalendarCellContent(termineId As String) As String
    172. Dim strSql As String = "SELECT * FROM tbl_kal_termine where terID = " & termineId
    173. Dim DataReader As OdbcDataReader
    174. Dim SQLInhalt As String = ""
    175. Using cmd As New OdbcCommand(strSql, conn)
    176. DataReader = cmd.ExecuteReader
    177. ' Jeden einzelnen Datensatz abarbeiten
    178. While DataReader.Read
    179. SQLInhalt = DataReader("terWas").ToString
    180. End While
    181. End Using
    182. Return SQLInhalt
    183. End Function
    184. Function Termine_Fuer_Diese_KW(KW As String) As ArrayList
    185. Dim DataReader As OdbcDataReader
    186. Dim strSql As String = "SELECT *, WEEK(terDatum,1) as kw, year(terDatum) as y FROM tbl_kal_Termine " &
    187. "WHERE WEEK(terDatum,1) = '" & KW.Substring(4, 2) & "' and year(terDatum) = '" & KW.Substring(0, 4) &
    188. "' ORDER BY y, kw, terWerId , terDatum "
    189. Dim Result As New ArrayList()
    190. Using cmd As New OdbcCommand(strSql, conn)
    191. DataReader = cmd.ExecuteReader
    192. ' Jeden einzelnen Datensatz abarbeiten
    193. ' Add each entry to array list
    194. While DataReader.Read()
    195. ' Insert each column into a dictionary
    196. Dim dict As New Dictionary(Of String, Object)
    197. For count As Integer = 0 To (DataReader.FieldCount - 1)
    198. dict.Add(DataReader.GetName(count), DataReader(count))
    199. Next
    200. ' Add the dictionary to the ArrayList
    201. Result.Add(dict)
    202. End While
    203. End Using
    204. Return Result
    205. DataReader.Close()
    206. End Function
    207. Private Sub dataGridView1_CellClick(ByVal sender As Object,
    208. ByVal e As DataGridViewCellEventArgs) _
    209. Handles DataGridView1.CellClick
    210. ' this event comes from a klick on a dataGridView cell. (left side)
    211. ' either the cell is empty or has not number followed by a #, We do not need to continue
    212. Dim cell As String
    213. ' an empty cell?
    214. Try
    215. cell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
    216. Catch ex As Exception
    217. 'an empty cell!
    218. myTable.Clear()
    219. Exit Sub
    220. End Try
    221. 'If a cell has a number with a # in it, We will continuge
    222. If cell.ToString.IndexOf("#") < 0 Then
    223. myTable.Clear()
    224. Exit Sub
    225. End If
    226. ' The table has been created in the load event of the form.
    227. ' all textboxes, comboboxes and datetimepickers have been linked to this table
    228. ' because I will focus on a total different set for the table, I need to clear the table first
    229. myTable.Clear()
    230. 'Set up the SQL String to the record and retrieve it from the odbc Database.
    231. Dim strSql As String = "SELECT * FROM tbl_kal_termine where terID = " & cell.Substring(0, cell.IndexOf("#"))
    232. ' fill myTable using the sql-String
    233. dataAdapterRechts = New OdbcDataAdapter(strSql, conn)
    234. dataAdapterRechts.Fill(myTable)
    235. 'Erstelle einen Commandbuilder für Insert, Update und Delete
    236. If myTable.Rows.Count <> 0 Then
    237. ' all textboxes, comboboxes and datetimepickers are filled!
    238. BindingSource1.DataSource = myTable
    239. Else
    240. MsgBox("no data")
    241. End If
    242. End Sub
    243. Private Sub Update_Click(sender As Object, e As EventArgs) Handles Update.Click
    244. 'to test what Is in row And each cell in the table myTable
    245. 'I see the changes I made in the myTable table / in each cell
    246. Dim txt As String = ""
    247. For Each row In myTable.Rows
    248. For Each column In myTable.Columns
    249. Console.Write(vbTab & row(column.ColumnName).ToString)
    250. txt = row(column.ColumnName).ToString
    251. Next
    252. Next row
    253. DataAdapterRechts.Update(myTable)
    254. End Sub
    255. End Class
    Bilder
    • Unbenannt.png

      49,83 kB, 1.530×540, 94 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „dh1sbg“ ()

    In Zeile 37 ff steht

    VB.NET-Quellcode

    1. [vbnet]Dim strSql As String = "SELECT * FROM tbl_kal_termine limit 1"
    2. dataAdapterRechts = New OdbcDataAdapter(strSql, conn)
    3. Dim commandbuilderRechts As New OdbcCommandBuilder(DataAdapterRechts)
    4. DataAdapterRechts.Fill(myTable)
    [/vbnet]


    Ich habe was gefunden.
    Kurz vor dem DataAdapterRechts.Update(myTable) lasse ich mir den updateString auslesen.

    ?commandbuilderRechts.GetUpdateCommand.CommandText.tostring

    "UPDATE tbl_kal_termine SET terGruppenID = ?, terAuftragID = ?, terWerId = ?, terDatum = ?, terVon = ?, terBis = ?, terWas = ?, terWo = ?, terKommentar = ? WHERE (((? = 1 AND terID IS NULL) OR (terID = ?)) AND (terGruppenID = ?) AND (terAuftragID = ?) AND (terWerId = ?) AND (terDatum = ?) AND (terVon = ?) AND (terBis = ?) AND (terWas = ?) AND (terWo = ?))"

    scheinbar ist myTable leer? oder was ist da los.

    Kann das mit dem myTable.clear zusammenhängen? => alle myTable.clear gelöscht - trotzdem kein Update Ergebnis

    Wenn ich rechts was geändert habe, dann muss ich eigentlich nach dem Update alles löschen. Im Klick-Event der DataGridView wird ggf ein anderer Datensatz gesucht und rechts angezeigt.


    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „dh1sbg“ ()

    dh1sbg schrieb:

    scheinbar ist myTable leer? oder was ist da los.
    Kann das mit dem myTable.clear zusammenhängen?
    Das fragst du jetzt nicht im Ernst, oder?
    Clear ist englisch, und bedeutet löschen.

    Darüber verwunderte ich mich schon im vorigen Post - dass du myTable erst befüllst, und dann gleich wieder löschst.

    jdfs. das UpdateCommand sieht korrekt aus.

    Und ich würde nicht nach dem Update alles löschen, sondern erst wenn tatsächlich eine neue Zelle geklickst wurde.
    Dazu kannste glaub auch einfach DataAdapter.ClearbeforeFill=True einstellen, dann macht der das auch für dich.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    in meinem Post, habe ich geschrieben, dass ich alle myTables.clear auskommentiert habe, trotzdem funktioniert der Update nicht.

    Zudem schaue ich mir ab Zeile 300 an, was in der Tabelle myTable pro Zelle alle enthalten ist. Dort sehe ich die Änderungen der Texboxes.
    Dann kommt Zeile 307. Und die Datenbank wird nicht geändert.

    DataAdapter.ClearbeforeFill=True werde ich implementieren.

    Warum funktioniert der Update nicht? Ich mache wohl irgendwas grottenfalsch.