Discussion:
Tabellen verbinden und im DataGridView anzeigen
(zu alt für eine Antwort)
Jörn Janz
2008-01-20 22:37:01 UTC
Permalink
Hallo NG,

ich möchte in einem DataGridView Auftragsdaten (Tabelle:
uebertragungsprotokoll) und die passenden Artikeldaten in einem
DataGridView anzeigen. Ein Auftrag enthält immer nur einen Artikel.
Die Artikeldaten befinden sich in einer weiteren Tabelle.
Mein Problem ist folgendes:
Die Artikelnummer - "artnr" in der Tabelle "prodorders" hat leider ein
anderes Format wie die Artikelnummer
in der Artikel Tabelle. In der Tabelle "prodorders" hat die
Artikelnummer führende Nullen und in der Tabelle mit den Artikeldaten
fehlen die Nullen.
Beispiel: prodorders: 0004711 / artikel: 4711

Gibt es eine Möglichkeit in einer SQL Abfrage die führenden Nullen zu
"ignorieren"?

Sonst würde ich die Tabelle prodorders einlesen und die führenden
Nullen entfernen und dann mit der
Artikel Tabelle verbinden. Ich habe leider keine große Erfahrung mit
DataSet,DataTable & Co. und würde
mich über Tips sehr freuen.

Gruß - Jörn

Dim conn As New OdbcConnection(strConn) ' strConn = meine ODBC
Verbindung

