| |
VB.NET - FortgeschritteneTreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 28.02.18 11:42 |
| Hallo zusammen,
habe hier einen alten VBA Code eingestellt, mit dem konnte ich in Accsess wunderbar ein TV befüllen.
nun wie macht man es in VB.Net ? bzw. mit Datatable, Dataset
habe 3 typisierte Tabellen aus denen die TV Daten kommen sollen.
- Warengruppe
- Artikelgruppe
- dann die Artikel anhängen
würde mich freuen wenn mich da jemand unterstützen kann.
ich möchte meine Form etwas strukturierter gestalten also auch Eingaben sollen wieder gemacht werden können.
VBA - Code
Public Sub tvBem_Laden()
' TreeView laden
Dim objBem As Object
Dim Nod As Object
Dim rst As DAO.Recordset
On Error GoTo tvBem_Laden_Error
LockWindowUpdate (tvBem.hwnd)
' Verweis auf Treeview setzen
Set objBem = Me!tvBem.Object
'Treeview leeren
objBem.Nodes.Clear
' Alle Plattformen
sSql = "SELECT * FROM tblPlattform"
Set rst = DB.OpenRecordset(sSql, dbOpenSnapshot)
' TreeView sortiert füllen
Do While Not rst.EOF
' Key besteht aus "P" und PlattformText
Set Nod = objBem.Nodes.Add(Key:="P" & CStr(rst!PlID), _
Text:="Typ " & rst!PlText, _
Image:=6)
Nod.ExpandedImage = 1
Nod.Expanded = True
rst.MoveNext
Loop
rst.Close
' Alle Produktgruppen eintragen
sSql = "SELECT DISTINCT tblArtikel.Pl_ID, tblArtikel.Pr_ID," & _
"tblProduktgruppe.PrText " & _
"FROM tblProduktgruppe RIGHT JOIN (tblPlattform RIGHT JOIN tblArtikel" & _
"ON tblPlattform.PlID = tblArtikel.Pl_ID) " & _
"ON tblProduktgruppe.PrID = tblArtikel.Pr_ID"
Set rst = DB.OpenRecordset(sSql, dbOpenSnapshot)
Do While Not rst.EOF
Set Nod = objBem.Nodes.Add(relative:="P" & CStr(rst!Pl_ID), _
Relationship:=4, _
Key:="G" & CStr(rst!Pr_ID) & "P" & CStr( _
rst!Pl_ID), _
Text:="Zsb.: " & rst!PrText, _
Image:=21)
rst.MoveNext
Loop
rst.Close
' Alle Artikel eintragen
sSql = "SELECT ArtID, Pr_ID, Pl_ID, ArtSachnummer FROM tblArtikel"
Set rst = DB.OpenRecordset(sSql, dbOpenSnapshot)
Do While Not rst.EOF
Set Nod = objBem.Nodes.Add(relative:="G" & CStr(rst!Pr_ID) & "P" & CStr( _
rst!Pl_ID), _
Relationship:=4, _
Key:="B" & CStr(rst!ArtID), _
Text:=rst!ArtSachnummer, _
Image:=15)
rst.MoveNext
Loop
rst.Close
On Error GoTo 0
LockWindowUpdate (0)
Exit Sub
tvBem_Laden_Error:
LockWindowUpdate (0)
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure" & _
"tvBem_Laden of VBA Dokument Form_frmBem"
End Sub | |
Re: TreeView befüllen in VB2010 | | | Autor: Souffleurlos | Datum: 28.02.18 16:00 |
| Hallo,
ich würde den alten Code zuerst mal optimieren.
Zum Beispiel mit:
With objBem.Nodes
.Add ...
End With
macht den Code gleich mal 20% schneller ;) da Du ja zwei Loops davon hast. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 28.02.18 16:29 |
| Hallo Souffleurlos,
Danke erst mal
ich denke hast mich nicht ganz verstanden? ich möchte das in VB.Net machen und weiß gerade nicht
wie man da die Abfragen zu macht.
so soll der Baum aus den Tabellen Warengruppe, Artikelgruppe, Artikeldetails aussehen
Root
Warengruppe
Artikelgruppe
Artikeldetails (Artikelnummer, Artikelbezeichnung) | |
Beispiel: Datarow-Spaltenwerte in TreeView eintragen | | | Autor: Manfred X | Datum: 01.03.18 06:15 |
| Ich nehme an, die Daten werden in Dataset/Datatable geladen.
Hier ein Beispiel zur Umsetzung von Spaltenwerten (Strings) aus
Datarows in eine Treeview-Knotenhierarchie.
Public Class FrmDatatable2Treeview
Dim dt As New DataTable
Dim bs As New BindingSource
Dim dgv As New DataGridView With
{.Parent = Me, .Width = 300, .DataSource = bs}
Dim trv As New TreeView With
{.Parent = Me, .Left = 310, .Width = 300, .Scrollable = True}
Private Sub FrmDatatable2Treeview_Load(sender As Object,
e As EventArgs) Handles MyBase.Load
Me.Size = New Size(630, 300)
'Testdaten
With dt
With .Columns
.Add("Menge", GetType(Integer))
.Add("Material") : .Add("Händler") : .Add("Qualität")
.Add("Status")
End With
With .Rows
.Add(20, "Holz", "Meyer", "Premium", "lagernd")
.Add(40, "Kohlen", "Schulz", "Bruch", "bestellt")
.Add(45, "Kohlen", "schulz", "Bruch", "bestellt")
.Add(12, "Koks", "Schneider", "Bruch", "lagernd")
.Add(10, "Holz", "Meyer", "Medium", "lagernd")
.Add(15, "Kohlen", "Schulz", "Premium", "geliefert")
.Add(20, "Propan", "Meyer", "Premium", "geliefert")
.Add(5, "Propan", "Schulz", "Medium", "bestellt")
.Add(10, "Holz", "Schulz", "Bruch", "lagernd")
.Add(30, "Kohlen", "Müller", "Medium", "")
.Add(20, "Kohlen", "Müller", "Bruch", "")
.Add(200, "Koks", "Müller", "Bruch", "lagernd")
End With
End With
bs.DataSource = dt 'Datenbindung
'Sortieren der Datenspalten: Festlegung der Knotenfolge im Treeview
bs.Sort = "Händler DESC, Material, Qualität"
'Übertragung von Spaltenwerten ins Treeview (Knoten-Hierarchie):
'Händler(2), Material(1), Qualität(3), Menge(0)
DatatableColumns2Treeview(bs, New Integer() {2, 1, 3, 0}, trv)
End Sub
Private Function DatatableColumns2Treeview(ByVal bs As BindingSource, _
ByVal columnindices() As Integer, _
trv As TreeView) As Boolean
If bs Is Nothing Or trv Is Nothing Then Return False
If bs.DataSource Is Nothing Then Return False
If Not TypeOf bs.DataSource Is DataTable Then Return False
'Spaltenindices prüfen
If columnindices Is Nothing OrElse
columnindices.Length < 2 Then Return False
For i As Integer = 0 To columnindices.Length - 1
If columnindices(i) < 0 Or
columnindices(i) > dt.Columns.Count - 1 Then Return False
Next i
trv.Nodes.Clear()
Try
'Zeilen in der Datatable durchlaufen
For r As Integer = 0 To bs.Count - 1
Dim row As DataRow = DirectCast(bs(r), DataRowView).Row
'Knoten-Pfad aus Spaltenwerten zusammensetzen
Dim path As String = ""
For i As Integer = 0 To columnindices.Length - 1
path &= row(columnindices(i)).ToString
If i < columnindices.Length - 1 Then path &= _
trv.PathSeparator
Next i
GetTreeNodeByPath(trv.Nodes, path)
Next r
Return True
Catch
Return False
End Try
End Function
''' <summary>In der Collection wird ein Pfad-Knoten ermittelt/erstellt</summary>
''' <param name="Nodes">Node-Collection</param>
''' <param name="path">zu suchender/zu erstellender Pfad</param>
''' <returns>Treenode</returns>
Private Function GetTreeNodeByPath(ByVal Nodes As TreeNodeCollection, _
path As String) As TreeNode
Dim parts() As String =
path.Split({trv.PathSeparator}, StringSplitOptions.None)
Dim nd As TreeNode, ind As Integer, c As Integer = -1
'Pfad durchlaufen
Do
c += 1
ind = Nodes.IndexOfKey(parts(c))
If ind = -1 Then
'Pfad-Knoten fehlt in Auflistung, wird erstellt
nd = Nodes.Add(parts(c), parts(c))
Else
nd = Nodes(parts(c))
End If
Nodes = nd.Nodes
Loop While c < parts.Length - 1
Return nd
End Function
End Class
Beitrag wurde zuletzt am 01.03.18 um 06:17:57 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 01.03.18 13:36 |
| Hallo ManfredX,
Danke dir für dein Beispiel, funktioniert auch.
mir ging es aber um drei Tabellen, das ich noch nicht verstehe wie das nun gehen könnte.
Dabei darf es eine Überschrift (Root) geben, zum Beispiel Artikelverwaltung.
die Daten werden in Dataset/Datatable geladen (Ja)
die Artikelverwaltung besteht aber aus diesen drei Tabellen
eine Tabelle für die Warengruppe
eine Tabelle für die Artikelgruppe
eine Tabelle für die Artikeldetails
Warengruppe:
ID = automatischer Wert
Warengruppe = String
Artikelgruppe:
ID = automatischer Wert
Artikelgruppe = String
WarengruppeID = Verbindung zur Warengruppe
Artikeldetails:
ID = automatischer Wert
Artikelnummer = String
Artikelbezeichnung = String
Mindestbestand = Zahl (Integer)
Meldeschwelle = Zahl (Interger)
WarengruppeID = Verbindung zur Warengruppe
ArtikelgruppeID = Verbindung zur Artikelgruppe
und nun möchte ich das eben Strukturierter in ein TreeView laden, bearbeiten etc.
heute habe ich auf der kleinen Form 3 DGV' s Warengruppe, Artikelgruppe, Artikeldetails
evtl. wird es so ersichtlich was ich meine? | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 01.03.18 17:42 |
| Hallo!
In Deinem ersten Post wird eine SQL-JOIN-Abfrage verwendet.
Du durchläufst die Do...While-Schleife und füllst statt
dem Treeview zunächst eine Datatable mit Datarows. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 02.03.18 14:05 |
| Hallo Manfred X,
meinst du so in etwa? wie bekomme ich die Abfrage in eine Tabelle
SELECT
Warengruppen.Warengruppe,
Artikelgruppen.Artikelgruppe,
Artikel.Erfassungsdatum,
Artikel.Artikelbezeichnung,
Artikel.Artikelnummer,
Artikel.MAXIMO
FROM Artikelgruppen
RIGHT JOIN (Warengruppen RIGHT JOIN Artikel
ON Warengruppen.ID = Artikel.WarengruppeID)
ON Artikelgruppen.ID = Artikel.ArtikelgruppeID; | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 02.03.18 19:27 |
| Ich weiß nicht, was Du unter "typisierten Tabellen" (s.o.) verstehst.
Ich nehme an, Du nutzt ein typisiertes Dataset.
In einem Dataset kannst Du geladene Tabellen
mit DataRelations verknüpfen (Fremdschlüssel).
Sie können auch im Dataset-Designer eingerichtet werden
Dann stehen Dir in den Tabellenzeilen "Childrows" zur Verfügung,
die Du direkt verwenden kannst, um eine hierarchische Knotenstruktur
daraus zu erstellen (geschachtelte Schleifenstruktur).
Ein einfaches Grundbeispiel (4 Tabellen, 3 Relations),
um die Vorgehensweise als Quellcode zu verdeutlichen:
Public Class frmDataset2Treeview
Dim ds As New DataSet
Dim trv As New TreeView With _
{.Parent = Me, .Dock = DockStyle.Fill}
Dim bs As New BindingSource
Private Sub CreateTableData(ByVal dt As DataTable)
'Hilfsfunktion
Const n As Integer = 20
dt.Columns.Add("ID", GetType(Integer))
dt.Columns.Add("Value", GetType(String))
dt.Columns.Add("Key", GetType(Integer))
dt.PrimaryKey = {dt.Columns(0)}
Dim rndm As New Random(123)
For i As Integer = 0 To n - 1
Dim row As DataRow = dt.NewRow
row(0) = i
row(2) = rndm.Next(0, n) 'Fremdschlüssel
row(1) = dt.TableName & "_Value_" & row(2).ToString
dt.Rows.Add(row)
Next i
End Sub
Private Sub frmDataset2Treeview_Load(sender As Object,
e As EventArgs) Handles MyBase.Load
'Im Dataset: 4 Tabellen mit Daten erzeugen
For i As Integer = 1 To 4
ds.Tables.Add(New DataTable With _
{.TableName = "DT" & i.ToString})
CreateTableData(ds.Tables(i - 1))
Next i
'Tabellen verknüpfen / Datarelations erstellen
'In jeder Tabelle ist ID die Schlüssel-Spalte (0),
'Key die Fremdschlüssel-Spalte (2) und
'Value die im Treeview anzuzeigende Datenspalte (1)
For i As Integer = 0 To ds.Tables.Count - 2
Dim dr As New DataRelation _
(ds.Tables(i).TableName & ds.Tables(i + 1).TableName,
ds.Tables(i).Columns(0), ds.Tables(i + 1).Columns(2))
ds.Relations.Add(dr)
Next i
'Diverse Hilfsvariablen
'Treeview-Knoten gemäß Datarelations erstellen
Dim nd_i, nd_k, nd_l As TreeNode
'aktuelle Datarow (Referenz) in den Schleifen
Dim row_i, row_k, row_l, row_m As DataRow
'Name der Datarelation
Dim rel_i, rel_k, rel_l As String
'Tabellen-Index der im TRV anzuzeigenden Spalte
Dim col_i, col_k, col_l, col_m As Integer
'anzuzeigender Daten-Wert im Treeview
Dim val_i, val_k, val_l As String
For i As Integer = 0 To ds.Tables(0).Rows.Count - 1
row_i = ds.Tables(0).Rows(i)
col_i = 1
val_i = row_i(col_i).ToString
nd_i = GetNode(trv.Nodes, val_i)
rel_i = ds.Relations(0).RelationName
For k As Integer = 0 To _
row_i.GetChildRows(rel_i).Length - 1
row_k = row_i.GetChildRows(rel_i)(k)
col_k = 1
val_k = row_k(col_k).ToString
nd_k = GetNode(nd_i.Nodes, val_k)
rel_k = ds.Relations(1).RelationName
For l As Integer = 0 To _
row_k.GetChildRows(rel_k).Length - 1
row_l = row_k.GetChildRows(rel_k)(l)
col_l = 1
val_l = row_l(col_l).ToString
nd_l = GetNode(nd_k.Nodes, row_l(1).ToString)
rel_l = ds.Relations(2).RelationName
For m As Integer = 0 To _
row_l.GetChildRows(rel_l).Length - 1
row_m = row_l.GetChildRows(rel_l)(m)
col_m = 1
val_l = row_m(col_m).ToString
GetNode(nd_l.Nodes, val_l)
Next m
Next l
Next k
Next i
End Sub
Private Function GetNode(nodes As TreeNodeCollection, Key As String,
Optional ByVal text As String = "") As TreeNode
Dim ind As Integer = nodes.IndexOfKey(Key)
If ind >= 0 Then Return nodes(ind)
If String.IsNullOrWhiteSpace(text) Then text = Key
Return nodes.Add(Key, text)
End Function
End Class
Beitrag wurde zuletzt am 02.03.18 um 19:45:47 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 03.03.18 19:45 |
| Hallo Manfred X,
Danke! habe nun mal manuell Relationen gesetzt und diesen Code dazu geschrieben:
das funktioniert auch.
nun sollen die Details "Artikel noch an eine DGV gebunden werden. Wenn ich also auf den Artigruppen Name gehe sollen die Artikeldetails in der DGV angezeigt werden. ?
was meinst du zu meiner Variante, bei deiner bin ich an den Relationen gescheitert.
Private Sub initTreeView()
TVArtikelverwaltung.Nodes.Clear()
Try
Dim parentrow As DataRow
Dim ParentTable As DataTable
Dim i As Integer = 1
Dim j As Integer = 101
Dim k As Integer = 1001
ParentTable = LagerDB.Tables("Warengruppen")
TVArtikelverwaltung.Nodes.Add("Artikelstamm")
TVArtikelverwaltung.Nodes(0).Tag = "0"
For Each parentrow In ParentTable.Rows
Dim parentnode As TreeNode
parentnode = New TreeNode(CStr(parentrow.Item(1))) ' Hier wird
' dem Objekt die erste Zeile der zweiten Spalte übergeben
TVArtikelverwaltung.Nodes(0).Nodes.Add(parentnode) ' wird am
' ersten Ast ein Zweig hinzugefügt welches unseren Anzeigetext
' und den Tag enthält
parentnode.Tag = CStr(i)
i += 1
''''populate child'''''
'''''''''''''''''''''''
Dim childrow As DataRow
Dim childnode As TreeNode
childnode = New TreeNode()
For Each childrow In parentrow.GetChildRows( _
"Warengruppen_Artikelgruppen")
childnode = parentnode.Nodes.Add(childrow(1).ToString)
childnode.Tag = CStr(j)
''''populate child2''''
''''''''''''''''''''''''''
Dim childrow2 As DataRow
Dim childnode2 As TreeNode
childnode2 = New TreeNode()
j += 1
For Each childrow2 In childrow.GetChildRows( _
"Artikelgruppen_Artikel")
childnode2 = childnode.Nodes.Add(childrow2(3).ToString)
childnode2.Tag = CStr(k)
k += 1
Next childrow2
''''''''''''''''''''''''
Next childrow
'''''''''''''''
Next parentrow
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub | |
Re: TreeView befüllen in VB2010 | | | Autor: Franki | Datum: 04.03.18 05:57 |
| Hallo,
warum eigentlich der ganze Aufwand? Du hast eine funktioniernde SQL Abfrage, bist in der Lage diese bzw. deren Ergebnis anzeigen zu können.
Ob es jetzt X, Y, Z oder .NET gibt im Vergleich zu früher spielt keine Rolle, Datenbank ist Datenbank, und SQL bleibt SQL.
Warum nimmst du nicht einfach die Basis und arbeitest wie gewohnt? Wie die Anzeige aus zu sehen hat bestimmst du, in welchem Steuerelement sie unter welchen Umständen sichtbar sein soll bestimmst auch nur du.
SQL it mächtig, versuche nicht die Funktionalität auszulagern. Das mag funktionieren bei relativ wenigen Datensätzen, abe im Endeffekt ist das verschwendete Zeit wenn dein Code auch mal für viele Datensätze tauglich sein soll.
Gruß
Frank | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 04.03.18 08:33 |
| Was genau Du erreichen möchtest, kann ich nicht erkennen.
Hier ein Beispiel mit drei verknüpften Tabellen,
wobei die Spalten der ersten beiden Tabellen in eine
Knotenhierarchie (Treeview) eingetragen werden und das Array
der jeweils zugehörigen Childrows der dritten Tabelle in die
TAG-Eigenschaft des Knotens der Spalte der zweiten Tabelle
eingetragen wird.
Beim Click auf einen Knoten der zweiten Hierarchie-Ebene
wird das Datagridview mit den, per Datarelation ermittelten,
Spalten der dritten Tabelle gefüllt (falls Sätze vorhanden sind).
Public Class FrmDataRelations2Controls
Dim ds As New DataSet
Dim WithEvents trv As New TreeView With
{.Parent = Me, .Width = 300}
Dim dgv As New DataGridView With
{.Parent = Me, .Left = 310, .AllowUserToAddRows = False}
Dim dtx As New DataTable 'für Grid-Anzeige der letzten Tabelle
Private Sub CreateTableData(ByVal dt As DataTable,
Optional ByVal n As Integer = 100)
dt.Columns.Add("ID", GetType(Integer))
dt.Columns.Add("Value", GetType(String))
dt.Columns.Add("Key", GetType(Integer))
dt.PrimaryKey = {dt.Columns(0)}
Dim rndm As New Random(123)
For i As Integer = 0 To n - 1
Dim row As DataRow = dt.NewRow
row(0) = i
row(2) = rndm.Next(0, n) 'Fremdschlüssel
row(1) = dt.TableName & "_Value_" & _
i.ToString & "/" & row(2).ToString
dt.Rows.Add(row)
Next i
End Sub
Private Sub FrmDataRelations2Controls_Load(sender As Object,
e As EventArgs) Handles MyBase.Load
Me.Size = New Size(620, 300)
Me.FormBorderStyle = FormBorderStyle.Fixed3D
'Im Dataset: 3 Tabellen mit Daten erzeugen
For i As Integer = 1 To 3
ds.Tables.Add(New DataTable With {.TableName = "DT" & i.ToString})
CreateTableData(ds.Tables(i - 1))
Next i
'Tabellen verknüpfen / Datarelations erstellen
For i As Integer = 0 To ds.Tables.Count - 2
Dim dr As New DataRelation _
(ds.Tables(i).TableName & ds.Tables(i + 1).TableName,
ds.Tables(i).Columns(0), ds.Tables(i + 1).Columns(2))
ds.Relations.Add(dr)
Next i
'Treeview-Knoten gemäß Datarelations erstellen
Dim nd_i, nd_k As TreeNode
Dim row_i, row_k As DataRow 'aktuelle Datarow in Schleife
Dim rel_i, rel_k As String 'Name der Datarelation
Dim col_i, col_k As Integer 'Index der anzuzeigenden Spalte im Treeview
Dim val_i, val_k As String 'anzuzeigender Daten-Wert im Treeview
dtx = ds.Tables(2).Clone
dgv.DataSource = dtx
For i As Integer = 0 To ds.Tables(0).Rows.Count - 1
row_i = ds.Tables(0).Rows(i)
col_i = 1
val_i = row_i(col_i).ToString
nd_i = GetNode(trv.Nodes, val_i)
rel_i = ds.Relations(0).RelationName
For k As Integer = 0 To row_i.GetChildRows(rel_i).Length - 1
row_k = row_i.GetChildRows(rel_i)(k)
col_k = 1
val_k = row_k(col_k).ToString
nd_k = GetNode(nd_i.Nodes, val_k)
rel_k = ds.Relations(1).RelationName
'Speichern einer Referenz des Childrows-Array im Knoten
nd_k.Tag = row_k.GetChildRows(rel_k)
Next k
Next i
End Sub
Private Sub Trv_NodeMouseClick(sender As Object,
e As TreeNodeMouseClickEventArgs) Handles trv.NodeMouseClick
dtx.Clear()
'Level = 1: zweite Knotenebene
If e.Node.Level = 1 Then
Dim rows As DataRow() = DirectCast(e.Node.Tag, DataRow())
For i As Integer = 0 To rows.Length - 1
dtx.Rows.Add(rows(i).ItemArray)
Next i
End If
End Sub
Private Function GetNode(nodes As TreeNodeCollection, Key As String,
Optional ByVal text As String = "") As TreeNode
Dim ind As Integer = nodes.IndexOfKey(Key)
If ind >= 0 Then Return nodes(ind)
If String.IsNullOrWhiteSpace(text) Then text = Key
Return nodes.Add(Key, text)
End Function
End Class
Beitrag wurde zuletzt am 04.03.18 um 08:33:57 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 04.03.18 13:16 |
| Hallo manfred X,
Danke für deine Mühe mir das TV näher zu bringen.
Was genau Du erreichen möchtest, kann ich nicht erkennen.
Na Ja heute nutze ich 3 Datagridviews um über die Warengruppen, Artikelgruppen die Artikeldetails anzuzeigen bzw. anzulegen.
ich möchte da eigentlich über eine Strukturierte TV machen da das weniger Platz auf der Form benötigt.
deine Beispiele sind auch Hilfreich doch ich kriege es nicht auf meine Tabellen umgesetzt.
bestimmt weil ich das noch nicht ganz verstanden habe. | |
Re: TreeView befüllen in VB2010 | | | Autor: Franki | Datum: 05.03.18 05:05 |
| Hallo,
zuerst sollte die DB Struktur stimmen, bzw. das her geben was später ausgewertet werden soll.
Es bringt rein gar nichts eine unzulängliche DB später in der eigenen Anwendung aufbereiten zu wollen. Selbst wenn das klappt ist es von der Performance her immer schlechter als ein gutes DB Design.
Schau dir doch mal Tutorials von vor ca. 10 Jahren an, damals war es unbedingt notwendig ein vernünfitiges DB Design zu haben, heute kann man das überspielen mit modernen Steuerelementen, die Filterung von Datensätzen auf den Client verlagern usw. usw. Aber das ist meiner Meinung nach der falsche Weg.
Du hast eine überschaubare Hierarchie mit drei Ebenen soweit ich das verstehe, da sollte es eine Kleinigkeit sein die DB entsprechend anpassen zu können.
Gruß
Frank | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 08.03.18 14:45 |
| Hallo Manfred X
du Sorry, den Teil mit dem clonen habe ich nicht ganz verstanden
wenn ich das mache habe ich alle Spalten in der DGV die ich aber garnicht alle benötige aus der "Tabelle" Artikel.
ansonsten scheint es zu funktionieren.
'Treeview-Knoten gemäß Datarelations erstellen
Dim nd_i, nd_k As TreeNode
Dim row_i, row_k As DataRow 'aktuelle Datarow in Schleife
Dim rel_i, rel_k As String 'Name der Datarelation
Dim col_i, col_k As Integer 'Index der anzuzeigenden Spalte im Treeview
Dim val_i, val_k As String 'anzuzeigender Daten-Wert im Treeview
dtx = ds.Tables(2).Clone
dgv.DataSource = dtx denn die ds.Tables(2) ist ja sogesehen meine Artikel Tabelle? | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 08.03.18 19:12 |
| Hallo!
Solche "Kniffe" benutze ich, um einen Überlauf der
zulässigen Posting-Länge zu vermeiden.
Wenn Du nicht alle Spalten der Quelltafel benötigst, mußt Du
in die erforderlichen Spalten einzeln erstellen und einrichten.
Beitrag wurde zuletzt am 08.03.18 um 19:14:14 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 08.03.18 19:26 |
| Wenn Du nicht alle Spalten der Quelltafel benötigst, mußt Du
in die erforderlichen Spalten einzeln erstellen und einrichten.
Bitte das macht mich derzeit Wahnsinnig, hilf mir auf die Sprünge
so bekomme ich alle, aus dem Clone
'Treeview-Knoten gemäß Datarelations erstellen
Dim nd_i, nd_k As TreeNode
Dim row_i, row_k As DataRow 'aktuelle Datarow in Schleife
Dim rel_i, rel_k As String 'Name der Datarelation
Dim col_i, col_k As Integer 'Index der anzuzeigenden Spalte im Treeview
Dim val_i, val_k As String 'anzuzeigender Daten-Wert im Treeview
CreateTableData(dtx)
dtx = LagerDB.Tables("Artikel").Clone
For i As Integer = 0 To LagerDB.Tables("Warengruppen").Rows.Count - 1
row_i = LagerDB.Tables("Warengruppen").Rows(i)
col_i = 1
val_i = row_i(col_i).ToString
nd_i = GetNode(Trv.Nodes, val_i)
rel_i = LagerDB.Relations( _
"Warengruppen_Artikelgruppen").RelationName
For k As Integer = 0 To row_i.GetChildRows(rel_i).Length - 1
row_k = row_i.GetChildRows(rel_i)(k)
col_k = 1
val_k = row_k(col_k).ToString
nd_k = GetNode(nd_i.Nodes, val_k)
rel_k = LagerDB.Relations("Artikelgruppen_Artikel").RelationName
'Speichern einer Referenz des Childrows-Array im Knoten
nd_k.Tag = row_k.GetChildRows(rel_k)
Next k
Next i
'Ascending, Descending
With ArtikelDGV
.DataSource = dtx
'ID
.Columns(0).Width = 60
.Columns(0).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleCenter
.Columns(0).SortMode = DataGridViewColumnSortMode.Automatic
'Daten
.Columns(1).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
.Columns(1).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleCenter
.Sort(ArtikelDGV.Columns(1), _
System.ComponentModel.ListSortDirection.Descending)
'Bauteil
.Columns(2).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
.Columns(2).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleCenter
.Columns(2).SortMode = DataGridViewColumnSortMode.Automatic
End With ich brauche aber nur diese:
Erfassungsdatum, Artikelnummer, Artikelbezeichnung, Maximo, vorhanden (ist die einzige Boolean Spalte) die anderen sind String | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 09.03.18 07:07 |
| 'dtx = LagerDB.Tables("Artikel").Clone
'(überträgt/erstellt das gesamte Tabellen-Schema)
'statt dessen: explizit erstelltes Spaltenschema
'(nur benötigte Spalten)
dtx.TableName = "WhatEver"
With dtx.columns
.Add("ID", Gettype(Integer)) 'falls eindeutige Schlüssel benötigt werden
.Add("Erfassungsdatum", Gettype(Date))
.Add("Artikelnummer", Gettype(Integer)) 'eventuell Gettype(String)
'usw ....
End With
dtx.Columns("ID").Unique = True 'Schlüssel muß eindeutig sein
dtx.PrimaryKey = _
New DataColumn() {dtx.Columns("ID")} 'Schlüssel ggf. einrichten
Beitrag wurde zuletzt am 09.03.18 um 07:10:00 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 09.03.18 08:38 |
| Ja du hast Recht, er funktionierte in Accsess aber nicht in meiner WindowsApplication VB2010
verwende auch keine SQL DB
wenn du mir sagst wie er abzuändern ist gehe ich gerne mit. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 09.03.18 08:50 |
| Danke, doch nun passt doch das itemArray nicht mehr
hier knallt es Der Eingabearray ist länger als die Anzahl der Spalten in dieser Tabelle.
Private Sub Trv_NodeMouseClick(sender As Object,
e As TreeNodeMouseClickEventArgs) Handles Trv.NodeMouseClick
dtx.Clear()
'Level = 1: zweite Knotenebene
If e.Node.Level = 1 Then
Dim rows As DataRow() = DirectCast(e.Node.Tag, DataRow())
For i As Integer = 0 To rows.Length - 1 "rows.Lenggth ist 6
dtx.Rows.Add(rows(i).ItemArray) "ItemArray Length ist 14
Next i
End If
End Sub | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 09.03.18 11:18 |
| If e.Node.Level = 2 Then
'Hier kommen Datensätze mit vollständiger Tabellenstruktur an
Dim rows As DataRow() = DirectCast(e.Node.Tag, DataRow())
For i As Integer = 0 To rows.Length - 1
'Hier wir eine neue Zeile mit reduz. Spalten-Schema erstellt
Dim newrow As DataRow = dtx.NewRow
'Hier ist die Spaltenzuordnung korrekt vorzunehmen
'Annahme: die Spaltenbezeichner sind übernommen worden"
newrow("ID") = i 'oder Schlüsselspalteneintrag aus rows(i)
newrow("Artikelnummer") = rows(i)("Artikelnummer")
newrow("Erfassungsdatum") = rows(i)("Erfassungsdatum")
'usw.
dtx.Rows.Add(newrow) 'aufbereitete Zeile in dtx eintragen
Next i | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 09.03.18 15:08 |
| Oh Manfred, ganz großes Kino
melde mich noch mal da muss ich mal das eine oder andere nachfragen möchte es auch verstehen.
derzeit läuft es wie gewünscht Danke dir
jetzt will man ja evtl. neue Artikel hinzufügen, wie aktualisiere ich dann das TV?
usw.
bis bald | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 09.03.18 15:57 |
| Das Windows.Forms.Treeview-Control unterstützt keine Datenbindung
und ist deshalb für solche Zwecke kaum geeignet.
Der einfachste Weg wäre wohl, für das Editieren in ein Grid-Formular zu
wechseln und nach dem Editieren der Daten das Treeview komplett neu
aufzubauen.
Wenn es nur um das Hinzufügen von Datenzeilen (=Knoten) geht, kann man
die obige Routine zum Füllen des Treeview erweitern, indem jeweils in den
Schleifen geprüft wird, ob der Daten-Knoten bereits im Treeview vorhanden
ist oder ob er ergänzt werden muß. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 09.03.18 19:01 |
| ja, so könnte man es machen. Danke dir
so sieht es mittlerweile bei mir aus, bis hierher habe ich es einigerma'en Verstanden doch habe ich noch 1-2 Fragen im Code Kommentiert
könnte man auch die Anzahl der Artikel ermitteln und dem Node zuweisen?
+ Elektrik
-- Anschlussleitungen (5)
-- Initiatoren (0)
+ Mechanik
-- Lastaufnahmemittel (10)
usw. ist nicht der Bestand sondern die erfassten Artikel in der Ebene
Dim dtx As New DataTable
Private Sub init_TVArtikelverwaltung()
Dim Rootnode As TreeNode = Nothing
Const Database As String = "Artikelstamm"
'Treeview-Knoten gemäß Datarelations erstellen
Dim nd_i, nd_k As TreeNode
Dim row_i, row_k As DataRow 'aktuelle Datarow in Schleife
Dim rel_i, rel_k As String 'Name der Datarelation
Dim col_i, col_k As Integer 'Index der anzuzeigenden Spalte im Treeview
Dim val_i, val_k As String 'anzuzeigender Daten-Wert im Treeview
'(nur benötigte Spalten)
dtx.TableName = "Artikelstamm"
'habe noch nicht verstanden wie die dtx an die Artikelrow kommt? für
' das DGV
With dtx.Columns
.Add("ID", GetType(Integer)) 'falls eindeutige Schlüssel
' benötigt werden
.Add("Erfassungsdatum", GetType(Date))
.Add("Artikelnummer", GetType(String)) 'eventuell Gettype(String)
.Add("Artikelbezeichnung", GetType(String))
.Add("Mindestbestand", GetType(Integer))
.Add("Meldeschwelle", GetType(Integer))
.Add("Maximo", GetType(String))
.Add("erledigt", GetType(Boolean))
End With
'Frage: benötige ich diese Zeile noch?
dtx.PrimaryKey = _
New DataColumn() {dtx.Columns("ID")} 'Schlüssel ggf. einrichten
'Frage: Rootknoten TV-Überschrift? ist das so OK
Rootnode = Trv.Nodes.Add(key:="Root", text:=Database, imageIndex:=0, _
selectedImageIndex:=1)
For i As Integer = 0 To LagerDB.Tables("Warengruppen").Rows.Count - 1
row_i = LagerDB.Tables("Warengruppen").Rows(i)
col_i = 1
val_i = row_i(col_i).ToString
nd_i = GetNode(Trv.Nodes, val_i)
rel_i = LagerDB.Relations( _
"Warengruppen_Artikelgruppen").RelationName
For k As Integer = 0 To row_i.GetChildRows(rel_i).Length - 1
row_k = row_i.GetChildRows(rel_i)(k)
col_k = 1
val_k = row_k(col_k).ToString
nd_k = GetNode(nd_i.Nodes, val_k)
rel_k = LagerDB.Relations("Artikelgruppen_Artikel").RelationName
'Speichern einer Referenz des Childrows-Array im Knoten
nd_k.Tag = row_k.GetChildRows(rel_k)
Next k
Next i
'Ascending, Descending
With ArtikelDGV
.DataSource = dtx
'ID
.Columns(0).Width = 50
.Columns(0).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleCenter
.Columns(0).SortMode = DataGridViewColumnSortMode.Automatic
'Datum
.Columns(1).Width = 110
.Columns(1).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleCenter
.Sort(ArtikelDGV.Columns(1), _
System.ComponentModel.ListSortDirection.Ascending)
'Artikelnummer
.Columns(2).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
.Columns(2).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleLeft
.Columns(2).SortMode = DataGridViewColumnSortMode.Automatic
'Artikelbezeichnung
.Columns(3).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
.Columns(3).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleLeft
.Columns(3).SortMode = DataGridViewColumnSortMode.Automatic
usw. | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 09.03.18 22:27 |
| 1.) Durch das Einfügen eines Stammknotens verschiebt sich
die Hierarchie der übrigen Knoten, weil sie ihm untergeordnet
sind.
Eine zu ändernde Codezeile:
nd_i = GetNode(RootNode.Nodes, val_i)
Dementsprechend muß im trv.NodeMouseClick-Eventhandler der
Level in der Bedingung um eins hochgesetzt werden.
2.) Jeder Knoten besitzt einen Rucksack (= Tag-Eigenschaft, Typ: Object).
Dort können beliebige Referenzen oder Werte abgelegt werden.
Im Beispiel wird über die GetChildRows-Eigenschaft der Datarow
ein Array mit den Referenzen auf die per Relation verknüpften
Datarows der untergeordneten Tabelle abgefragt.
Dieses Array kommt beim Erstellen der Knoten der zweiten Ebene (Level)
in dessen Rucksack:
nd_k.Tag = row_k.GetChildRows(rel_k)
Im NodeMouseClick-Eventhandler wird der Level des angeclickten Knotens
geprüft und ggf. das Array mit den Zeilenreferenzen aus dem Rucksack
geholt - per Directcast:
Dim rows As DataRow() = DirectCast(e.Node.Tag, DataRow())
Danach können die Daten dieser Zeilen per Schleife in eine Tabelle
eingetragen werden.
(Es gibt elegantere Lösungen, aber im Forum müssen Beispiele kurz sein).
3.) Ob Du in der Tabelle dtx einen Primärschlüssel benötigst, hängt davon
ab, ob diese Tabelle noch weiterverarbeitet werden soll
(z.B. Find, Relation, Save/Update).
4.) Ich weiß nicht genau, welche Zahl in den Knoten-Text eingetragen werden
soll.
Falls es sich um die Anzahl der untergeordneten Knoten handelt, kann diese
der GetChildrows(rel_?).Length-Eigenschaft entnommen werden.
Ansonsten muß eventuell eine Schleife über die Zeilen im Array laufen und
der erforderliche Wert als eine Spaltensumme berechnet werden.
Beitrag wurde zuletzt am 09.03.18 um 22:30:08 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 10.03.18 09:42 |
| Guten Morgen Manfred X,
äh das TV ist doch ziehmlich komplex und kompliziert, auch weil es verschiedene Möglichkeiten gibt
und Schade ist das es nicht gebunden werden kann.
da muss ich noch sehr viel experementieren.
das mit der Anzahl: habe ich so gemeint evtl. erkennt man es auf dem Bild.
(Level 1)
die Artikelgruppe: Greifer / Dreheinheiten (10) Artikel
die Artikelgruppe: Antriebsrollen (11) Artikel
die Artikelgruppe: Hebel ( 0) Artikel
GetChildrows(rel_?).Length also nicht die Anzahl Unterknoten
die sieht man ja erst in der DGV, aber die Anzahl wäre schon Sinnvoll im TV zu sehen.
und dann habe ich da noch ein Problem, beim erneuten aufrufen der Sub gibt es ein Problem:
Fehlermeldung: Eine Spalte names 'ID' gehört bereits zu dieser DataTable ich entferne die dtx vorher aber VB meldet weiter. Also einmal kann ich auf die Daten zugreifen und dann nicht mehr. | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 10.03.18 10:49 |
| Wenn die Treeview mehrfach gefüllt werden soll,
wäre die dtx-Tabelle und die erforderlichen Spalten
im Form_Load-Eventhandler einmal anzulegen.
Vor Wiederverwendung dieser Tafel sind jeweils ggf.
vorhandenen die Zeilen zu entfernen.
Die Spalten bleiben aber unverändert.
Auf Deinen Mini-Bildchen kann ich nie etwas erkennen!
Lege die Bilder in Originalgröße auf einen Bilder-Hoster
und poste hier im Forum den Link, den der Hoster (zur Einbettung
in Foren) zur Verfügung stellt.
Big Picture | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 10.03.18 10:58 |
| OK Manfred,
habe das mit dem Bild soweit verstanden, hier der Link
ich werde die Tabelle im Load Event erstellen und schauen ob es läuft.
https://picload.org/view/daopwgir/10-03-_2018_09-04-15.png.html
Danke dir wie verrückt
PS ich möchte auch gerne nach Anschlussleitung, oder XXX suchen im TV
das gefundene soll selektiert werden und die DGV sollte die Daten gleich anzeigen
Beitrag wurde zuletzt am 10.03.18 um 11:25:34 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 10.03.18 11:28 |
| ????
So (in einer Knotenbildungsschleife)?
row_i = ds.Tables(0).Rows(i)
col_i = 1
val_i = row_i(col_i).ToString 'Schlüssel des Knotens
nd_i = GetNode(rootnode.Nodes, val_i) 'Referenz zum Knoten
rel_i = ds.Relations(0).RelationName 'Verknüpf. der Tabellen
'zusätzlich: Text des Knotens erweitern
nd_i.Text = val_i & _
" (" & row_i.GetChildRows(rel_i).Length.ToString & ")" | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 10.03.18 12:44 |
| Manfred X,
Danke für deine Geduld, aber ich möchte nicht die Artikelgruppe zählen sondern die Artikel je Artikelgruppe
aber evtl. habe ich es ja falsch gemacht, hier wo ich es im Code hinzugefügt habe.
For i As Integer = 0 To LagerDB.Tables("Warengruppen").Rows.Count - 1
row_i = LagerDB.Tables("Warengruppen").Rows(i)
col_i = 1
val_i = row_i(col_i).ToString
nd_i = GetNode(Trv.Nodes, val_i)
rel_i = LagerDB.Relations( _
"Warengruppen_Artikelgruppen").RelationName
For k As Integer = 0 To row_i.GetChildRows(rel_i).Length - 1
row_k = row_i.GetChildRows(rel_i)(k)
col_k = 1
val_k = row_k(col_k).ToString
nd_k = GetNode(nd_i.Nodes, val_k)
rel_k = LagerDB.Relations("Artikelgruppen_Artikel").RelationName
'Speichern einer Referenz des Childrows-Array im Knoten
nd_k.Tag = row_k.GetChildRows(rel_k)
Next k
'zusätzlich: Text des Knotens erweitern
nd_i.Text = val_i & _
" (" & row_i.GetChildRows(rel_i).Length.ToString _
& ")"
Next i PS die Tabelle dtx erstelle ich nun im Load Ereignis, nun funktioniert das Neu abfrufen auch.
https://picload.org/view/daowgioi/10-03-_2018_12-31-37.png.html | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 10.03.18 12:57 |
| Nun ja ...
Du könntest die Zeile nd_i.text = ....
in die k-Schleife verschieben und dann in dieser Zeile
die Variablen entsprechend ersetzen .....
nd_i -> nd_k
val_i -> val_k
row_i -> row_k
rel_i -> rel_k | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 10.03.18 13:29 |
| Mann Manfred du hast das im Griff
Super und Danke, Damke
https://picload.org/view/daowrlii/10-03-_2018_13-16-51.png.html
sieht doch strukturierter aus als mit 3 DGVs und ich sehe nun auch wo ich überhaupt Artikel habe
das konnte ich mit den 3 DGVs nicht da musste ich mich durchklicken.
nun als letztes noch eine Textbox mit der ich das TV nach einer Artikelgruppe durchsuchen könnte
Beispiel: ich möchte nach Zylinder suchen, nun soll das TV.Nodes selektiert werden und ich möchte auch das die Daten dazu im DGV = angezeigt werden wenn Node gefunden wurde, damit man das TV nicht nach dem Suchen erneut anklicken muss sondern = ein Ergebnis der Suche hat.
geht das? | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 10.03.18 14:20 |
| Knoten besitzen eine Find-Methode für die Suche nach Unterknoten.
Sei "txtSearch" eine Textbox für die Suche nach Knoten in einer
bestimmten Hierarchieebene und "trv" das Treeview .....
Private Sub txtSearch_KeyDown(sender As Object, _
e As KeyEventArgs) Handles txtSearch.KeyDown
If e.KeyCode = Keys.Return Then
Dim tn() As TreeNode = trv.Nodes.Find(txtSearch.Text, True)
If tn Is Nothing OrElse tn.Length = 0 Then Exit Sub
Dim tnx As TreeNode = Nothing
'erster gefundener Knoten im relevanten Level
For i As Integer = 0 To tn.Length - 1
'Such-Level korrekt angeben - 2 ??
If tn(i).Level = 2 Then
tnx = tn(i) : Exit For
End If
Next i
If tnx Is Nothing Then Exit Sub
'Ereignishandler rufen, um die Tabelle zu füllen
Trv_NodeMouseClick _
(Me, New TreeNodeMouseClickEventArgs(tnx, Nothing, 0, 0, 0))
trv.SelectedNode = tnx
End If
End sub | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 10.03.18 16:14 |
| perfekt bei mir war es Level 1
tausend Dank
schönes Wochenende | |
Re: TreeView befüllen in VB2010 | | | Autor: Franki | Datum: 11.03.18 01:58 |
| Hallo,
ich stehe nach wie vor auf dem Standpunkt, dass DB Zugriffe Vorrang haben.
Ok, in Access hat das funktioniert bei dir, jetzt verwendest du keine SQL DB (was ist das?) mehr.
Aber jede Datenbasis hat eine Abfragemöglichkeit, wenn SQL nicht geht (würde mich sehr wundern), dann gibt es ja immer noch die Möglichkeit irgendwelche Daten sei es *.txt, *.csv, *,Rauchzeichen, *.irgendwas in eine DB Struktur zu bringen, sei es nur temporär.
Und die kann man dann per SQL ansprechen, d.h. Abfragen, Editieren, Datensätze hinzufügen oder löschen. Und dann hast du das volle Spektrum von SQL zur Verfügung und brauchst das nicht in Steuerelemente auszulagern die dafür eigentlich gar nicht gedacht sind.
Was meinst du mir "er" funktionierte in Access, auf was für eine DB hast du unter Access (welche Version) denn zugegriffen? Und die .NET Versionen können alle noch auf Access DBs zugreifen. Anscheinend hast du das Access intern damls geregelt per VBA vermute ich mal.
Aber gut, du hast ja von ManfredX in den ganzen Threads ja schon die Antwort bekommen, dein Problem scheint gelöst. Aber trotzdem halte ich das für den falschen Weg, die Umstände kenne ich nicht, deswegen nur eine Vermutung.
Aber Hauptsache es funktioniert bei dir.
Gruß
Frank | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 11.03.18 10:41 |
| Hallo!
Ich denke, es liegen einige Mißverständnisse vor.
Die Abfrage und das Update der Daten erfolgt über SQL,
aber die Tabellen werden jetzt "in-memory" verlagert und
die Tabellen-Verknüpfungen dort über Datarelations realisiert
(Dataset).
Welche Zusammenstellung von Daten zu Paketen für die Übertragung
in den Haupspeicher sinnvoll ist, erfordert im Einzelfall
komplexe Überlegungen und Annahmen (relevant bei Multi-User-DBs).
Man kann eigentlich nicht von einem "Vorrang" von DB-Zugriffen
oder von SQL sprechen.
Gewöhnlich verwendet die Datenverarbeitung eine Kombination von
eingebetteten DB-Routinen, SQL-Transaktionen und in-memory-
Operationen (z.B. LINQ).
Das "klassische" Windows.Forms.Treeview ist nicht geeignet,
um mit einem Dataset zu kommunizieren, könnte aber funktionell
erweitert werden.
Wie gezeigt, läßt sich eine Hierarchie von Tabellenspalten
mit vertretbarem Aufwand darstellen. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 11.03.18 11:37 |
| Hallo Manfred X,
Danke für dein Kommentar.
in Sache TreeView noch eine Bitte
wie kann ich mit vertretbarem Aufwand in die Tabelle dtx speichern ?
habe nun einige TextBoxen über Binding hinzugefügt
nun habe ich eine "MAXIMO" Nummer eingetragen und speichere so ab:
die Änderung sehe ich in der DGV über DGV.Refresh auch da es ja eine Binding (Bindingsource)gibt.
Problem: es wird nicht wirklich gespeichert in die Tabelle
Me.Validate()
BindingSource.EndEdit()
dict_BS_Pos.Clear()
dict_BS_Pos.Add(BindingSource, BindingSource.Position)
dict_BS_Pos.Add(BS_SD_Dokumente, BS_SD_Dokumente.Position)
mod_Saver.SaveDataset(Me.LagerDB, dict_BS_Pos, _
ArtikelTableAdapter.Adapter, DokumenteTableAdapter.Adapter) Private Sub BindingControls()
'Datenbindungen an Controls
' ---------------------------------------------------------------------
' ----------------------------------
DSIDTextBox.DataBindings.Add(New Binding("Text", BindingSource, "ID", _
False, DataSourceUpdateMode.OnPropertyChanged))
ArtikelnummerTextBox.DataBindings.Add(New Binding("Text", _
BindingSource, "Artikelnummer", False, _
DataSourceUpdateMode.OnPropertyChanged))
ArtikelbezeichnungTextBox.DataBindings.Add(New Binding("Text", _
BindingSource, "Artikelbezeichnung", False, _
DataSourceUpdateMode.OnPropertyChanged))
MAXIMOTextBox.DataBindings.Add(New Binding("Text", BindingSource, _
"MAXIMO", False, DataSourceUpdateMode.OnPropertyChanged))
chb_Maximo.DataBindings.Add(New Binding("CheckState", BindingSource, _
"erledigt", True, DataSourceUpdateMode.OnPropertyChanged))
'Datenbindungen an Controls
' ---------------------------------------------------------------------
' ----------------------------------
End Sub | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 11.03.18 12:49 |
| Nur für Tabellen im Dataset, die per Datenadapter gefüllt worden sind,
kann ein DB-Update gemacht werden.
Die Tabelle dtx ist eine temporäre Tabelle ohne Bezug zur Datenbank.
Um die DB-Artikel-Tabelle in Zusammenhang mit der Treeview-Ansicht zu
verwenden, ist statt dessen eine Nutzung von Bindingsourcen
unter Verwendung der Datarelations erforderlich.
Beispiel:
http://www.vbarchiv.net/forum/id22_i94845t94842_kaskadierte-datagridviews-mit-datarelations.html | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 11.03.18 17:48 |
| so ganz Manfred X, habe ich es noch nicht ganz verstanden.
Sorry, aber ich brauch da immer etwas länger, und wie dann speichern?
bekomme Fehlermeldung: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
OK, Objektverweis auf dtx fehlte, aber speichern lässt sich das so auch noch nicht
evtl. hilft uns der Ausschnitt vom DB-Modell
https://picload.org/view/dalgwprr/11-03-_2018_18-00-57.png.html
dtx.TableName = "Artikelstamm"
'habe noch nicht verstanden wie die dtx an die Artikelrow kommt? für
' das DGV
With dtx.Columns
.Add("ID", GetType(Integer)) 'falls eindeutige Schlüssel
' benötigt werden
.Add("Erfassungsdatum", GetType(Date))
.Add("Artikelnummer", GetType(String)) 'eventuell Gettype(String)
.Add("Artikelbezeichnung", GetType(String))
.Add("Mindestbestand", GetType(Integer))
.Add("Meldeschwelle", GetType(Integer))
.Add("Maximo", GetType(String))
.Add("erledigt", GetType(Boolean))
End With
'benötige ich diese Zeile noch?
dtx.PrimaryKey = _
New DataColumn() {dtx.Columns("ID")} 'Schlüssel ggf. einrichten
LagerDB.BeginInit()
LagerDB.Tables.Add(dtx)
Dim drArtikel As New DataRelation("dtx", "Artikelstamm", "Artikel", New _
String() {"ID"}, New String() {"ArtikelgruppeID"}, False)
LagerDB.Relations.AddRange(New DataRelation() {drArtikel})
LagerDB.EndInit()
Beitrag wurde zuletzt am 11.03.18 um 18:06:49 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 12.03.18 06:21 |
| Also noch einmal ....
Das Treeview-Control kennt keine Datenbindung.
Deshalb ist in diesem Formular keine Bindung verwendet worden.
Alle Werte werden aus dem Dataset gelesen und in die beiden
Controls (Treeview, Datatable) eingetragen.
"dtx" ist eine temporäre Tabelle, deren Werte bei jedem Click auf
einen Treeview-Knoten gelöscht werden.
Falls Zellinhalte editiert werden, können diese Daten in das Dataset
zurückgeschrieben werden und werden beim nächsten Datenbank-Update
gesichert.
Zu diesem Zweck benötigt man zwei formular-global definierte Hilfsvariable:
Dim TempTableRows As DataRow()
Dim TempTableModified As Boolean Der Eventhandler für den NodeMouseClick ist entsprechen zu erweitern ...
'Speichern der zuvor editierten Daten
If TempTableModified Then SaveTempTableRows()
TempTableRows = Nothing
dtx.Clear()
If e.Node.Level = ???? Then
'Hier kommen Datensätze mit vollständiger Tabellenstruktur an
Dim Rows As DataRow() = DirectCast(e.Node.Tag, DataRow())
If Rows.Length > 0 Then
TempTableRows = Rows 'Referenzen der Dataset-Tabellenzeilen
For i As Integer = 0 To Rows.Length - 1
'siehe oben
Next i
end if
End If Die Modifikation der temporären Tabelle muß irgendwo registriert werden.
Sei "dgv" das Datagridview an das "dtx" (lokal) gebunden ist ....
Private Sub dgv_CellEndEdit(sender As Object,
e As DataGridViewCellEventArgs) Handles dgv.CellEndEdit
TempTableModified = True
End Sub Beim Zurückschreiben der editierten Daten wird der Lesevorgang umgekehrt ...
Private Sub SaveTempTableRows()
For i As Integer = 0 To dtx.Rows.Count - 1
'Spaltenbezeichner wie oben
TempTableRows(i)("Spaltenbezeichner") = dtx(i)("Spaltenbezeichner")
'....
Next i
End Sub Die Verarbeitung von "Hinzufügen" oder "Löschen" von Datensätzen
erfordert etwas zusätzlichen Programmieraufwand
(Beachtung des Rowstate, Rückverzeigerung) !!!!!!!!!! | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 12.03.18 10:22 |
| Hallo Manfred X,
es liegt nicht an dir, habe jetzt mal versucht es umzusetzen. Scheinbar habe ich da noch einen Blocker
im Schädel. So ist es wohl falsch, da ich noch die Fehler bekommen beim neuen Klick auf Node
die Zeile sei entfernt worden.
ist die Erweiterung evtl. falsch von mir verstanden?
Private Sub Trv_NodeMouseClick(sender As Object,
e As TreeNodeMouseClickEventArgs) Handles Trv.NodeMouseClick
'Speichern der zuvor editierten Daten
If TempTableModified Then SaveTempTableRows()
TempTableRows = Nothing
dtx.Clear()
If e.Node.Level = 1 Then
'Hier kommen Datensätze mit vollständiger Tabellenstruktur an
Dim rows As DataRow() = DirectCast(e.Node.Tag, DataRow())
For i As Integer = 0 To rows.Length - 1
'Hier wir eine neue Zeile mit reduz. Spalten-Schema erstellt
Dim newrow As DataRow = dtx.NewRow
'Hier ist die Spaltenzuordnung korrekt vorzunehmen
'Annahme: die Spaltenbezeichner sind übernommen worden"
newrow("ID") = rows(i)("ID") 'oder Schlüsselspalteneintrag aus
' rows(i)
newrow("Erfassungsdatum") = rows(i)("Erfassungsdatum")
newrow("Artikelnummer") = rows(i)("Artikelnummer")
newrow("Artikelbezeichnung") = rows(i)("Artikelbezeichnung")
newrow("Mindestbestand") = rows(i)("Mindestbestand")
newrow("Meldeschwelle") = rows(i)("Meldeschwelle")
newrow("Maximo") = rows(i)("Maximo")
newrow("erledigt") = rows(i)("erledigt")
'usw.
dtx.Rows.Add(newrow) 'aufbereitete Zeile in dtx eintragen
Next i
End If
End Sub
Private Sub ArtikelDGV_CellEndEdit(sender As Object,
e As DataGridViewCellEventArgs) Handles ArtikelDGV.CellEndEdit
TempTableModified = True
End Sub
'Speichervorgang
Private Sub SaveTempTableRows()
For i As Integer = 0 To dtx.Rows.Count - 1
'Spaltenbezeichner wie oben
TempTableRows(i)("Erfassungsdatum") = dtx(i)("Erfassungsdatum")
TempTableRows(i)("Artikelnummer") = dtx(i)("Artikelnummer")
TempTableRows(i)("Artikelbezeichnung") = dtx(i)( _
"Artikelbezeichnung")
TempTableRows(i)("Mindestbestand") = dtx(i)("Mindestbestand")
TempTableRows(i)("Meldeschwelle") = dtx(i)("Meldeschwelle")
TempTableRows(i)("Maximo") = dtx(i)("Maximo")
TempTableRows(i)("erledigt") = dtx(i)("erledigt")
'....
Next i
End Sub | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 12.03.18 11:34 |
| Tja. Dann schau Dir meinen Code noch einmal an.
Bei Dir fehlen einige (entscheidende) Zeilen
im NodeMouseclick-Handler.
Am Ende der SaveTempTableRows-Routine sollte noch
TempTableNotified = false gesetzt werden.
Beitrag wurde zuletzt am 12.03.18 um 11:37:02 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 12.03.18 12:13 |
| Oh Mann, ist mir schon Peinlich das ich die Super Vorlage nicht verstehe ergänzen bzw. umsetzen kann
ich denke da komplett falsch. Sorry, Sorry hoffe das ich dich jetzt nicht verärgert habe.
ich will es aber verstehen.
das hier ist murx.
Private Sub Trv_NodeMouseClick(sender As Object,
e As TreeNodeMouseClickEventArgs) Handles Trv.NodeMouseClick
dtx.Clear()
If e.Node.Level = 1 Then
'Hier kommen Datensätze mit vollständiger Tabellenstruktur an
Dim rows As DataRow() = DirectCast(e.Node.Tag, DataRow())
For i As Integer = 0 To rows.Length - 1
'Hier wir eine neue Zeile mit reduz. Spalten-Schema erstellt
Dim newrow As DataRow = dtx.NewRow
'Hier ist die Spaltenzuordnung korrekt vorzunehmen
'Annahme: die Spaltenbezeichner sind übernommen worden"
newrow("ID") = rows(i)("ID") 'oder Schlüsselspalteneintrag aus
' rows(i)
newrow("Erfassungsdatum") = rows(i)("Erfassungsdatum")
newrow("Artikelnummer") = rows(i)("Artikelnummer")
newrow("Artikelbezeichnung") = rows(i)("Artikelbezeichnung")
newrow("Mindestbestand") = rows(i)("Mindestbestand")
newrow("Meldeschwelle") = rows(i)("Meldeschwelle")
newrow("Maximo") = rows(i)("Maximo")
newrow("erledigt") = rows(i)("erledigt")
'usw.
dtx.Rows.Add(newrow) 'aufbereitete Zeile in dtx eintragen
Next i
End If
'Speichern der zuvor editierten Daten
If TempTableModified Then SaveTempTableRows()
TempTableRows = Nothing
dtx.Clear()
If e.Node.Level = 1 Then
'Hier kommen Datensätze mit vollständiger Tabellenstruktur an
Dim Rows As DataRow() = DirectCast(e.Node.Tag, DataRow())
If Rows.Length > 0 Then
TempTableRows = Rows 'Referenzen der Dataset-Tabellenzeilen
For i As Integer = 0 To Rows.Length - 1
'Hier wir eine neue Zeile mit reduz. Spalten-Schema erstellt
Dim newrow As DataRow = dtx.NewRow
'Hier ist die Spaltenzuordnung korrekt vorzunehmen
'Annahme: die Spaltenbezeichner sind übernommen worden"
newrow("ID") = Rows(i)("ID") 'oder Schlüsselspalteneintrag
' aus rows(i)
newrow("Erfassungsdatum") = Rows(i)("Erfassungsdatum")
newrow("Artikelnummer") = Rows(i)("Artikelnummer")
newrow("Artikelbezeichnung") = Rows(i)("Artikelbezeichnung")
newrow("Mindestbestand") = Rows(i)("Mindestbestand")
newrow("Meldeschwelle") = Rows(i)("Meldeschwelle")
newrow("Maximo") = Rows(i)("Maximo")
newrow("erledigt") = Rows(i)("erledigt")
'usw.
dtx.Rows.Add(newrow) 'aufbereitete Zeile in dtx eintragen
Next i
End If
End If
End Sub
Private Sub ArtikelDGV_CellEndEdit(sender As Object,
e As DataGridViewCellEventArgs) Handles ArtikelDGV.CellEndEdit
TempTableModified = True
End Sub
'Speichervorgang
Private Sub SaveTempTableRows()
For i As Integer = 0 To dtx.Rows.Count - 1
'Spaltenbezeichner wie oben
TempTableRows(i)("Erfassungsdatum") = dtx(i)("Erfassungsdatum")
TempTableRows(i)("Artikelnummer") = dtx(i)("Artikelnummer")
TempTableRows(i)("Artikelbezeichnung") = dtx(i)( _
"Artikelbezeichnung")
TempTableRows(i)("Mindestbestand") = dtx(i)("Mindestbestand")
TempTableRows(i)("Meldeschwelle") = dtx(i)("Meldeschwelle")
TempTableRows(i)("Maximo") = dtx(i)("Maximo")
TempTableRows(i)("erledigt") = dtx(i)("erledigt")
'....
Next i
TempTableModified = False
End Sub ich will doch nur meine Checkbox haken setzen die Maximo Nummer eintragen und speichern.
warum über MouseNode klick? | |
Re: TreeView befüllen in VB2010 | | | Autor: Manfred X | Datum: 12.03.18 12:31 |
| Private Sub Trv_NodeMouseClick(sender As Object,
e As TreeNodeMouseClickEventArgs) Handles Trv.NodeMouseClick
'Speichern der zuvor editierten Daten
If TempTableModified Then SaveTempTableRows()
TempTableRows = Nothing
dtx.Clear()
If e.Node.Level = 1 Then
'Hier kommen Datensätze mit vollständiger Tabellenstruktur an
Dim Rows As DataRow() = DirectCast(e.Node.Tag, DataRow())
If Rows.Length > 0 Then
TempTableRows = Rows 'Referenzen der Dataset-Tabellenzeilen
For i As Integer = 0 To Rows.Length - 1
'Hier wir eine neue Zeile mit reduz. Spalten-Schema erstellt
Dim newrow As DataRow = dtx.NewRow
'Hier ist die Spaltenzuordnung korrekt vorzunehmen
'Annahme: die Spaltenbezeichner sind übernommen worden"
newrow("ID") = Rows(i)("ID") 'oder Schlüsselspalteneintrag
' aus rows(i)
newrow("Erfassungsdatum") = Rows(i)("Erfassungsdatum")
newrow("Artikelnummer") = Rows(i)("Artikelnummer")
newrow("Artikelbezeichnung") = Rows(i)("Artikelbezeichnung")
newrow("Mindestbestand") = Rows(i)("Mindestbestand")
newrow("Meldeschwelle") = Rows(i)("Meldeschwelle")
newrow("Maximo") = Rows(i)("Maximo")
newrow("erledigt") = Rows(i)("erledigt")
'usw.
dtx.Rows.Add(newrow) 'aufbereitete Zeile in dtx eintragen
Next i
End If
End If
End Sub Bei jedem Click auf einen Node in der ersten Ebene
werden die untergeordneten Datenzeilen (Artikel) in dtx
eingetragen. Die Referenzen dieser Dataset-Zeilen werden für das
Aktualisieren nach dem Editieren in "TempTableRows"
zwischen-gespeichert.
(Hinweis: erste Ebene ist eigentlich falsch
Stammknoten = 0 ... Artikel = 2)
Bei einem Click auf einen anderen Node muß
ggf. der Inhalt der bereits editierten dtx zunächst zurückübertragen
werden in die Dataset-Tabelle (über TempTableRows-Referenzen).
Danach wird dtx ggf. neu gefüllt mit den Artikeln des nächsten
Knotens (NodeMouseClick).
Abhängig davon, wie dieses Formular eingesetzt wird, muß beim
Verlassen des Formulars noch einmal diese Zeile ausgeführt werden:
If TempTableModified Then SaveTempTableRows()
Das stellt sicher, daß auch die letzte Änderung übertragen wird.
Um diesen Vorgang wirklich zu verstehen, mußt Du die Grundprinzipien
des objektorientieren Programmierens begriffen haben.
Beitrag wurde zuletzt am 12.03.18 um 12:32:26 editiert. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 12.03.18 13:11 |
| Ja da haste Recht mein Guter.
Um diesen Vorgang wirklich zu verstehen, mußt Du die Grundprinzipien
des objektorientieren Programmierens begriffen haben.
aber nun bin ich langsam am Verzweifeln, die 2 Ebene wähle dann füllt sich keine Tabelle (dtx)
in der ersten füllt sich die Tabelle doch sobald ich dann eine Änderung in der Textbox "Maximo"
muss ich (soll) ich eigentlich die Änderung MAXIMO direkt im DGV machen?
vornehme und erneut auf NodeMouseClick kommt wieder Zeile wurde entfernt??
am einlesen des TV kann es scheinbar nicht liegen, das füllt sich eigentlich immer korrekt.
Private Sub init_TVArtikelverwaltung()
Dim Rootnode As TreeNode = Nothing
Trv.Nodes.Clear()
'Treeview-Knoten gemäß Datarelations erstellen
Dim nd_i, nd_k As TreeNode
Dim row_i, row_k As DataRow 'aktuelle Datarow in Schleife
Dim rel_i, rel_k As String 'Name der Datarelation
Dim col_i, col_k As Integer 'Index der anzuzeigenden Spalte im Treeview
Dim val_i, val_k As String 'anzuzeigender Daten-Wert im Treeview
For i As Integer = 0 To LagerDB.Tables("Warengruppen").Rows.Count - 1
row_i = LagerDB.Tables("Warengruppen").Rows(i)
col_i = 1
val_i = row_i(col_i).ToString
nd_i = GetNode(Trv.Nodes, val_i)
rel_i = LagerDB.Relations( _
"Warengruppen_Artikelgruppen").RelationName
For k As Integer = 0 To row_i.GetChildRows(rel_i).Length - 1
row_k = row_i.GetChildRows(rel_i)(k)
col_k = 1
val_k = row_k(col_k).ToString
nd_k = GetNode(nd_i.Nodes, val_k)
rel_k = LagerDB.Relations("Artikelgruppen_Artikel").RelationName
'Speichern einer Referenz des Childrows-Array im Knoten
nd_k.Tag = row_k.GetChildRows(rel_k)
'zusätzlich: Text des Knotens erweitern
nd_k.Text = val_k & _
" (" & row_k.GetChildRows( _
rel_k).Length.ToString & ")" & " Artikel"
nd_k.ImageIndex = 3
Next k
Next i
End Sub | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 12.03.18 15:37 |
| wir müssen noch mal reden, irgendwie hat es schon mal funktioniert bei mir.
wir vergessen aber den Adapter den ich verwende, die Daten sind nicht wirklich gespeichert in der Artikel Tabelle.
bis später dann. | |
Re: TreeView befüllen in VB2010 | | | Autor: ERBRU | Datum: 15.03.18 19:36 |
| Hallo Manfred X,
verstehe das du dich noch nicht wieder gemeldet hast.
ich hatte in den letzten Tagen das Problem, das ich mir durch das hin und her probieren meine Form kaputt gemacht habe "Editor zerschossen", mittlerweile erneut aufgebaut. Aber wie schon erwähnt ich kriege die "Artikel" Tabelle nicht aktualisiert
ich möchte es verstehen, warum kann ich nicht einfach die Nummer in die TextBox schreiben und speichern? ich nehme auch gern eine Form für die Eingabe die dann in Artikel speichert Haken / Maximo
https://picload.org/view/dalpgail/11-03-_2018_11-41-27.png.html
Beitrag wurde zuletzt am 15.03.18 um 19:38:38 editiert. | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
vb@rchiv CD Vol.6 vb@rchiv Vol.6
Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
Online-Update-Funktion Entwickler-Vollversionen u.v.m.Jetzt zugreifen Tipp des Monats Neu! sevDTA 3.0 Pro
SEPA mit Kontonummernprüfung
Erstellen von SEPA-Dateien mit integriertem BIC-Verzeichnis und Konto- nummern-Prüfverfahren, so dass ungültige Bankdaten bereits im Vorfeld ermittelt werden können. Weitere Infos
|