none
Visual Basic Datenbankabfrage mit INNER JOIN

    Frage

  • Hallo,

    ich erarbeite gerade ein Datenbankprogramm und will mit INNER JOIN 2 Tabellen verknüpfen.

    Code ist folgender:

        Private dbpfad As String = Application.StartupPath & "\gs_personal.mdb"
        Private connstr As String = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source =" & dbpfad
        Private selStr As String = "SELECT * FROM Pfändungen INNER JOIN Personal ON Pfändungen.NR = Personal.NR"
        Private conn As OleDbConnection
        Private da As OleDbDataAdapter
        Private dt As DataTable
        Private ds As DataSet
        Private cb As OleDbCommandBuilder
        Private bm As BindingManagerBase
        Private dv As DataView
    
        Private Sub Pfändungen_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            conn = New OleDbConnection(connstr)
            da = New OleDbDataAdapter(selStr, conn)
            cb = New OleDbCommandBuilder(da)
            dt = New DataTable("Pfändungen")
            ds = New DataSet
            conn.Open()
            da.Fill(dt)
            da.Fill(ds, "Pfändungen")
            conn.Close()
            dv = New DataView(ds.Tables("Pfändungen"))
            DataGridView1.DataSource = dv
            DataGridView1.Columns(0).Visible = False
           
            TextBox1.DataBindings.Add("Text", dt, "Nr")
            Dim b1 As Binding = New Binding("Text", dt, "PFDatum")
            AddHandler b1.Format, AddressOf DatToDateString
            AddHandler b1.Parse, AddressOf DateStrToDat
            Dim b2 As Binding = New Binding("Text", dt, "PFGesamtbetrag")
            AddHandler b2.Format, AddressOf DecToCurrString
            AddHandler b2.Parse, AddressOf CurStrToDecimal
            Dim b3 As Binding = New Binding("Text", dt, "PFÜberweisungsbetrag")
            AddHandler b3.Format, AddressOf DecToCurrString
            AddHandler b3.Parse, AddressOf CurStrToDecimal
            TextBox2.DataBindings.Add(b1)
            TextBox3.DataBindings.Add(b2)
            TextBox4.DataBindings.Add(b3)
            TextBox5.DataBindings.Add("Text", dt, "Empfänger1")
            TextBox6.DataBindings.Add("Text", dt, "Empfänger2")
            TextBox7.DataBindings.Add("Text", dt, "Empfänger3")
            TextBox8.DataBindings.Add("Text", dt, "Empfänger4")
            TextBox9.DataBindings.Add("Text", dt, "Empfängerzeichen")
            TextBox10.DataBindings.Add("Text", dt, "Empfängerbank")
            TextBox11.DataBindings.Add("Text", dt, "Empfängerkto")
            TextBox12.DataBindings.Add("Text", dt, "empfängerblz")
            Dim b4 As Binding = New Binding("Text", dt, "DatumersteZahlung")
            AddHandler b4.Format, AddressOf DatToDateString
            AddHandler b4.Parse, AddressOf DateStrToDat
            TextBox13.DataBindings.Add(b4)
            TextBox14.DataBindings.Add("Text", dt, "UnserZeichen")
            TextBox15.DataBindings.Add("TexT", dt, "Reihenfolge")
            TextBox16.DataBindings.Add("Text", dt, "PFTyp")
            TextBox17.DataBindings.Add("Text", dt, "Status")
            TextBox18.DataBindings.Add("Text", dt, "Brieftext")
            TextBox19.DataBindings.Add("Text", dt, "Bemerkungen")
            bm = Me.BindingContext(dt)
    

    im Datagridview wird die Tabelle richtig angezeigt, d.h. alle Werte aus beiden Tabellen.

    Die Steuerelemente, die per DataBindings angebunden wurden bleiben leer.

    wo liegt der Fehler?

    Danke im voraus.

    Freitag, 28. Juni 2013 08:04