Try
conn.Open()
Dim selCmd As New OdbcCommand("SELECT
Fertigungsauftrag,mhd,artnr FROM uebertragungsprotokoll.prodorders p
where prodlinie=2 order by mhd desc", conn)
Dim da As New OdbcDataAdapter(selCmd)
Dim ds As New DataSet
Dim dt As New DataTable

da.Fill(dt)
Dim bs As New BindingSource
dv = dt.DefaultView
bs.DataSource = dt

With Me.dgvFertigungsauftrag ' mein DataGridView im
Formular
.MultiSelect = False
.ReadOnly = True
.DataSource = bs
End With

Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler")

Finally
conn.Close()

End Try
Peter Fleischer
2008-01-21 05:09:28 UTC
Permalink
Post by Jörn Janz
Die Artikelnummer - "artnr" in der Tabelle "prodorders" hat leider ein
anderes Format wie die Artikelnummer
in der Artikel Tabelle. In der Tabelle "prodorders" hat die
Artikelnummer führende Nullen und in der Tabelle mit den Artikeldaten
fehlen die Nullen.
Beispiel: prodorders: 0004711 / artikel: 4711
Gibt es eine Möglichkeit in einer SQL Abfrage die führenden Nullen zu
"ignorieren"?
Hi Jörn,
ich vermute mal, dass die Artikelnnumer in "prodorders" eine Zeichenkette
ist und die in "artikel" numerisch ist. Für solchen Fall würde ich als
erstes die Datenbanken konvertieren, so dass die logisch in Beziehung
stehenden Spalten auch physisch in Beziehung gesetzt werden können. Wenn
jedoch die Spalte in "prodorders" als Zeichenkette gewählt wurde, weil auch
alphanumerische Zeichen zulässig sind, gibt es sowieso keine Möglichkeit,
die alphanumerische Spalte mit der numerischen Spalte in Beziehung zu
setzen. Wenn der genutzte Datenbankprovider dies zulässt, wäre vielleicht
die Nutzung einer Konvertierungsfunktion (z.B. Val) möglich.
Post by Jörn Janz
Sonst würde ich die Tabelle prodorders einlesen und die führenden
Nullen entfernen und dann mit der
Artikel Tabelle verbinden. Ich habe leider keine große Erfahrung mit
DataSet,DataTable & Co. und würde
mich über Tips sehr freuen.
Ein "sauberes" Datenbank-Design wäre zuerst anzugehen.

Wenn dies unmöglich ist, dann wäre die Nutzung von Konvertierungsfunktionen
im SQL zu prüfen.

Wenn auch dies unmöglich ist, wäre ein separates Einlesen mit nachfolgender
Konvertierung im Client zu prüfen, z.B. zusätzliche typgerechte Spalte im
Client einfügen und mit einer foreach-Schleife die Daten konvertieren und
ablegen.

Wenn auch dies nicht in Frage kommt, dann beide Tabellen laden und die
Beziehungslogik im Code realisieren.
Post by Jörn Janz
Dim conn As New OdbcConnection(strConn) ' strConn = meine ODBC
Verbindung
Try
conn.Open()
Dim selCmd As New OdbcCommand("SELECT
Fertigungsauftrag,mhd,artnr FROM uebertragungsprotokoll.prodorders p
where prodlinie=2 order by mhd desc", conn)
Dim da As New OdbcDataAdapter(selCmd)
Dim ds As New DataSet
Ein DataSet ist hie rnicht erforderlich, da weiter nur eine DataTable
genutzt wird. Es bleibt aber die Frage, wohin die zweite Tabelle geladen
werden soll.
Post by Jörn Janz
Dim dt As New DataTable
da.Fill(dt)
Dim bs As New BindingSource
dv = dt.DefaultView
Eine Sicht ist nicht erforderlich, wenn eine BindingSource genutzt wird.
Eine BindingSource baut intern eine Sicht auf.
Post by Jörn Janz
bs.DataSource = dt
With Me.dgvFertigungsauftrag ' mein DataGridView im
Formular
...
--
Viele Gruesse

Peter
Jörn Janz
2008-01-21 10:41:52 UTC
Permalink
Hallo Peter,
Post by Peter Fleischer
Hi Jörn,
ich vermute mal, dass die Artikelnnumer in "prodorders" eine Zeichenkette
ist und die in "artikel" numerisch ist. Für solchen Fall würde ich als
erstes die Datenbanken konvertieren....
Ich bekomme die Datenbank gestellt und kann die DB leider nicht
verändern....
Der Datentyp ist in beiden Tabellen VARCHAR.
Post by Peter Fleischer
Post by Jörn Janz
Sonst würde ich die Tabelle prodorders einlesen und die führenden
Nullen entfernen und dann mit der
Artikel Tabelle verbinden. Ich habe leider keine große Erfahrung mit
DataSet,DataTable & Co. und würde
mich über Tips sehr freuen.
Ein "sauberes" Datenbank-Design wäre zuerst anzugehen.
Das Datenbankdesign darf ich leider nicht ändern...
Post by Peter Fleischer
Wenn dies unmöglich ist, dann wäre die Nutzung von Konvertierungsfunktionen
im SQL zu prüfen.
Welche Möglichkeiten bietet mir SQL da?
Post by Peter Fleischer
Wenn auch dies unmöglich ist, wäre ein separates Einlesen mit nachfolgender
Konvertierung im Client zu prüfen, z.B. zusätzliche typgerechte Spalte im
Client einfügen und mit einer foreach-Schleife die Daten konvertieren und
ablegen.
Die Datenkonvertierung bekomme ich hin. Ich würde gerne die prodorders
Tabelle einlesen die führenden Nullen entfernen und
dann DataSet / Dataview (was muss ich da benutzen) mit der Artikel
Tabelle verknüpfen.
Ich komme mit dem verändern nicht klar und dem nachträglich verknüpfen
der Tabell noch nicht klar.

Gruß - Jörn
Peter Fleischer
2008-01-21 11:25:25 UTC
Permalink
Post by Jörn Janz
Post by Peter Fleischer
Wenn dies unmöglich ist, dann wäre die Nutzung von
Konvertierungsfunktionen
im SQL zu prüfen.
Welche Möglichkeiten bietet mir SQL da?
Hi Jörn,
der SQL-Standard bietet da keine Möglichkeit. Die einzelnen
SQL-Implementation könnten da etwas bieten. Da wir nicht wissen, ob du
Sybase, MySQL, DB2 oder Oracle nutzt, kann man nur empfehlen, die
Dokumentation zu dem von dir genutzten Datenbankprovider zu lesen.
Post by Jörn Janz
Post by Peter Fleischer
Wenn auch dies unmöglich ist, wäre ein separates Einlesen mit nachfolgender
Konvertierung im Client zu prüfen, z.B. zusätzliche typgerechte Spalte im
Client einfügen und mit einer foreach-Schleife die Daten konvertieren und
ablegen.
Die Datenkonvertierung bekomme ich hin. Ich würde gerne die prodorders
Tabelle einlesen die führenden Nullen entfernen
Da müsste man die Regeln für die Erstellung der Artikelbezeichner als
Zeichenketten kennen. Davon ausgehend kann man einen regulären Ausdruck
erstellen, der das Gewünschte extrahiert. Wenn die Zeichenketten wirklich
nur numerische Daten enthalten, kann man die Val-Funktion nutzen. Wenn die
Zeichenketten nur ganzahlige Werte enthalten, kann man Integer.TryParse
nutzen und das Ergebnis als Integer ablegen. Das müsste man aber in beiden
Tabellen machen, damit beide Tabellen in Beziehung gesetzt werden können.
Post by Jörn Janz
und
dann DataSet / Dataview (was muss ich da benutzen) mit der Artikel
Tabelle verknüpfen.
Ich komme mit dem verändern nicht klar und dem nachträglich verknüpfen
der Tabell noch nicht klar.
Da wäre folgender Ablauf möglich:
1. DataSet für 2 Tabellen
2. beide Tabellen laden
3. in beiden Tabellen eine Spalte für die Beziehung hinzufügen
4. in beiden Tabellen die Zeichenketten konvertieren
5. Datenbeziehung erstellen

Nachfolgend mal ein Beispiel für den SQL Server und VB)-Anwendung (VS2008):

Dim ds As New DataSet
Dim cn As New SqlConnection(My.Settings.cn)
Dim cmd As New SqlCommand("Select * From Tab1;Select * From Tab2", cn)
Call (New SqlDataAdapter(cmd)).Fill(ds)
With ds
With .Tables(0)
.TableName = "Tab1"
.Columns.Add("ArtNr", GetType(Integer))
Array.ForEach(Of DataRow)(.Select(), _
Function(r As DataRow) Integer.TryParse(r!ArtikelNr, r!ArtNr))
End With
With .Tables(1)
.TableName = "Tab2"
.Columns.Add("ArtNr", GetType(Integer))
Array.ForEach(Of DataRow)(.Select(), _
Function(r As DataRow) Integer.TryParse(r!ArtikelNr, r!ArtNr))
End With
.Relations.Add("rel1", .Tables(0).Columns("ArtNr"), _
.Tables(1).Columns("ArtNr"))
End With
--
Viele Gruesse

Peter
Peter Götz
2008-01-21 09:39:32 UTC
Permalink
Hallo Jörn,
Post by Jörn Janz
ich möchte in einem DataGridView Auftragsdaten
(Tabelle: uebertragungsprotokoll) und die passenden
Artikeldaten in einem DataGridView anzeigen.
Ein Auftrag enthält immer nur einen Artikel.
Die Artikeldaten befinden sich in einer weiteren
Tabelle.
Die Artikelnummer - "artnr" in der Tabelle "prodorders"
hat leider ein anderes Format wie die Artikelnummer
in der Artikel Tabelle. In der Tabelle "prodorders" hat
die Artikelnummer führende Nullen
Das lässt vermuten, dass das betr. Feld keinen
numerischen Datentyp hat, sondern ein Textfeld ist.
Deshalb die erste Frage:

Welchen DatenTyp hat das Feld "artnr" in "prodorders"?
Post by Jörn Janz
und in der Tabelle mit den Artikeldaten fehlen die Nullen.
Beispiel: prodorders: 0004711 / artikel: 4711
Auch hieraus geht nicht hervor welchen Datentyp das Feld
Feld für Deine Artikelnummer in Deiner Artikeltabelle?
Post by Jörn Janz
Gibt es eine Möglichkeit in einer SQL Abfrage die
führenden Nullen zu "ignorieren"?
Solange nicht geklärt ist woher (Datentyp String oder
Programmcode) diese führenden Nullen herkommen,
kann man Deine Frage nicht beantworten.
Post by Jörn Janz
Sonst würde ich die Tabelle prodorders einlesen und
die führenden Nullen entfernen und dann mit der
Artikel Tabelle verbinden.
Zuerst mal muss geklärt werden, welchen Datentyp
das Feld für die Artikelnummer in beiden zu
verknüpfenden Tabellen hat. Wenn, was zu
befürchten ist, eines oder beide diese Felder
Textfelder (String) sind, dann wäre die erste
Überlegung, dies zu ändern und einen für beide
Tabellen übereinstimmenden numerischen
Datentyp zu verwenden.
Post by Jörn Janz
Ich habe leider keine große Erfahrung mit
DataSet,DataTable & Co. und würde mich
über Tips sehr freuen.
Wenn Du lediglich Daten aus zwei "verjointen"
DB-Tabellen in einer DataTable zusammenführen
möchtest, brauchst Du dazu überhaupt kein
DataSet. Das wäre in einem solchen Fall nur
völlig überflüssiger Ballast.
Post by Jörn Janz
Gruß - Jörn
Dim conn As New OdbcConnection(strConn) ' strConn = meine ODBC
Verbindung
Warum ODBC?
Mit welcher Art von Datenbank (SQL-Server, ORACLE,
Jet usw.) arbeitest Du?
Post by Jörn Janz
Try
conn.Open()
Dim selCmd As New OdbcCommand("SELECT
Fertigungsauftrag,mhd,artnr
FROM uebertragungsprotokoll.prodorders p
where prodlinie=2 order by mhd desc", conn)
Du wärest gut beraten, Deine Kriterienwerte nicht direkt in
den jeweiligen SQL-String zu schreiben, sondern mit
typgerechten Paramterobjekten zu arbeiten.
Post by Jörn Janz
Dim da As New OdbcDataAdapter(selCmd)
Dim ds As New DataSet
s.oben:
um eine einzige DataTable zu verwalten brauchst Du kein
DataSet. Das würde Sinn machen, wenn Du z.B. mehrere
über DataRelations verknüpfte DataTables zu verwalten
hättest.
Post by Jörn Janz
Dim dt As New DataTable
da.Fill(dt)
Dim bs As New BindingSource
dv = dt.DefaultView
bs.DataSource = dt
Ein BindingSource-Objekt kapselt bereits eine DataView.
Wozu erstelltst Du ein weiteres DataView-Objekt?
Post by Jörn Janz
With Me.dgvFertigungsauftrag '
mein DataGridView im Formular
.MultiSelect = False
.ReadOnly = True
.DataSource = bs
End With
Die DataSource für ein DataGridView ist letztlich immer
eine DataView-Objekt. Wenn dieses so konkret nicht
angeboten wird, erstellt das DataGridView implizit ein
solches DataView-Objekt.
Es genügt also vollkommen:

Dim DT as DataTable
Dim DV as DataView

DV = New DataView(DT)
DataGridView.DataSource = DV

Das wars auch schon. Kein DataSet, kein Bindingsource-
Objekt. So wird Dein Code übersichtlicher und macht
es Dir auch einfacher, zu verstehen, was da eigentlich
abläuft.
Post by Jörn Janz
Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler")
Finally
conn.Close()
End Try
Unter

www.gssg.de -> Visual Basic -> VB.net

findest Du eine Reihe von Beispielprogrammen mit
dem DataGridView-Control. Die solltest Du Dir
vielleicht mal ansehen um ein Gefühl für das Zusammenspiel
von DataTable, DataView und DataGridView zu bekommen.

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Jörn Janz
2008-01-21 10:57:13 UTC
Permalink
Hallo Peter (Götz),
Post by Peter Götz
Hallo Jörn,
Post by Jörn Janz
ich möchte in einem DataGridView Auftragsdaten
(Tabelle: uebertragungsprotokoll) und die passenden
Artikeldaten in einem DataGridView anzeigen.
Ein Auftrag enthält immer nur einen Artikel.
Die Artikeldaten befinden sich in einer weiteren
Tabelle.
Die Artikelnummer - "artnr" in der Tabelle "prodorders"
hat leider ein anderes Format wie die Artikelnummer
in der Artikel Tabelle. In der Tabelle "prodorders" hat
die Artikelnummer führende Nullen
Das lässt vermuten, dass das betr. Feld keinen
numerischen Datentyp hat, sondern ein Textfeld ist.
Welchen DatenTyp hat das Feld "artnr" in "prodorders"?
beide Felder sind VARCHAR Felder
Post by Peter Götz
Warum ODBC?
Mit welcher Art von Datenbank (SQL-Server, ORACLE,
Jet usw.) arbeitest Du?
Ich arbeite mit einer MySQL Datenbank.
Post by Peter Götz
Du wärest gut beraten, Deine Kriterienwerte nicht direkt in
den jeweiligen SQL-String zu schreiben, sondern mit
typgerechten Paramterobjekten zu arbeiten.
Post by Jörn Janz
Dim da As New OdbcDataAdapter(selCmd)
Dim ds As New DataSet
um eine einzige DataTable zu verwalten brauchst Du kein
DataSet. Das würde Sinn machen, wenn Du z.B. mehrere
über DataRelations verknüpfte DataTables zu verwalten
hättest.
Post by Jörn Janz
Dim dt As New DataTable
da.Fill(dt)
Dim bs As New BindingSource
dv = dt.DefaultView
bs.DataSource = dt
Ein BindingSource-Objekt kapselt bereits eine DataView.
Wozu erstelltst Du ein weiteres DataView-Objekt?
Post by Jörn Janz
With Me.dgvFertigungsauftrag '
mein DataGridView im Formular
.MultiSelect = False
.ReadOnly = True
.DataSource = bs
End With
Die DataSource für ein DataGridView ist letztlich immer
eine DataView-Objekt. Wenn dieses so konkret nicht
angeboten wird, erstellt das DataGridView implizit ein
solches DataView-Objekt.
Dim DT as DataTable
Dim DV as DataView
DV = New DataView(DT)
DataGridView.DataSource = DV
Das wars auch schon. Kein DataSet, kein Bindingsource-
Objekt. So wird Dein Code übersichtlicher und macht
es Dir auch einfacher, zu verstehen, was da eigentlich
abläuft.
Genau in diesen Bereichen liegen meine Lücken. Was spricht gegen den
SQL String? Ich möchte aber nur 3 Spalten angezeigt haben.
Ich bekomme doch dann in Deinem Beispiel im DataGrid View die ganze
Tabelle angezeigt, oder?

Gruß - Jörn
Peter Götz
2008-01-21 13:17:28 UTC
Permalink
Hallo Jörn,
Post by Jörn Janz
Post by Peter Götz
Welchen DatenTyp hat das Feld "artnr" in "prodorders"?
beide Felder sind VARCHAR Felder
Gibt es einen zwingenden Grund dafür?
Wenn es sich wirklich nur um Nummern,
also Ziffern 0 ... 9 handelt, wäre es aus
vielerlei Gründen vorteilhaft, den FeldTyp in
z.B. Int32 zu ändern. Das spart u.a. Speicherplatz
und das suchen nach int32-Werten geht schneller
als das Suchen nach Strings.
Sollte ein num. Datentype aus irgendwelchen Gründen
nicht möglich sein, könntest Du evtl. in der Tabelle mit
den "kurzen"
Artikelnummer in einem einmaligen Durchlauf mit
führenden Nullen auffüllen und so Gleichheit in beiden
Tabellen herstellen.
Post by Jörn Janz
Genau in diesen Bereichen liegen meine Lücken.
Was spricht gegen den SQL String?
Einen SQL-String hast Du auch bei Verwendung von
Parameter-Objekten, aber dieser SQL-String enthält
keine konkreten Wertangaben mehr, sondern nur
noch Platzhalter für die jeweiligen Werte. Die Werte
selbst übergibst Du an das jeweilige Paramter-Objekt
mit ihren tatsächlichen Datentypen, also ohne eine
Umwandlung in Strings, bei der es immer wieder
Probleme mit der richtigen Darstellung der Werte
(z.B. mit u. ohne Anführungszeichen, länderspezifische
Dezimaltrenner und Datumsformate usw., usw.)
Post by Jörn Janz
Ich möchte aber nur 3 Spalten angezeigt haben.
Ich bekomme doch dann in Deinem Beispiel im
DataGrid View die ganze Tabelle angezeigt, oder?
Dann kannst Du im einfachsten Fall gleich von vorneherein
Deine DataTable nur mit diesen 3 Feldern erstellen.
Brauchst Du aus irgendwelchen Gründen eine DataTable
mit mehr Feldern, dann kannst Du im einfachsten Fall
beim DataGridview eine oder mehrere Spalten ausblenden,
wie das nachfolgende Beispiel zeigt.

' /// Code in einer leeren Form
Public Class Form1
Private mDT As DataTable
Private mDV As DataView
Private WithEvents mCM As CurrencyManager

Private WithEvents DGV As DataGridView
Private WithEvents Timer1 As Windows.Forms.Timer
Private mRnd As Random

Private Sub Form1_Load _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles MyBase.Load

DGV = New DataGridView
With DGV
.SetBounds _
(10, 10, _
Me.ClientSize.Width - 20, _
Me.ClientSize.Height - 20)

.Anchor = AnchorStyles.Left Or _
AnchorStyles.Top Or _
AnchorStyles.Right Or _
AnchorStyles.Bottom

.DefaultCellStyle.Font = _
New Font("Arial", 12)

.ColumnHeadersDefaultCellStyle.Font = _
New Font("Arial", 8, FontStyle.Bold)

End With
Me.Controls.Add(DGV)
mRnd = New Random
Timer1 = New Windows.Forms.Timer
End Sub


Private Sub Form1_Shown _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles Me.Shown

Dim i As Integer
CreateData()
DGV.DataSource = mDV
DGV.AutoResizeColumns()

For i = 0 To 3
If i <> 1 Then
DGV.Columns(i).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleRight
End If
Next

Dim W As Integer
For i = 0 To 3
W += DGV.Columns(i).Width
Next
Me.ClientSize = New Size(W + 85, Me.ClientSize.Height)

Timer1.Interval = 2000
Timer1.Start()
End Sub


Private Sub Form1_FormClosing _
(ByVal sender As Object, _
ByVal e As FormClosingEventArgs _
) Handles Me.FormClosing

Timer1.Stop()
Timer1.Dispose()
End Sub


Private Sub CreateData()
Dim i As Integer
Dim DR As DataRow

mDT = New DataTable
With mDT
.Columns.Add("ID", GetType(Integer))
.Columns.Add("Bezeichnung", GetType(String))
.Columns.Add("Menge", GetType(Integer))
.Columns.Add("Preis", GetType(Single))

For i = 1 To 25
DR = .NewRow
DR.Item(0) = i
DR.Item(1) = GetText()
DR.Item(2) = mRnd.Next(0, 300)
DR.Item(3) = GetPrice()
.Rows.Add(DR)
Next
.AcceptChanges()
End With

mDV = New DataView(mDT)

mCM = _
DirectCast(Me.BindingContext(mDV), CurrencyManager)
End Sub


Private Function GetPrice() As Single
Dim Buffer As Double
Buffer = _
Math.Round(mRnd.Next(0, 25) + mRnd.NextDouble, 2)

Return CType(Buffer, Single)
End Function


Private Function GetText() As String
Dim i As Integer
Dim strBuffer As String = ""
Dim Max As Integer = mRnd.Next(5, 15)
For i = 1 To Max
strBuffer &= Chr(mRnd.Next(65, 90))
Next
Return strBuffer
End Function


Private Sub DGV_CellFormatting _
(ByVal sender As Object, _
ByVal e As DataGridViewCellFormattingEventArgs _
) Handles DGV.CellFormatting

If e.ColumnIndex = 3 Then
If e.Value IsNot DBNull.Value Then
e.Value = Format(e.Value, "0.00")
Else
e.Value = ""
End If
e.FormattingApplied = True
End If
End Sub


Private Sub Timer1_Tick _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles Timer1.Tick

DGV.Columns(2).Visible = _
Not DGV.Columns(2).Visible
End Sub
End Class
' \\\ E N T E

Das Beispiel erzeugt eine DataTable mit zugehöriger
DataView und CurrencyManager (im Beispiel nicht
benutzt) und übergibt dem DataGridView-Control die
DataView (mDV) als Datasource. Der Timer Timer1
blendet eine der Spalten abwechselnd aus und ein.

Eine andere Möglichkeit, im DataGridView nur eine
Auswahl von mehreren Columns einer DataTable
anzuzeigen siehst Du im nachfolgenden Beispiel:

' /// Code in einer leeren Form1
Imports System.Text
Public Class Form1
Private WithEvents DGV As DataGridView
Private WithEvents mCM As CurrencyManager
Private mDT As DataTable
Private mDV As DataView
Private mR As New Random

Private Sub Form1_Load _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles Me.Load

CreateData()
CreateControls()

DGV.DataSource = mDV
DGV.AutoResizeColumns()

Me.Show()
ShowDataTable()
End Sub

Private Sub ShowDataTable()
Dim strBuffer As String = ""
For Each DR As DataRow In mDT.Rows
If strBuffer.Length = 0 Then
strBuffer = "ID; Text; Datum"
End If
strBuffer = strBuffer & ControlChars.CrLf & _
DR.Item(0).ToString & "; " & _
DR.Item(1).ToString & "; " & _
DR.Item(2).ToString
Next
MsgBox( _
strBuffer, _
MsgBoxStyle.Information, _
"DataTable (mDT)" _
)
End Sub

Private Sub CreateControls()
Dim i As Integer
Dim strBuffer As String

DGV = New DataGridView
With DGV
.Columns.Clear()

For i = 0 To 1
strBuffer = mDT.Columns(i).ColumnName
.Columns.Add(strBuffer, strBuffer)
.Columns(i).DataPropertyName = strBuffer
If i = 0 Then
.Columns(i).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleRight
Else
.Columns(0).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleLeft
End If
Next i
.AutoGenerateColumns = False

.Bounds = New Rectangle _
( _
10, 10, _
Me.ClientSize.Width - 20, _
Me.ClientSize.Height - 20 _
)

.Anchor = AnchorStyles.Left Or _
AnchorStyles.Top Or _
AnchorStyles.Right Or _
AnchorStyles.Bottom

End With
Me.Controls.Add(DGV)
End Sub

Private Sub CreateData()
Dim i As Integer
Dim DR As DataRow

mDT = New DataTable
With mDT
.Columns.Add("ID", GetType(Integer))
.Columns(0).Unique = True

.Columns.Add("Text", GetType(String))
.Columns.Add("Datum", GetType(Date))

For i = 1 To 20
DR = .NewRow
DR.Item(0) = i
DR.Item(1) = GetRndText(5, 20)
DR.Item(2) = Now.AddDays(mR.Next(0, 30))

.Rows.Add(DR)
Next
.AcceptChanges()
End With
mDV = New DataView(mDT)

mCM = CType _
( _
Me.BindingContext(mDV), _
CurrencyManager _
)
End Sub

Private Function GetRndText _
( _
ByVal MinLen As Integer, _
ByVal MaxLen As Integer _
) As String

Dim i As Integer
Dim SB As New StringBuilder
Dim TextLen As Integer = mR.Next(MinLen, MaxLen)
For i = 1 To TextLen
SB.Append(Chr(mR.Next(97, 122)))
Next
Return StrConv(SB.ToString, VbStrConv.ProperCase)
End Function
End Class
' \\\ E N T E


Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Attila Krick
2008-01-21 16:17:47 UTC
Permalink
Post by Jörn Janz
Hallo NG,
uebertragungsprotokoll) und die passenden Artikeldaten in einem
DataGridView anzeigen. Ein Auftrag enthält immer nur einen Artikel.
Die Artikeldaten befinden sich in einer weiteren Tabelle.
Die Artikelnummer - "artnr" in der Tabelle "prodorders" hat leider ein
anderes Format wie die Artikelnummer
in der Artikel Tabelle. In der Tabelle "prodorders" hat die
Artikelnummer führende Nullen und in der Tabelle mit den Artikeldaten
fehlen die Nullen.
Beispiel: prodorders: 0004711 / artikel: 4711
Gibt es eine Möglichkeit in einer SQL Abfrage die führenden Nullen zu
"ignorieren"?
Hallo Jörg,

warum bastellst Du dir ein ein Abfrage die entwerde in der einen Tabelle
die führenden Null auffüllt oder b) sie in der anderen Tabelle wegkürtzt!

