Mehrere markierte Zeilen aus DataGridview löschen und an AccessDB zurück geben

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von stevez.

    Mehrere markierte Zeilen aus DataGridview löschen und an AccessDB zurück geben

    Hallo,

    nachdem mir schon gut geholfen wurde, suche ich jetzt eine Lösung, wie ich die gelöschten Zeilen im DataGridview an die AccessDB zurück geben kann. Wie mache ich das?

    Dies ist momentan mein Code:

    VB.NET-Quellcode

    1. Imports System.Data, System.Data.Common
    2. Public Class frmMain
    3. Dim Ada As OleDb.OleDbDataAdapter
    4. Dim Kda As OleDb.OleDbDataAdapter
    5. Dim Pda As OleDb.OleDbDataAdapter
    6. Dim dt As DataTable
    7. Dim ds As DataSet
    8. Dim view As DataView = New DataView
    9. Dim Tabelle As String
    10. Public Sub Main()
    11. Dim ConnectionString As String = GetConnectionString()
    12. ConnectToData(ConnectionString)
    13. End Sub
    14. Private Shared Function GetConnectionString() As String
    15. Dim lokPfad As String
    16. 'Lokaler Dateipfad des Programms ermitteln
    17. lokPfad = IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath)
    18. 'Lokale Access 2003 Datei "Daten.mdb" ansprechen
    19. Return "Provider=Microsoft.Jet.OLEDB.4.0;" &
    20. "Data Source=" & lokPfad & "\Daten.mdb;"
    21. End Function
    22. Private Sub ConnectToData(ByVal ConnectionString As String)
    23. 'MSSQL Verbindung mit der Datenbank herstellen
    24. Using Con As OleDb.OleDbConnection = New OleDb.OleDbConnection(ConnectionString)
    25. 'Verbindung öffnen und ggf. abfangen
    26. Try
    27. 'Verbindung öffnen
    28. Con.Open()
    29. Dim AstrSQL As String = "SELECT * FROM tblArtikel"
    30. Dim KstrSQL As String = "SELECT * FROM tblKunden"
    31. Dim PstrSQL As String = "SELECT * FROM tblPreise"
    32. Dim cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand
    33. '3 DataAdapter nehmen 3 Tabellen auf
    34. Ada = New OleDb.OleDbDataAdapter(AstrSQL, Con)
    35. Kda = New OleDb.OleDbDataAdapter(KstrSQL, Con)
    36. Pda = New OleDb.OleDbDataAdapter(PstrSQL, Con)
    37. 'DataSet initialisieren
    38. ds = New DataSet
    39. 'da.SelectCommand = cmd
    40. 'DataAdapter füllt das DataSet
    41. Ada.Fill(ds, "Artikel")
    42. Kda.Fill(ds, "Kunden")
    43. Pda.Fill(ds, "Preise")
    44. 'DataView initialisieren
    45. view = ds.Tables(Tabelle).DefaultView
    46. 'Bindingsource initialisieren
    47. Dim bs As BindingSource = New BindingSource()
    48. bs.DataSource = view
    49. DataGridView1.DataSource = bs
    50. 'Filter und Sortierung setzen
    51. view.Sort = "ID DESC"
    52. 'Verbindung schließen
    53. Con.Close()
    54. Catch ex As Exception
    55. MessageBox.Show("Kann keine Verbindung zur DB herstellen. Ist die Datei vorhanden?")
    56. End Try
    57. End Using
    58. End Sub
    59. Private Sub btnSuche_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    60. Handles btnSuche.Click
    61. Filter()
    62. End Sub
    63. 'Wenn im Formular entfernen gedrückt wird
    64. Private Sub frmMain_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
    65. If e.KeyCode = Keys.Delete Then
    66. Delete()
    67. End If
    68. End Sub
    69. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    70. Handles MyBase.Load
    71. 'Beim Laden DataGridview und Buttonleiste ausblenden
    72. FillByToolStrip.Visible = False
    73. DataGridView1.Visible = False
    74. End Sub
    75. Private Sub ArtikelToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ArtikelToolStripMenuItem.Click
    76. Tabelle = "Artikel"
    77. 'DatagridView füllen
    78. Main()
    79. FillByToolStrip.Visible = True
    80. DataGridView1.Visible = True
    81. End Sub
    82. Private Sub KundenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles KundenToolStripMenuItem.Click
    83. Tabelle = "Kunden"
    84. 'DatagridView füllen
    85. Main()
    86. FillByToolStrip.Visible = True
    87. DataGridView1.Visible = True
    88. End Sub
    89. Private Sub PreiseToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PreiseToolStripMenuItem.Click
    90. Tabelle = "Preise"
    91. 'DatagridView füllen
    92. Main()
    93. FillByToolStrip.Visible = True
    94. DataGridView1.Visible = True
    95. End Sub
    96. Private Sub fldSuche_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles fldSuche.KeyUp
    97. 'Wenn im Textfeld Suche "Enter" gedrückt wird
    98. If e.KeyCode = Keys.Return Then
    99. Filter()
    100. End If
    101. End Sub
    102. Private Sub Filter()
    103. 'Wenn kein Text in fldSuche steht, dann keine Variable an Prozedur übergeben
    104. If fldSuche.Text = "" Then
    105. view.RowFilter = ""
    106. Else
    107. 'Filter übergeben
    108. Dim Var() As String = Split(fldSuche.Text)
    109. Dim strFilter As String = ""
    110. For i = 0 To UBound(Var)
    111. If i > 0 Then strFilter = strFilter & " OR "
    112. Select Case Tabelle
    113. Case "Artikel"
    114. If IsNumeric(Var(i)) Then
    115. strFilter = strFilter & "ArtNr = " & Var(i)
    116. Else
    117. strFilter = strFilter & "ArtName LIKE '*" & Var(i) & "*'"
    118. End If
    119. Case "Kunden"
    120. If IsNumeric(Var(i)) Then
    121. strFilter = strFilter & "KndNr = " & Var(i)
    122. Else
    123. strFilter = strFilter & "KndName LIKE '*" & Var(i) & "*'"
    124. End If
    125. Case "Preise"
    126. If IsNumeric(Var(i)) Then
    127. strFilter = strFilter & "KndNr = " & Var(i) & " OR ArtNr = " & Var(i)
    128. Else
    129. strFilter = strFilter & "KndName LIKE '*" & Var(i) & "*' OR ArtName LIKE '*" & Var(i) & "*'"
    130. End If
    131. End Select
    132. Next
    133. view.RowFilter = strFilter
    134. End If
    135. End Sub
    136. 'Prozedur um alle markierten Zeilen zu löschen
    137. Private Sub Delete()
    138. If MessageBox.Show("Wollen Sie die Datensätze wirklich löschen?", "Löschen", MessageBoxButtons.YesNo) = DialogResult.Yes Then
    139. For Each dgvr As DataGridViewRow In Me.DataGridView1.SelectedRows
    140. Me.DataGridView1.Rows.Remove(dgvr)
    141. Next
    142. Select Case Tabelle
    143. Case "Artikel"
    144. Me.Ada.Update(Me.ds.Tables(Tabelle))
    145. Case "Kunden"
    146. Me.Kda.Update(Me.ds.Tables(Tabelle))
    147. Case "Preise"
    148. Me.Pda.Update(Me.ds.Tables(Tabelle))
    149. End Select
    150. End If
    151. End Sub
    152. 'Button "btnDelete"
    153. Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click
    154. Delete()
    155. End Sub
    156. End Class


    Wenn die Prozedur "Delete" aufgerufen wird, funktioniert das Löschen der markierten Zeilen im DataGridview. Das Übergeben an die AccessDB mit Update funktioniert aber nicht:Für ein Update ist ein gültiger DeleteCommand erforderlich, wenn eine DataRow-Auflistung mit gelöschten Zeilen weitergegeben wird.

    Was muss ich an meinem Code ändern?
    Du arbeitest ohne Designer was heißt, dass du sämtlichen Code selber machen mußt.

    Du mußt also erst mal definieren, was er im Falle von UPDATE, INSERT, DELETE überhaupt machen soll.
    Wenn du diese Befehle als SQL Command schreiben willst, müßtest du sowas wie

    VB.NET-Quellcode

    1. DELETE FROM Datenbanktabelle WHERE SCHLÜSSELSPALTE = z.B.=Textbox1.text
    schreiben.

    Wenn du das alles über DataTable machst, mußt du nur zum Programmstart alle Befehle definieren lassen.
    Beim Delete Befehl sieht das z.B. bei mir so aus

    VB.NET-Quellcode

    1. ' DELETE Befehl definieren
    2. '
    3. Befehl_Delete.CommandText = "DELETE FROM " & Tabelle.ToString & " WHERE " & DB_Felder(0) & " = " & "@" & DB_Felder(0)
    4. Befehl_Delete.Connection = Conn
    5. Prm = Befehl_Delete.Parameters.Add("@" & DB_Felder(0), OleDbType.VarChar)
    6. Prm.SourceColumn = DB_Felder(0)
    7. Prm.SourceVersion = DataRowVersion.Original
    8. DataAdap.DeleteCommand = Befehl_Delete


    Der Aufruf heißt nachher einfach

    VB.NET-Quellcode

    1. BS_Mitglieder.EndEdit() ' die Binding Source ist an die DataTable gebunden. Mit .EndEdit gebe ich diese Änderungen frei, Abfrage z.B. über DataTable.getchanges
    2. DA_Mitglieder.Update(DT_Mitglieder) ' alle Änderungen die z.B. über DataTable.getchanges sichtbar sind, werden an die Datenbank geschreiben, egal ob UPDATE, INSERT, DELETE


    z.B. könntest du dir ein DataGridView anzeigen lassen, welches die Änderungen anzeigt : DGV.DataSource = DataTable.GetChanges
    Hallo,

    aufgrund dessen, dass ich die selektierten Zeilen löschen will, habe ich OleDbCommand lediglich global definiert:

    VB.NET-Quellcode

    1. Dim cmddel As OleDb.OleDbCommand


    Und mit Start des Formulars initialisiert:

    VB.NET-Quellcode

    1. cmddel = New OleDb.OleDbCommand


    Der CommandText erfolgt dann erst in einer Löschprozedur:

    VB.NET-Quellcode

    1. 'Prozedur um alle markierten Zeilen zu löschen
    2. Private Sub Delete()
    3. If MessageBox.Show("Wollen Sie die Datensätze wirklich löschen?", "Löschen", MessageBoxButtons.YesNo) = DialogResult.Yes Then
    4. Dim strID As String = ""
    5. Dim i As Integer = 0
    6. Con.Open()
    7. For Each dgvr As DataGridViewRow In Me.DataGridView1.SelectedRows
    8. Me.DataGridView1.Rows.Remove(dgvr)
    9. i = i + 1
    10. If Len(strID) > 0 Then strID = strID & " OR "
    11. strID = strID & "ID = " & DataGridView1.CurrentRow.Cells(0).Value 'erste Spalte im Datagridview ist die ID
    12. Next
    13. 'Erstellen des CommandTextes mit allen zu löschenden ID´s
    14. cmddel.CommandText = "DELETE * FROM tbl" & Tabelle & _
    15. " WHERE " & strID
    16. cmddel.Connection = Con
    17. 'Je nach geöffneter Tabelle im Datagridview wird der entsprechende Adapter angesprochen
    18. Select Tabelle
    19. Case "Artikel"
    20. Ada.DeleteCommand = cmddel
    21. bs.EndEdit()
    22. Me.Ada.Update(Me.ds.Tables(Tabelle))
    23. Case "Kunden"
    24. Kda.DeleteCommand = cmddel
    25. bs.EndEdit()
    26. Me.Kda.Update(Me.ds.Tables(Tabelle))
    27. Case "Preise"
    28. Pda.DeleteCommand = cmddel
    29. bs.EndEdit()
    30. Me.Pda.Update(Me.ds.Tables(Tabelle))
    31. End Select
    32. MsgBox(i & "Datensätze gelöscht!")
    33. Con.Close()
    34. End If
    35. End Sub


    Gibt es für meinen Fall auch die Möglichkeit, dass ich den CommandText bereits beim Laden initialisiere oder ist es schon richtig, dass ich es in dieser Sub mache, da ich zum Anfang noch nicht weiß, welche ID´s der User markiert?

    Ich erhalte in Zeile 22, 26 bzw. 30 leider folgende Fehlermeldung:
    Parallelitätsverletzung: Der DeleteCommand hat sich auf 0 der erwarteten 1 Datensätze ausgewirkt.

    Wo liegt der Fehler?

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

    Hallo,


    habe es gelöst! :D

    VB.NET-Quellcode

    1. 'Prozedur um alle markierten Zeilen zu löschen
    2. Private Sub Delete()
    3. If MessageBox.Show("Wollen Sie die Datensätze wirklich löschen?", "Löschen", MessageBoxButtons.YesNo) = DialogResult.Yes Then
    4. Dim strID As String = ""
    5. Dim i As Integer = 0
    6. Con.Open()
    7. For Each dgvr As DataGridViewRow In Me.DataGridView1.SelectedRows
    8. i = i + 1
    9. If Len(strID) > 0 Then strID = strID & " OR "
    10. strID = strID & "ID = " & dgvr.Cells(0).Value 'erste Spalte im Datagridview ist die ID
    11. Me.DataGridView1.Rows.Remove(dgvr)
    12. Next
    13. 'Erstellen des CommandTextes mit allen zu löschenden ID´s
    14. If Len(strID) = 0 Then strID = "ID = " & DataGridView1.CurrentRow.Cells(0).Value
    15. cmddel.CommandText = "DELETE * FROM tbl" & Tabelle & _
    16. " WHERE " & strID
    17. MsgBox(cmddel.ExecuteNonQuery & "Datensätze gelöscht!")
    18. Con.Close()
    19. End If
    20. End Sub
    Hallo Leute,
    ich habe das irgendwie nicht richtig verstanden, was da gemacht werden muss... Was muss ich bei meinem Code ändern? Also das Hinzufügen und die Weitergabe an meinne accdb funktioniert soweit, nur wenn ich löschen oder ändern will, macht er Probleme...

    Quellcode

    1. Private Sub GeburtstageBindingNavigatorSaveItem_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GeburtstageBindingNavigatorSaveItem.Click
    2. Me.Validate()
    3. Me.GeburtstageBindingSource.EndEdit()
    4. Me.TableAdapterManager.UpdateAll(Me.GeburtstagsdatenDataSet)
    5. Dim deletedGeburtstage As GeburtstagsdatenDataSet.GeburtstageDataTable = CType( _
    6. GeburtstagsdatenDataSet.Geburtstage.GetChanges(Data.DataRowState.Deleted), GeburtstagsdatenDataSet.GeburtstageDataTable)
    7. Dim newGeburtstage As GeburtstagsdatenDataSet.GeburtstageDataTable = CType( _
    8. GeburtstagsdatenDataSet.Geburtstage.GetChanges(Data.DataRowState.Added), GeburtstagsdatenDataSet.GeburtstageDataTable)
    9. Dim modifiedGeburtstage As GeburtstagsdatenDataSet.GeburtstageDataTable = CType( _
    10. GeburtstagsdatenDataSet.Geburtstage.GetChanges(Data.DataRowState.Modified), GeburtstagsdatenDataSet.GeburtstageDataTable)
    11. Try
    12. ' Remove all deleted orders from the Orders table.
    13. If Not deletedGeburtstage Is Nothing Then
    14. GeburtstageTableAdapter.Update(deletedGeburtstage)
    15. End If
    16. ' Update the Customers table.
    17. GeburtstageTableAdapter.Update(GeburtstagsdatenDataSet.Geburtstage)
    18. ' Add new orders to the Orders table.
    19. If Not newGeburtstage Is Nothing Then
    20. GeburtstageTableAdapter.Update(newGeburtstage)
    21. End If
    22. ' Update all modified Orders.
    23. If Not modifiedGeburtstage Is Nothing Then
    24. GeburtstageTableAdapter.Update(modifiedGeburtstage)
    25. End If
    26. GeburtstagsdatenDataSet.AcceptChanges()
    27. Catch ex As Exception
    28. MsgBox("Aktualisierung fehlgeschlagen")
    29. Finally
    30. If Not deletedGeburtstage Is Nothing Then
    31. deletedGeburtstage.Dispose()
    32. End If
    33. If Not newGeburtstage Is Nothing Then
    34. newGeburtstage.Dispose()
    35. End If
    36. If Not modifiedGeburtstage Is Nothing Then
    37. modifiedGeburtstage.Dispose()
    38. End If
    39. End Try
    40. End Sub


    Also den Code habe ich, wenn ich auf Speichern klicke.

    gruß Asgard
    hmm - eiglich wirds nicht gern gesehen, wenn so uralt-leichen-Threads wieder vorgezerrt werden und weiterbefragt. aber egal.

    also ich täte denken, wenn alles bei dir richtig konfiguriert ist, würde folgender Code reichen:

    VB.NET-Quellcode

    1. Private Sub GeburtstageBindingNavigatorSaveItem_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GeburtstageBindingNavigatorSaveItem.Click
    2. Me.Validate()
    3. Me.GeburtstageBindingSource.EndEdit()
    4. Me.TableAdapterManager.UpdateAll(Me.GeburtstagsdatenDataSet)
    5. End Sub
    Weil TableAdapterManager kümmert sich um alles.

    noch 2 Tipps: VB-Tag richtig benutzen

    TryCatch ist ein heißes Eisen
    Suche in Testfall.Beschreibung und gebe die entsprechenden Suites aus:

    VB.NET-Quellcode

    1. Private Sub btn_suchen_Click(sender As System.Object, e As System.EventArgs) Handles btn_suchen.Click
    2. 'Stichwortsuche in Testfällen
    3. Dim suchwort As String = txtbx_suchwort.Text
    4. 'DataView mit Filter erstellen
    5. Dim dvTestfall As DataView = New DataView(HauptDataSet.Testfall, "Beschreibung LIKE '%" & suchwort & "%'", "SuiteID", DataViewRowState.OriginalRows)
    6. dgv_Suchanzeige.Columns.Add("Name", "Suitename mit Inhalt '" & suchwort & "'")
    7. For Each drvTestfall As DataRowView In dvTestfall
    8. Dim sID As Integer = CInt(drvTestfall.Item("SuiteID"))
    9. dgv_Suchanzeige.Rows.Add(HauptDataSet.Suite.First(Function(a) a.ID = sID))
    10. Next
    11. End Sub


    Fehler in Row 10:
    "Zeilen können nicht automatisch zur Zeilenauflistung der DataGridView hinzugefügt werden, wenn das Steuerelement datengebunden ist."

    -> muss ich das erst über ein weiteres DataView realisieren? und wie kann ich einzelne Zeilen von hauptdataset.suite mit nur der Spalte "Suitename" in ein Dataview hinzufügen?

    Edit: gelöst

    VB.NET-Quellcode

    1. Private Sub btn_suchen_Click(sender As System.Object, e As System.EventArgs) Handles btn_suchen.Click
    2. 'Stichwortsuche in Testfällen
    3. Dim suchwort As String = txtbx_suchwort.Text
    4. 'DataView mit Filter erstellen
    5. Dim dvTestfall As DataView = New DataView(HauptDataSet.Testfall, "Beschreibung LIKE '%" & suchwort & "%'", "SuiteID", DataViewRowState.OriginalRows)
    6. dgv_Suchanzeige.Columns.Clear()
    7. dgv_Suchanzeige.Columns.Add("Name", "Suitename mit Inhalt '" & suchwort & "'")
    8. For Each drvTestfall As DataRowView In dvTestfall
    9. Dim sID As Integer = CInt(drvTestfall.Item("SuiteID"))
    10. dgv_Suchanzeige.Rows.Add(HauptDataSet.Suite.First(Function(a) a.ID = sID).Name)
    11. Next
    12. End Sub