Antworten

  • Hi,
    wie Elmar vorgeschlagen hat, binde die TextBoxes an das dv-Object. In Deinem Fall laufen die Steuerelemente nicht synchron, da sie unterschiedliche BindingContexte nutzen. Das würde dann so aussehen:

        conn = New OleDbConnection(connstr)
        da = New OleDbDataAdapter(selStr, conn)
        cb = New OleDbCommandBuilder(da)
        dt = New DataTable("Pfändungen")
        ds = New DataSet
        conn.Open()
        da.Fill(dt)
        da.Fill(ds, "Pfändungen")
        conn.Close()
        dv = New DataView(ds.Tables("Pfändungen"))
        DataGridView1.DataSource = dv
        DataGridView1.Columns(0).Visible = False
        TextBox1.DataBindings.Add("Text", dv, "Nr")
        Dim b1 As Binding = New Binding("Text", dv, "PFDatum")
        AddHandler b1.Format, AddressOf DatToDateString
        AddHandler b1.Parse, AddressOf DateStrToDat
        Dim b2 As Binding = New Binding("Text", dv, "PFGesamtbetrag")
        AddHandler b2.Format, AddressOf DecToCurrString
        AddHandler b2.Parse, AddressOf CurStrToDecimal
        Dim b3 As Binding = New Binding("Text", dv, "PFÜberweisungsbetrag")
        AddHandler b3.Format, AddressOf DecToCurrString
        AddHandler b3.Parse, AddressOf CurStrToDecimal
        TextBox2.DataBindings.Add(b1)
        TextBox3.DataBindings.Add(b2)
        TextBox4.DataBindings.Add(b3)
        TextBox5.DataBindings.Add("Text", dv, "Empfänger1")
        TextBox6.DataBindings.Add("Text", dv, "Empfänger2")
        TextBox7.DataBindings.Add("Text", dv, "Empfänger3")
        TextBox8.DataBindings.Add("Text", dv, "Empfänger4")
        TextBox9.DataBindings.Add("Text", dv, "Empfängerzeichen")
        TextBox10.DataBindings.Add("Text", dv, "Empfängerbank")
        TextBox11.DataBindings.Add("Text", dv, "Empfängerkto")
        TextBox12.DataBindings.Add("Text", dv, "empfängerblz")
        Dim b4 As Binding = New Binding("Text", dv, "DatumersteZahlung")
        AddHandler b4.Format, AddressOf DatToDateString
        AddHandler b4.Parse, AddressOf DateStrToDat
        TextBox13.DataBindings.Add(b4)
        TextBox14.DataBindings.Add("Text", dv, "UnserZeichen")
        TextBox15.DataBindings.Add("TexT", dv, "Reihenfolge")
        TextBox16.DataBindings.Add("Text", dv, "PFTyp")
        TextBox17.DataBindings.Add("Text", dv, "Status")
        TextBox18.DataBindings.Add("Text", dv, "Brieftext")
        TextBox19.DataBindings.Add("Text", dv, "Bemerkungen")
        bm = Me.BindingContext(dv)

    Besser wäre aber, eine BindingSource zu nutzen, z.B. wie nachfolgend. Da erübrigt sich der Stress mit BindingManager und Sicht. Die Variable bs1 kann natürlich auch als Field klassenweit sichtbar deklariert werden, wie die anderen Variablen.

    conn = New OleDbConnection(connstr) da = New OleDbDataAdapter(selStr, conn) cb = New OleDbCommandBuilder(da) dt = New DataTable("Pfändungen") ds = New DataSet da.Fill(dt) da.Fill(ds, "Pfändungen") Dim bs1 As New BindingSource(ds, "Pfändungen") DataGridView1.DataSource = bs1 DataGridView1.Columns(0).Visible = False TextBox1.DataBindings.Add("Text", bs1, "Nr") Dim b1 As Binding = New Binding("Text", bs1, "PFDatum") AddHandler b1.Format, AddressOf DatToDateString AddHandler b1.Parse, AddressOf DateStrToDat Dim b2 As Binding = New Binding("Text", bs1, "PFGesamtbetrag") AddHandler b2.Format, AddressOf DecToCurrString AddHandler b2.Parse, AddressOf CurStrToDecimal Dim b3 As Binding = New Binding("Text", bs1, "PFÜberweisungsbetrag") AddHandler b3.Format, AddressOf DecToCurrString AddHandler b3.Parse, AddressOf CurStrToDecimal TextBox2.DataBindings.Add(b1) TextBox3.DataBindings.Add(b2) TextBox4.DataBindings.Add(b3) TextBox5.DataBindings.Add("Text", bs1, "Empfänger1") TextBox6.DataBindings.Add("Text", bs1, "Empfänger2") TextBox7.DataBindings.Add("Text", bs1, "Empfänger3") TextBox8.DataBindings.Add("Text", bs1, "Empfänger4") TextBox9.DataBindings.Add("Text", bs1, "Empfängerzeichen") TextBox10.DataBindings.Add("Text", bs1, "Empfängerbank") TextBox11.DataBindings.Add("Text", bs1, "Empfängerkto") TextBox12.DataBindings.Add("Text", bs1, "empfängerblz") Dim b4 As Binding = New Binding("Text", bs1, "DatumersteZahlung") AddHandler b4.Format, AddressOf DatToDateString AddHandler b4.Parse, AddressOf DateStrToDat TextBox13.DataBindings.Add(b4) TextBox14.DataBindings.Add("Text", bs1, "UnserZeichen") TextBox15.DataBindings.Add("TexT", bs1, "Reihenfolge") TextBox16.DataBindings.Add("Text", bs1, "PFTyp") TextBox17.DataBindings.Add("Text", bs1, "Status") TextBox18.DataBindings.Add("Text", bs1, "Brieftext") TextBox19.DataBindings.Add("Text", bs1, "Bemerkungen")

    --
    Peter

    Sonntag, 30. Juni 2013 15:29