So kannst Du dan die Beiden Abfragen in einem Dataset in Beziehung
setzen ohne die DB tatsächlich antasten zu müssen?

Grüße

Attila Krick
Jörn Janz
2008-01-21 21:17:35 UTC
Permalink
Hallo Peter & Peter,

vielen Dank für Eure Hilfe. Ich habe mit den Tips von Euch die
Tabellen in einem Dataset
untergebracht in der Tables(0) habe ich die führenden Nullen vorab
beseitigt.
Jetzt habe ich in dem Dataset eine "Relation" hinzugefügt.

Wie kann ich mit der Relation arbeiten und die Datensätze in einem
DataGridView unterbringen?

Dim ds As New DataSet

With ds
.Tables.Add(dt0)
.Tables.Add(dt1)
.Relations.Add("Bez1", .Tables(1).Columns("Artikelnummer"), .Tables(0).Columns("artnr"),
False)
End With

Gruß - Jörn
Attila Krick
2008-01-21 21:39:08 UTC
Permalink
Post by Jörn Janz
Hallo Peter & Peter,
vielen Dank für Eure Hilfe. Ich habe mit den Tips von Euch die
Tabellen in einem Dataset
untergebracht in der Tables(0) habe ich die führenden Nullen vorab
beseitigt.
Jetzt habe ich in dem Dataset eine "Relation" hinzugefügt.
Wie kann ich mit der Relation arbeiten und die Datensätze in einem
DataGridView unterbringen?
Dim ds As New DataSet
With ds
.Tables.Add(dt0)
.Tables.Add(dt1)
.Relations.Add("Bez1", .Tables(1).Columns("Artikelnummer"), .Tables(0).Columns("artnr"),
False)
End With
Gruß - Jörn
Hallo Jörn,

