Windows Forms-Datenbindung / Neuen Datensatz anfügen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 25 Antworten in diesem Thema. Der letzte Beitrag () ist von Westerwälder.

    Windows Forms-Datenbindung / Neuen Datensatz anfügen

    Hallo,

    binde mehrere Controls einer Form an eine Datatable.
    Ändern und Löschen von Datensätze funktioniert.
    Möchte ich einen neuen speichern, wird der letzte angezeigte Datensatz geändert, aber kein neuer angelegt.
    Was habe ich übersehen?

    Spoiler anzeigen


    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Public Class Setup_User
    4. Private da As OleDb.OleDbDataAdapter = Nothing
    5. Private dt As DataTable = Nothing
    6. Private BS As New BindingSource
    7. Private Sub Setup_User_Load(sender As Object, e As EventArgs) Handles Me.Load
    8. Monitor.Form_Initalisieren(Me)
    9. Dim Conn As New OleDb.OleDbConnection(Daten.Verbindungsstring)
    10. Dim selstr As String = "Select * from Anwender"
    11. da = New OleDb.OleDbDataAdapter(selstr, Conn)
    12. Dim cb As New OleDb.OleDbCommandBuilder(da)
    13. dt = New DataTable("Anwender")
    14. da.Fill(dt)
    15. Conn.Close()
    16. BS.DataSource = dt
    17. PRGM.Ausl = False
    18. With TS_Anwender.ComboBox
    19. .DataSource = BS
    20. .DisplayMember = "Anzeige"
    21. .ValueMember = "Nummer"
    22. End With
    23. Label_Usernummer.DataBindings.Add("Text", BS, "Nummer")
    24. Label_Anzeige.DataBindings.Add("Text", BS, "Anzeige")
    25. TextBox_Nachname.DataBindings.Add("Text", BS, "Nachname")
    26. TextBox_Vorname.DataBindings.Add("Text", BS, "Vorname")
    27. DTP_Geburtstag.DataBindings.Add("Value", BS, "Geburtstag")
    28. NUP_Stufe.DataBindings.Add("Value", BS, "Berechtigung")
    29. CheckBox_Admin.DataBindings.Add("Checked", BS, "Admin")
    30. PRGM.Ausl = True
    31.  
    32. End Sub


    VB.NET-Quellcode

    1. Private Sub TS_Bestaetigen_Click(sender As Object, e As EventArgs) Handles TS_Bestaetigen.Click
    2. If PRGM.Ausl = False Then Exit Sub
    3. If PRGM.Aktion = Nothing Then Exit Sub
    4. Datacontrol() ' Prüfung - Korrekte Dateneingabe in den Formcontrols
    5. If PRGM.IstFehler = True Then
    6. PRGM.IstFehler = False
    7. Exit Sub
    8. End If
    9.  
    10. If PRGM.Aktion = "N" Then ' Datensatz anfügen
    11. BS.AddNew()
    12. MsgBox("Neuanlage gewählt")
    13. End If
    14. If PRGM.Aktion = "L" Then ' Datensatz löschen
    15. BS.RemoveCurrent()
    16. End If
    17. Me.Validate()
    18. BS.EndEdit()
    19. da.Update(dt)
    20.  
    21. TS_Bestaetigen.Visible = False
    22. PRGM.Aktion = Nothing
    23. PRGM.Ausl = True
    24. MsgBox("Gespeichet")
    25. End Sub


    Gruß Markus

    Westerwälder schrieb:

    Möchte ich einen neuen speichern, wird der letzte angezeigte Datensatz geändert, aber kein neuer angelegt.
    Erstaunlich - am Code kann ich nix entsprechendes finden.
    Aber verstehe ich das ühaupt richtig: Angenommen, der letzte angezeigte User in der Tabelle heißt "Fritz", und du klickst "Neu", dann heisst der auf einmal "Wolfgang"? Oder wie muss man sich das vorstellen?
    Ja, der Fritz heißt dann Wolfgang. Verstehe es ja auch nicht.

    Vielleicht noch ein wenig mehr Information:
    Betriebssystem: Windows 10, 32 bit
    IDE Microsoft Visual Studio Express 2015
    Access 2013 (Office 365)
    Property Provider As String = "Provider=Microsoft.ACE.OLEDB.12.0;"
    Property Verbindungsstring As String = Provider & " Data Source=C:\MBSOFT\DATA\MBSOFT.accdb;"
    Datentabelle hat einen Primärschlüssel (Autowert Long Integer)



    Gruß Markus

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Westerwälder“ ()

    Was versprichst du dir von dieser Hinzufügung?

    ein typDataset erhält man nicht durch im Editor formulierten Code, sondern dadurch, dass man im Datenquell-Fenster den Datenquellen eine Datenquelle hinzufügt.
    Alternativ kann man eine Access-Mdb auch als Datei dem Projekt hinzufügen, das aktiviert automatisch den entsprechenden Assistenten - ist also wohl der schnellste Weg zum typDataset.

    Probiers halt so, oder guck, ob das als "Datenbank in 10 Minuten" gegebene animierte Tutorial noch funktioniert.
    Hallo EDR,

    danke für deine Ausführungen. Kann mich erinnern, dass wir schon über Import von Datenquellen diskutiert haben.
    Folgende Situation:
    Programm läuft auf drei Rechner im Haus ohne zentrale Datenquelle (Server, NAS oder sowas)
    Mein Rechner ist überwiegend im Betrieb (nennen wir ihn nun mal Hostrechner)
    Auf diesem Hostrechner findet die Datenbearbeitung statt.
    Geht nun ein andere Rechner (nennen wir sie mal Client) im Heimnetz online, kann er sich die Datenbank vom Hostrechner holen.
    Nun stehen dem Client die aktualisieren Daten (Musik, Bilder, Termine usw.) zur Verfügung. Bearbeiten darf er sie nicht.

    Da die Client's nicht alle Programm-Module aufrufen dürfen oder sollen, arbeite ich mit zwei Datenbanken. (Privat und Vermietung)
    Des weiteren möchte ich mich nicht so festnageln und die Möglichkeit haben, eine Tabelle auch später mal hinzufügen können oder die
    Tabellenstruktur ändern zu können.
    Gruß Markus

    Westerwälder schrieb:

    ... eine Tabelle auch später mal hinzufügen können oder die
    Tabellenstruktur ändern zu können.
    Änderungen am Datenmodell erfordern bei typisiertem Dataset ein Neu-Kompilieren, und bei Produktiv-Systemen folglich ein Neu-Verteilen.
    Allerdings wüsste ich auch bei untypisierten Datasets nicht, wie ein Programm bei geändertem Datenmodell noch korrekt arbeiten sollte, ausser man kompiliert es neu.

    Oder mal direkt gefragt: Wie ist das bisher gewesen, bei Änderungen an deim Datenmodell: Konntest du diese durchführen, ohne auch das Programm zu ändern und neu zu kompilieren?
    Habe nun versucht die Datenbank über "Datenquelle hinzu fügen" einzufügen.
    In dem Assistenten kommt nun folgende Fehlermeldung:
    "Für die Tabelle oder die Ansicht [Tabellenname] konnten keine Schemainformationen abgefragt werden."

    Dies gilt für alle Tabellen der Datenbank.
    Gruß Markus
    und hast du mal versucht, die mdb im ProjektExplorer dem Projekt hinzuzufügen? Das finde ich immer am Einfachsten.

    Ansonsten scheint die mdb kaputt, der Connectionstring falsch, oder ein installations-Problem.

    Hast du mal das angegebene Tut runtergeladen? Da ist auch eine funktionierende mdb dabei.
    Habe die Datenbank nun über den Projekt-Explorer.
    Kommen aber auch einige Fehlermeldungen.
    Muss ich mir morgen mal in Ruhe anschauen.

    Bezahle für das neue Office 365 jährlich , da kann man doch erwarten, dass es mit VB 2015 kompatibel ist.

    Noch eine Frage:
    Binde ich nun die Datenbank in das Projekt ein, läuft dass denn bei den Client-Rechner (bei gleicher Pfad-Struktur) auch,
    oder treten da Probleme auf?
    Gruß Markus
    Das Einbinden ist nur eine Art, den Assistenten zu starten, der ein typisiertes Dataset generiert - schien ja auf anderem Weg nicht zu gehen.
    Solange du nicht die mit-generierten TableAdapter benutzst, kannste die eingebundene mdb auch wieder entfernen - das typDataset verschwindet deswegen ja nicht.
    Auch generiert dieses Einbinden normalerweise ein Setting mit dem ConnectionString. Dieses Setting wird von den mit-generierten TableAdaptern benutzt.

    Ich empfehle immer, die mit-generierten TableAdapter im Dataset-Designer zu löschen, und danach(!) kannste auch das Setting löschen.
    Weil auf einem anderen Rechner stimmt das Setting normalerweise eh nicht.
    Also mit dem Einbinden - denke mal, komme auf ca. 40 Tabellen gesamt. Möchte gerne Modulweise programmieren. D.h., z. Bsp. erst die Datentabelle Termine anlegen. Diese Daten über eine Datatable einlesen und anschließend den entsprechenden Programmcode erstellen. Bei dieser Vorgehensweise sehe ich sofort, was an den Daten "Termine" fehlt oder noch geändert werden muss.
    Weiterhin muss gewährleistet sein, dass die Software auch auf anderen Rechner lauffähig ist.
    Im Grunde reicht mir der Datenzugriff über Datentabellen vollkommen.

    Das Problem, was ich nun habe, ist das Auslesen des Schema der Tabelle.
    Arbeite mit dem Buch "Datenbank-Programmierung mit Visual Basic 2010" - ISBN 978-3-86645-445-3

    Hier wird viel gezeigt, doch einiges nicht erklärt.
    Nachstehend Versuche zur Ermittlung des Tabellenschemas:

    VB.NET-Quellcode

    1. Dim Conn As New OleDb.OleDbConnection(Daten.Verbindungsstring)
    2. Dim selstr As String = "Select * from Anwender Order by Anzeige"
    3. da = New OleDb.OleDbDataAdapter(selstr, Conn)
    4. Dim cb As New OleDb.OleDbCommandBuilder(da)
    5. Dim Filter() As String = {Nothing, Nothing, "Anwender", Nothing}
    6. cb.QuotePrefix = "["
    7. cb.QuoteSuffix = "]"
    8. dt = New DataTable("Anwender")
    9. ds = New DataSet("Privat")
    10. Conn.Open()
    11. ' dt = Conn.GetSchema("Tables")
    12. dt = Conn.GetSchema("Columns")
    13. dt.PrimaryKey = New DataColumn() {dt.Columns("Nummer")}
    14. ' da.MissingSchemaAction = MissingSchemaAction.AddWithKey
    15. ' da.FillSchema(dt, SchemaType.Mapped)
    16. da.Fill(dt)
    17. ' da.Fill(ds, "Anwender")
    18. BS.DataSource = dt
    19.  
    20. Conn.Close()
    21. PRGM.Ausl = False
    22. With TS_Anwender.ComboBox
    23. .DataSource = BS
    24. .DisplayMember = "Anzeige"
    25. .ValueMember = "Nummer"
    26. End With
    27. Label_Usernummer.DataBindings.Add("Text", BS, "Nummer")
    28. Label_Anzeige.DataBindings.Add("Text", BS, "Anzeige")
    29. TextBox_Nachname.DataBindings.Add("Text", BS, "Nachname")
    30. TextBox_Vorname.DataBindings.Add("Text", BS, "Vorname")
    31. DTP_Geburtstag.DataBindings.Add("Value", BS, "Geburtstag")
    32. NUP_Stufe.DataBindings.Add("Value", BS, "Berechtigung")
    33. CheckBox_Admin.DataBindings.Add("Checked", BS, "Admin")


    Was sagen die Angaben beim Filter aus?

    Bei dieser Variante bekomme ich nun die Fehlermeldung "Ein Objekt kann nicht von DBNull in andere Typen umgewandelt werden."
    DTP_Geburtstag ist ein DateTimePicker, Geburtstag aus der Datenbank ist auf Datum/Zeit (Eingabe erforderlich) eingestellt.

    Vielleicht kennt jemand eine Informationsquelle (WEB), welche diese Problematik expliziert behandelt.
    Gruß Markus
    prinzipiell versuch mal, ganze Methoden zu posten, und entferne auch die Leerzeilen, die Einrückungen erhalte aber. Das würde deine Snippets lesbarer machen.
    Aber darüber hinaus verstehe ich kaum den Sinn einer Zeile.

    etwa #15 erzeugt eine DataTable
    #23 überschreibt sie dann
    und #31 befüllt sie dann nochmal ganz neu, mit wieder einem gänlich neuem Inhalt.

    Wie gesagt - kein Plan, was da ühaupt bezweckt wird.

    "Schema" ist auch ein mehrdeutiger Begriff.
    Meinst du das Schema einer DataTable? Dazu brauchst du die Datenbank nicht, sondern das ist Bestandteil der DataTable.

    Oder meinst du das Datenbank-Schema?
    Letzteres gibt es gar nicht, sondern von einer Datenbank können viele Schemata abgerufen werden: Tabellen, TabellenSpalten, Constraints, Relations, StoredProcedures, DataTypes,...
    gugge vlt. Datenbank-Schema auslesen - DataViewer
    Hallo,
    habe das auch schon bemerkt, die Leerzeichen generieren sich beim Kopieren/Einfügen von selbst. (Muss ich in Zukunft halt manuell löschen)

    WirrWarr, weil diverse Versuche zum Auslesen des Schema.

    Ja, ich meine Datenbank-Schema, Tabellen
    - Was ist der Primärschlüssel
    - Datentype
    - Datenlänge
    Gruß Markus
    Hallo.

    Habe ein wenig umprogrammiert.
    Korrektur und Löschung von Datensätzen in Ordnung.

    Problem Neuanlage:
    Nun wird der letzte Datensatz nicht mehr mit den neuen Daten überschrieben, sondern ich erhalte folgende Fehlermeldung:
    Bei BS.EndEdit
    Ausnahmefehler System.Data.NoNullAllowedExeption ist in System.Data.dll aufgetreten.
    Zusätzliche Information: Spalte Nummer läßt nicht nulls zu.

    Nummer ist gebunden an einen label. Auch wenn ich Nummer in der Datenbank auf String stelle kommt die gleiche Fehlermeldung.
    Gruß Markus