Alle Antworten

  • Freitag, 28. Juni 2013 12:06
  • Hallo,

    Du erzeugst einmal eine DataView und bindest sie ans DataGridView. Für die TextBoxen verwendest Du jedoch dt, was in DataTable.DefaultView resultiert. Und ausserdem durch das doppelte Fill nichts mit dem DataSet zu tun hat (solltest Du also ganz weglassen).

    Damit alle die gleiche Bindung bekommen ist es sinnvoller eine BindingSource zu verwenden. Dort kannst Du die DataSource zuweisen und später mal wechseln, ohne dass die Bindungen davon beeinträchtigt werden - auch andere Dinge wie Filter, Sortierungen sind darüber leichter zu regeln.

    Gruß Elmar

    Freitag, 28. Juni 2013 15:47
    Beantworter
  • Hallo Elmar,

    hättest du hierfür vielleicht mal ein kleines Beispiel für mich?

    Danke im voraus

    Sonntag, 30. Juni 2013 13:23
  • Hi,
    wie Elmar vorgeschlagen hat, binde die TextBoxes an das dv-Object. In Deinem Fall laufen die Steuerelemente nicht synchron, da sie unterschiedliche BindingContexte nutzen. Das würde dann so aussehen:

        conn = New OleDbConnection(connstr)
        da = New OleDbDataAdapter(selStr, conn)
        cb = New OleDbCommandBuilder(da)
        dt = New DataTable("Pfändungen")
        ds = New DataSet
        conn.Open()
        da.Fill(dt)
        da.Fill(ds, "Pfändungen")
        conn.Close()
        dv = New DataView(ds.Tables("Pfändungen"))
        DataGridView1.DataSource = dv
        DataGridView1.Columns(0).Visible = False
        TextBox1.DataBindings.Add("Text", dv, "Nr")
        Dim b1 As Binding = New Binding("Text", dv, "PFDatum")
        AddHandler b1.Format, AddressOf DatToDateString
        AddHandler b1.Parse, AddressOf DateStrToDat
        Dim b2 As Binding = New Binding("Text", dv, "PFGesamtbetrag")
        AddHandler b2.Format, AddressOf DecToCurrString
        AddHandler b2.Parse, AddressOf CurStrToDecimal
        Dim b3 As Binding = New Binding("Text", dv, "PFÜberweisungsbetrag")
        AddHandler b3.Format, AddressOf DecToCurrString
        AddHandler b3.Parse, AddressOf CurStrToDecimal
        TextBox2.DataBindings.Add(b1)
        TextBox3.DataBindings.Add(b2)
        TextBox4.DataBindings.Add(b3)
        TextBox5.DataBindings.Add("Text", dv, "Empfänger1")
        TextBox6.DataBindings.Add("Text", dv, "Empfänger2")
        TextBox7.DataBindings.Add("Text", dv, "Empfänger3")
        TextBox8.DataBindings.Add("Text", dv, "Empfänger4")
        TextBox9.DataBindings.Add("Text", dv, "Empfängerzeichen")
        TextBox10.DataBindings.Add("Text", dv, "Empfängerbank")
        TextBox11.DataBindings.Add("Text", dv, "Empfängerkto")
        TextBox12.DataBindings.Add("Text", dv, "empfängerblz")
        Dim b4 As Binding = New Binding("Text", dv, "DatumersteZahlung")
        AddHandler b4.Format, AddressOf DatToDateString
        AddHandler b4.Parse, AddressOf DateStrToDat
        TextBox13.DataBindings.Add(b4)
        TextBox14.DataBindings.Add("Text", dv, "UnserZeichen")
        TextBox15.DataBindings.Add("TexT", dv, "Reihenfolge")
        TextBox16.DataBindings.Add("Text", dv, "PFTyp")
        TextBox17.DataBindings.Add("Text", dv, "Status")
        TextBox18.DataBindings.Add("Text", dv, "Brieftext")
        TextBox19.DataBindings.Add("Text", dv, "Bemerkungen")
        bm = Me.BindingContext(dv)

    Besser wäre aber, eine BindingSource zu nutzen, z.B. wie nachfolgend. Da erübrigt sich der Stress mit BindingManager und Sicht. Die Variable bs1 kann natürlich auch als Field klassenweit sichtbar deklariert werden, wie die anderen Variablen.

    conn = New OleDbConnection(connstr) da = New OleDbDataAdapter(selStr, conn) cb = New OleDbCommandBuilder(da) dt = New DataTable("Pfändungen") ds = New DataSet da.Fill(dt) da.Fill(ds, "Pfändungen") Dim bs1 As New BindingSource(ds, "Pfändungen") DataGridView1.DataSource = bs1 DataGridView1.Columns(0).Visible = False TextBox1.DataBindings.Add("Text", bs1, "Nr") Dim b1 As Binding = New Binding("Text", bs1, "PFDatum") AddHandler b1.Format, AddressOf DatToDateString AddHandler b1.Parse, AddressOf DateStrToDat Dim b2 As Binding = New Binding("Text", bs1, "PFGesamtbetrag") AddHandler b2.Format, AddressOf DecToCurrString AddHandler b2.Parse, AddressOf CurStrToDecimal Dim b3 As Binding = New Binding("Text", bs1, "PFÜberweisungsbetrag") AddHandler b3.Format, AddressOf DecToCurrString AddHandler b3.Parse, AddressOf CurStrToDecimal TextBox2.DataBindings.Add(b1) TextBox3.DataBindings.Add(b2) TextBox4.DataBindings.Add(b3) TextBox5.DataBindings.Add("Text", bs1, "Empfänger1") TextBox6.DataBindings.Add("Text", bs1, "Empfänger2") TextBox7.DataBindings.Add("Text", bs1, "Empfänger3") TextBox8.DataBindings.Add("Text", bs1, "Empfänger4") TextBox9.DataBindings.Add("Text", bs1, "Empfängerzeichen") TextBox10.DataBindings.Add("Text", bs1, "Empfängerbank") TextBox11.DataBindings.Add("Text", bs1, "Empfängerkto") TextBox12.DataBindings.Add("Text", bs1, "empfängerblz") Dim b4 As Binding = New Binding("Text", bs1, "DatumersteZahlung") AddHandler b4.Format, AddressOf DatToDateString AddHandler b4.Parse, AddressOf DateStrToDat TextBox13.DataBindings.Add(b4) TextBox14.DataBindings.Add("Text", bs1, "UnserZeichen") TextBox15.DataBindings.Add("TexT", bs1, "Reihenfolge") TextBox16.DataBindings.Add("Text", bs1, "PFTyp") TextBox17.DataBindings.Add("Text", bs1, "Status") TextBox18.DataBindings.Add("Text", bs1, "Brieftext") TextBox19.DataBindings.Add("Text", bs1, "Bemerkungen")

    --
    Peter

    Sonntag, 30. Juni 2013 15:29
  • Hallo Peter,

    ich habe jetzt folgendes probiert:

    Imports System.Data.OleDb Imports System.IO Public Class Pfändungen Private dbpfad As String = Application.StartupPath & "\gs_personal.mdb" Private connstr As String = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source =" & dbpfad Private selStr As String = "SELECT * FROM Pfändungen INNER JOIN Personal ON Pfändungen.NR = Personal.NR" Private conn As OleDbConnection Private da As OleDbDataAdapter Private dt As DataTable Private ds As DataSet Private cb As OleDbCommandBuilder Private bm As BindingManagerBase Private dv As DataView Private bindingsource1 As BindingSource Private bs1 As BindingSource Private Sub Pfändungen_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load conn = New OleDbConnection(connstr) da = New OleDbDataAdapter(selStr, conn) cb = New OleDbCommandBuilder(da) dt = New DataTable("Pfändungen") ds = New DataSet da.Fill(dt) da.Fill(ds, "Pfändungen") Dim bs1 As New BindingSource(ds, "Pfändungen") DataGridView1.DataSource = bs1 DataGridView1.Columns(0).Visible = False TextBox1.DataBindings.Add("Text", bs1, "Nr", True) Dim b1 As Binding = New Binding("Text", bs1, "PFDatum") AddHandler b1.Format, AddressOf DatToDateString AddHandler b1.Parse, AddressOf DateStrToDat Dim b2 As Binding = New Binding("Text", bs1, "PFGesamtbetrag") AddHandler b2.Format, AddressOf DecToCurrString AddHandler b2.Parse, AddressOf CurStrToDecimal Dim b3 As Binding = New Binding("Text", bs1, "PFÜberweisungsbetrag") AddHandler b3.Format, AddressOf DecToCurrString AddHandler b3.Parse, AddressOf CurStrToDecimal TextBox2.DataBindings.Add(b1) TextBox3.DataBindings.Add(b2) TextBox4.DataBindings.Add(b3) TextBox5.DataBindings.Add("Text", bs1, "Empfänger1") TextBox6.DataBindings.Add("Text", bs1, "Empfänger2") TextBox7.DataBindings.Add("Text", bs1, "Empfänger3") TextBox8.DataBindings.Add("Text", bs1, "Empfänger4") TextBox9.DataBindings.Add("Text", bs1, "Empfängerzeichen") TextBox10.DataBindings.Add("Text", bs1, "Empfängerbank") TextBox11.DataBindings.Add("Text", bs1, "Empfängerkto") TextBox12.DataBindings.Add("Text", bs1, "empfängerblz") Dim b4 As Binding = New Binding("Text", bs1, "DatumersteZahlung") AddHandler b4.Format, AddressOf DatToDateString AddHandler b4.Parse, AddressOf DateStrToDat TextBox13.DataBindings.Add(b4) TextBox14.DataBindings.Add("Text", bs1, "UnserZeichen") TextBox15.DataBindings.Add("TexT", bs1, "Reihenfolge") TextBox16.DataBindings.Add("Text", bs1, "PFTyp") TextBox17.DataBindings.Add("Text", bs1, "Status") TextBox18.DataBindings.Add("Text", bs1, "Brieftext") TextBox19.DataBindings.Add("Text", bs1, "Bemerkungen") End Sub

    Allerdings ist das Ergebnis das gleiche:

    Leider bleiben die TextBoxen weiterhin leer.

    Fehlt hier vielleicht noch ein Verweis?

    Danke im voraus

    Stefan

    Sonntag, 30. Juni 2013 15:48
  • Muss man nicht noch Bindingsource.Position setzten, damit die Controls wissen wo sich die Auswahl gerade befindet und somit welcher Datensatz an den Controls gebunden ist...
    Sonntag, 30. Juni 2013 19:42
  • Erstmals Danke für die schnelle und kompetente Hilfe an alle.

    Habe den Fehler gefunden. Es war die SQL - Abfrage. Habe sie jetzt folgendermaßen geändert:

    Private selStr As String = "SELECT Pfändungen.*,Personal.Name1,Personal.Name2 FROM Pfändungen INNER JOIN Personal ON Pfändungen.NR = Personal.NR"

    Seitdem funktioniert die ganze Sache. die Navigation der Datensätze funktioniert jetzt ebenfalls.

    Danke nochmals

    Stefan

    Montag, 1. Juli 2013 07:41