wie stellst Du dir die Ansicht vor? Links ein DGV und Rechts das Andere?

Per Hand ohne anspruch auf Vollständigkeit:

1. Eine Instanz von deinem Dataset erzeugen.
2. BindingSource erstellen und als DataSource dein DS angeben
3. BS-Member TabelleA
4. BS für die zweite Tabelle erstellen
5. BS-Member die Beziehung von TabelleA
6. Jeweils eine Instanz von Deinen TableAdapter erstellen und mit Fill das
Dataset füllen
7. BS1 und BS2 ans DGVa und DGVb binden.

Aber am einfachsten schaust Du dir das einmal mit der Drag&Drop-Methode des
Designer an, auch wenn man so nicht wirklich was lernt, was im Hintergund
passiert.

Öffne dazu den Datenquellen-Explorer wenn die Form offen ist. Dann solltest
Du Dein DataSet sehen. Klapp es auf und wähle die übergeordnete Tabelle aus
und ziehe sie auf die Form. Anschließend klappst Du die erste Tabelle im
Explorer auf und da sollte, auf Grund Deiner Beziehung am Schluß die zweite
Tabelle stehen auch diese ziehst Du auf Deine Form.

Der Designer erstellt setzt, macht und tut alles das wie o. beschrieben.

Grüße

Attila
Jörn Janz
2008-01-21 22:53:51 UTC
Permalink
Hallo Attila,
Post by Attila Krick
wie stellst Du dir die Ansicht vor? Links ein DGV und Rechts das Andere?
Nein, in der Auftragstabelle steht die Artikelnummer (nur ein Artikel
pro Auftrag). Ich benötige noch den Artikelnamen und noch zwei weitere
Felder aus der
Artikeltabelle und das ganze soll dann in einer Zeile in einem DGV
dargestellt werden.

Gruß - Jörn
Peter Götz
2008-01-22 08:48:26 UTC
Permalink
Hallo Jörn,
Post by Attila Krick
wie stellst Du dir die Ansicht vor? Links ein DGV
und Rechts das Andere?
Nein, in der Auftragstabelle steht die Artikelnummer
(nur ein Artikel pro Auftrag). Ich benötige noch den
Artikelnamen und noch zwei weitere Felder aus der
Artikeltabelle und das ganze soll dann in einer Zeile
in einem DGV dargestellt werden.
Den prakt. Einsatz von DataRelation-Objekten kannst
du Dir in den Beispielen

www.gssg.de -> Visua Basic -> VB.net
-> DataGridView Relation
-> DataGridView Relation 3

ansehen. Ein weiteres Beispiel

-> DataGridView Master/Slave

zeigt eine andere Möglichkeit mit Master- und
Detaildaten aus zwei DataTables zu arbeiten.

Aus Deinen bisherigen Beschreibungen wird immer
noch nicht so recht klar, wie Dein DB-Design
tatsächlich aussieht, bzw. wie Deine Bedientechnologie
gestaltet sein soll.
Ist der Ausgangpunkt ein bestimmter Auftrag oder ist
es ein bestimmter Artikel?
Was soll letztlich mit den Daten gemacht werden?
Sollen sie nur eingesehen werden, oder ist eine
Bearbeitung (Ändern, Löschen, Hinzufügen) der
Daten gewünscht?
Wenn ja, was soll wo (in welcher Tabelle) geändert
werden?

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Jörn Janz
2008-01-22 09:29:14 UTC
Permalink
Hallo Peter,
Post by Peter Götz
Den prakt. Einsatz von DataRelation-Objekten kannst
du Dir in den Beispielen
www.gssg.de-> Visua Basic -> VB.net
-> DataGridView Relation
-> DataGridView Relation 3
ansehen. Ein weiteres Beispiel
-> DataGridView Master/Slave
Die Beispiele gucke ich mir gleich mal an.
Post by Peter Götz
noch nicht so recht klar, wie Dein DB-Design
tatsächlich aussieht,
Tabelle Auftrag:
ID, Auftragsnummer, artnr, MHD, Linie

Tabelle Artikel:
ID, Artikelnummer, Produktbez, EANCode
Post by Peter Götz
bzw. wie Deine Bedientechnologie gestaltet sein soll.
In einem (!) DataGridView möchte ich die Auftragsnummer, MHD,
Artikelnummer, Produktbez
anzeigen . Es sollen nur Datensätze einer Linie angezeigt werden. Die
Sortierung erfolgt nach dem MHD.
(Filtern und sortieren nach MHD geben ich schon in dem SQL Statement
mit).
In der Tabelle Auftrag befinden sich ca. 50 Datensätze.
In der Tabelle befinden sich immer nur die zur Zeit aktuellen
Aufträge.
Die Artikel Tabelle enthält ca. 60 Artikel.
Der Benutzer soll dann in dem DataGridView den Auftrag auswählen
können.
Die Datensätze sind nicht änderbar und es wird nichts
zurückgeschrieben.
Keine Bearbeitung, Kein Ändern, Löschen oder Hinzufügen.
"Nur" Anzeigen.
Den vom Benutzer gewählten Datensatz verarbeite ich dann weiter, aber
damit komme ich dann klar.

Gruß - Jörn
Attila Krick
2008-01-22 16:19:42 UTC
Permalink
Post by Jörn Janz
Hallo Peter,
Post by Peter Götz
Den prakt. Einsatz von DataRelation-Objekten kannst
du Dir in den Beispielen
www.gssg.de-> Visua Basic -> VB.net
-> DataGridView Relation
-> DataGridView Relation 3
ansehen. Ein weiteres Beispiel
-> DataGridView Master/Slave
Die Beispiele gucke ich mir gleich mal an.
Post by Peter Götz
noch nicht so recht klar, wie Dein DB-Design
tatsächlich aussieht,
ID, Auftragsnummer, artnr, MHD, Linie
ID, Artikelnummer, Produktbez, EANCode
Post by Peter Götz
bzw. wie Deine Bedientechnologie gestaltet sein soll.
In einem (!) DataGridView möchte ich die Auftragsnummer, MHD,
Artikelnummer, Produktbez
anzeigen . Es sollen nur Datensätze einer Linie angezeigt werden. Die
Sortierung erfolgt nach dem MHD.
(Filtern und sortieren nach MHD geben ich schon in dem SQL Statement
mit).
In der Tabelle Auftrag befinden sich ca. 50 Datensätze.
In der Tabelle befinden sich immer nur die zur Zeit aktuellen
Aufträge.
Die Artikel Tabelle enthält ca. 60 Artikel.
Der Benutzer soll dann in dem DataGridView den Auftrag auswählen
können.
Die Datensätze sind nicht änderbar und es wird nichts
zurückgeschrieben.
Keine Bearbeitung, Kein Ändern, Löschen oder Hinzufügen.
"Nur" Anzeigen.
Den vom Benutzer gewählten Datensatz verarbeite ich dann weiter, aber
damit komme ich dann klar.
Gruß - Jörn
a
Attila Krick
2008-01-22 16:19:59 UTC
Permalink
Post by Jörn Janz
Hallo Peter,
Post by Peter Götz
Den prakt. Einsatz von DataRelation-Objekten kannst
du Dir in den Beispielen
www.gssg.de-> Visua Basic -> VB.net
-> DataGridView Relation
-> DataGridView Relation 3
ansehen. Ein weiteres Beispiel
-> DataGridView Master/Slave
Die Beispiele gucke ich mir gleich mal an.
Post by Peter Götz
noch nicht so recht klar, wie Dein DB-Design
tatsächlich aussieht,
ID, Auftragsnummer, artnr, MHD, Linie
ID, Artikelnummer, Produktbez, EANCode
Post by Peter Götz
bzw. wie Deine Bedientechnologie gestaltet sein soll.
In einem (!) DataGridView möchte ich die Auftragsnummer, MHD,
Artikelnummer, Produktbez
anzeigen . Es sollen nur Datensätze einer Linie angezeigt werden. Die
Sortierung erfolgt nach dem MHD.
(Filtern und sortieren nach MHD geben ich schon in dem SQL Statement
mit).
In der Tabelle Auftrag befinden sich ca. 50 Datensätze.
In der Tabelle befinden sich immer nur die zur Zeit aktuellen
Aufträge.
Die Artikel Tabelle enthält ca. 60 Artikel.
Der Benutzer soll dann in dem DataGridView den Auftrag auswählen
können.
Die Datensätze sind nicht änderbar und es wird nichts
zurückgeschrieben.
Keine Bearbeitung, Kein Ändern, Löschen oder Hinzufügen.
"Nur" Anzeigen.
Den vom Benutzer gewählten Datensatz verarbeite ich dann weiter, aber
damit komme ich dann klar.
Gruß - Jörn
Hallo Jörn,

so ganz klar wirds bei mir noch immer nicht, heißt das pro Kunde ein
Artikel oder mehrer?

Wenn mehrere ein DGV mit allen Bestellung und ein zweites DGV für die
dazugehörigen Artikel?

Oder Alle Kunden sooft in einem DGV wiederholen wie Artikel bestellt
wurden?

müller socken
müller hosen
meier socken
etc.


?!?!?!?


Grüße

Attila
Jörn Janz
2008-01-22 18:53:50 UTC
Permalink
Hallo Attila,
Post by Peter Götz
Hallo Jörn,
so ganz klar wirds bei mir noch immer nicht, heißt das pro Kunde ein
Artikel oder mehrer?
2 Tabellen
Tabelle 1 enthält die Auftragsdaten
Tabelle 2 enthält die Artikeldaten

Die Mastertabelle ist Tabelle 1 mit den Auftragsdaten
1 Produktionsauftrag enthält nur einen Artikel
1 x DGV auf dem Formular zur Auswahl des Datensatz
In dem DGV möchte / muss ich bereits die Bezeichnung aus der
Artikeltabelle anzeigen.

Beispiel:
Tabelle 1
ID, AuftragNr, ArtikelNr, MHD
1, 22, 0004711, 22.03.2008
2, 23, 0004712, 22.04.2008

Tabelle 2
ID, Artikelnummer, Bezeichnung, EANCode
1, 4711, Socken, 4012345678123
2, 4712, Hose, 4058745123658

Um bei Deinem Beispiel zu bleiben:
Heute sollen auf der Produktionslinie Socken gekennzeichnet werden
Also wählt der Mitarbeiter an dem Rechner seinen Auftrag aus und
bekommt alle für Ihn wichtigen
Daten zur verfügung gestellt.

Gruß - Jörn
Peter Fleischer
2008-01-22 20:28:22 UTC
Permalink
Post by Attila Krick
so ganz klar wirds bei mir noch immer nicht, heißt das pro Kunde ein
Artikel oder mehrer?
2 Tabellen
Tabelle 1 enthält die Auftragsdaten
Tabelle 2 enthält die Artikeldaten

Die Mastertabelle ist Tabelle 1 mit den Auftragsdaten
___


Hi Jörn,
hier mal eine Demo zu deinem Problem und deinen Beispieldaten. Kopier das
einfach in den Codeteil eines leeren Formulars einer VB-Windows-Anwendung.
Das Problem bei deiner Schilderung ist, dass Master mit Child zu vertauschen
ist. Das geht, solange IMMER wirklich auch genau 1:1-Daten enthalten sind.

Public Class Form1

Dim tb As New TextBox

Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

' daten laden
Dim ds As New DataSet
With ds.Tables.Add
.Columns.Add("ID", GetType(Integer))
.Columns(0).AutoIncrement = True
.Columns.Add("AuftragNr", GetType(String))
.Columns.Add("ArtikelNr", GetType(String))
.Columns.Add("MHD", GetType(String))
.Rows.Add(New Object() {1, "22", "0004711", "22.03.2008"})
.Rows.Add(New Object() {2, "23", "0004712", "22.04.2008"})
End With
With ds.Tables.Add
.Columns.Add("ID", GetType(Integer))
.Columns(0).AutoIncrement = True
.Columns.Add("Artikelnummer", GetType(String))
.Columns.Add("Bezeichnung", GetType(String))
.Columns.Add("EANCode", GetType(String))
.Rows.Add(New Object() {1, "4711", "Socken", "4012345678123"})
.Rows.Add(New Object() {2, "4712", "Hose", "4058745123658"})
End With

' verknüpfen
With ds
With .Tables(0)
.TableName = "Tab1"
.Columns.Add("ArtNr", GetType(Integer))
For Each r As DataRow In .Rows
r!ArtNr = CInt(r!ArtikelNr)
Next
End With
With .Tables(1)
.TableName = "Tab2"
.Columns.Add("ArtNr", GetType(Integer))
For Each r As DataRow In .Rows
r!ArtNr = CInt(r!Artikelnummer)
Next
End With
.Relations.Add("rel1", .Tables(1).Columns("ArtNr"), _
.Tables(0).Columns("ArtNr"))
End With

' Expression-Spalte
ds.Tables(0).Columns.Add("Bezeichnung", GetType(String),
"parent(rel1).Bezeichnung")

' Grind-Anzeige
Dim dgv As New DataGridView
Me.Controls.Add(dgv)
With dgv
.Dock = DockStyle.Fill
.DataSource = New BindingSource(ds, "Tab1")
End With

End Sub

End Class
--
Viele Gruesse

Peter
Loading...