TreeView aus Datenbank füllen - Child-Nodes "Problem"

  • VB.NET

Es gibt 63 Antworten in diesem Thema. Der letzte Beitrag () ist von tragl.

    TreeView aus Datenbank füllen - Child-Nodes "Problem"

    Hallo liebes Forum.

    Ich lasse mir ein TreeView aus einer Access-Datenbank füllen. Das klappt auch wunderbar, allerdings werden mir die Variablen
    "tnr" (Zeile 28) und "tnp" (Zeile 33)
    im VisualStudio gekennzeichnet als "verwendet, bevor ein Wert zugewiesen ist", was mit eine unschöne Hinweis-Meldung erzeugt.
    Habt ihr einen Rat für mich?

    Hier mein Code zum Füllen des TreeView. Die "Problemstelle" bezieht sich auf die Zeilen 14-35.

    VB.NET-Quellcode

    1. Public Function DB_tree_lesen(ByVal Datenbank As String, Tabelle As String, TV As TreeView) As String
    2. Try
    3. TV.Nodes.Clear()
    4. DB_connect(Datenbank)
    5. con.Open()
    6. Select Case My.Settings.AppMode
    7. Case "User"
    8. sql_string = "SELECT * FROM `" & Tabelle & "` WHERE (Aktiv = True) AND (nur_admin = False) ORDER BY `Bezeichnung`"
    9. Case "Admin"
    10. sql_string = "SELECT * FROM `" & Tabelle & "` WHERE (Aktiv = True) ORDER BY `Bezeichnung`"
    11. End Select
    12. sql_cmd = New OleDb.OleDbCommand(sql_string, con)
    13. reader = sql_cmd.ExecuteReader
    14. While reader.Read
    15. Dim tnr As TreeNode
    16. Dim tnp As TreeNode
    17. Dim tnc As TreeNode
    18. Dim tntyp As String
    19. tntyp = reader("Typ").ToString()
    20. 'root
    21. If tntyp = "r" Then
    22. tnr = New TreeNode(reader("Bezeichnung").ToString())
    23. TV.Nodes.Add(tnr)
    24. End If
    25. 'parents
    26. If tntyp = "p" Then
    27. tnp = New TreeNode(reader("Bezeichnung").ToString())
    28. tnr.Nodes.Add(tnp)
    29. End If
    30. 'childs
    31. If tntyp = "c" Then
    32. tnc = New TreeNode(reader("Bezeichnung").ToString())
    33. tnp.Nodes.Add(tnc)
    34. End If
    35. End While
    36. con.Close()
    37. Return "OK"
    38. Catch ex As Exception
    39. con.Close()
    40. Msg_ex(ex)
    41. Debug_msg("Tree aus DB lesen", ex.Message)
    42. Return "nicht ok"
    43. End Try
    44. End Function
    Bilder
    • 03.png

      59,37 kB, 1.284×570, 218 mal angesehen
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tragl“ ()

    @tragl Verwendest Du in diesem Fall den richtigen Node?

    Im Fall "p" ist tnr = Nothing.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das Ganze mag funktionieren, wenn die Reihenfolge richtig ist, d.h. wenn der reader die Reihenfolge r, p, c fest zurückgibt. Wenn dem nicht so ist, also reader zuallererst "c" zurückgeben würde, crasht es, weil eben "tnp" zu diesem Zeitpunkt noch nicht festgelegt wurde (weil quasi von Zeile#16 auf Z#33 gesprungen wird). Wenn Du weißt "nee, ich mach immer alles richtig, das kann niemals pasieren", dann ...
    Aber Fehler tauchen nunmal auf. Daher meckert der Compiler zurecht. Denn er weiß definitiv nicht, dass immer die Richtige Reihenfolge kommt. Daher ist Post#2 schon richtig.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Das Ganze mag funktionieren, wenn die Reihenfolge richtig ist
    What :?:
    Die Node-Variablen werden in der reader.Read-Schleife angelegt!
    Ich denke mal so:

    VB.NET-Quellcode

    1. Dim tnr As TreeNode = Nothing
    2. Dim tnp As TreeNode = Nothing
    3. Dim tnc As TreeNode = Nothing
    4. While reader.Read
    5. Dim tntyp = reader("Typ").ToString()
    6. If tntyp = "r" Then
    7. 'root
    8. tnr = New TreeNode(reader("Bezeichnung").ToString())
    9. TV.Nodes.Add(tnr)
    10. ElseIf tntyp = "p" Then
    11. 'parents
    12. tnp = New TreeNode(reader("Bezeichnung").ToString())
    13. tnr.Nodes.Add(tnp)
    14. ElseIf tntyp = "c" Then
    15. 'childs
    16. tnc = New TreeNode(reader("Bezeichnung").ToString())
    17. tnp.Nodes.Add(tnc)
    18. End If
    19. End While
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Mist, ich hab' gerade das Problem dass OneDrive meine Änderungen von gestern abend scheinbar nicht gesynced hat, somit hab ich hier auf der Arbeit
    noch eine alte Version. Ich schau' mir das später an und melde mich, ob es nun klappt :) Ich muss mir jetzt erstmal überlegen wie ich das mit dem Speichern künftig
    lösen kann :(

    EDIT: Daten sind wieder da, habe den Code entsprechend angepasst, allerdings werden die Hinweise noch immer gezeigt.
    Die Sortierung wird über die "ORDER BY"-Klausel festgelegt - das passt soweit. Allerdings hätte ich die Schönheitsfehler trotzdem gerne weg :)
    Bilder
    • 01.PNG

      43,38 kB, 1.030×584, 174 mal angesehen
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tragl“ ()

    tragl schrieb:

    allerdings werden die Hinweise noch immer gezeigt.
    Lesen bildet:

    RodFromGermany schrieb:

    VB.NET-Quellcode

    1. Dim tnr As TreeNode = Nothing
    2. Dim tnp As TreeNode = Nothing
    3. Dim tnc As TreeNode = Nothing



    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    @RodFromGermany: Und was ist, wenn bei Post#5, Zeile#5 beim allerersten reader("Typ").ToString ein "c" gelesen wird, also wenn die While-Schleife das erste mal durchlaufen wird? Dann crasht es. Weil quasi folgende Zeilenreihenfolge entsteht: ##1, #2, #3, #4, #5, #6, #10# 14, #16, #17 -> crash. Mehr wollte ich nicht sagen. Weiß daher jetzt gerade nicht, worauf Du hinaus willst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    tragl schrieb:

    Die Sortierung wird über die "ORDER BY"-Klausel festgelegt - das passt soweit.
    Das ist vermutlich Zufall, dass das bislang passt.
    Wenn länger mit der DB gearbeitet wird, Datensätze zukommen und wieder weggelöscht, dann kann iwann der Zustand eintreten, dass ein Datensatz mit Typ 'c' geliefert wird, bevor überhaupt je ein Typ 'p' vorkam. Das ergäbe dann eine NullReference-Exception, weil's noch keinen ParentNode gibt zum Adden.
    Wahrscheinlicher (und hinterhältiger, weil keine Exception, sondern "nur" falsche Daten) dass bei ungünstiger Reihenfolge ein 'c'-Typ in den falschen 'p'-Typ einsortiert wird.

    Oder wie ist das sichergestellt, dass die 'c'-Typ-Datensätze genau nach denjenigen 'p'-Typ-Datensätzen eintrudeln, in die sie auch einsortiert werden sollen?
    Order By 'Bezeichnung' sortiert ja nach Bezeichnung, nicht nach Typ. (Und nach Typ zu sortieren würde nur falsche Ergebnisse bringen).

    Jo, das war glaub, was Vaprized angesprochen hat.

    Ah - ich denke, das angedachte Problem ist vielleicht schnell verifiziert:
    Zeige mal einen Tree mit 2 'p'-Typen und den 'c'-Typen darinnen an. Füge dann in den ersten 'p'-Typ einen 'c'-Typ-Datensatz ein.
    Unsere Annahme ist, dass dieser neue 'c'-Typ beim nächsten DatenAbruf in den letzten 'p'-Typ gewandert sein wird.

    RodFromGermany schrieb:

    Lesen bildet:

    RodFromGermany schrieb:

    VB.NET-Quellcode

    1. Dim tnr As TreeNode = Nothing
    2. Dim tnp As TreeNode = Nothing
    3. Dim tnc As TreeNode = Nothing



    [/quote]

    Danke, das "Nothing" hatte ich nicht gesehen - war hektisch heute morgen. Damit sind die Fehler nun weg, danke. Zu der Sortierung:
    - Die Einträge des TreeView (auch in der DB) werden wenn überhaupt nur sehr selten geändert, das TreeView bildet mein "Hauptmenu" zur Auswahl
    der einzelnen Programmteile.
    - Die Sortierung ist somit "safe", denn die Bezeichnungen beinhalten Zahlen, die dann wiederum das Menu abbilden (siehe Bilder)
    Nach Typ zu sortieren macht hier in der Tat keinen Sinn und wird zwangsläufig zu Fehlern führen.

    Was ich allerdings nicht bedacht habe:
    In meinem Code wird der TreeView ja mit .Add(Node) gefüllt.
    Um zusätzlich noch einen Key zu vergeben (welcher Sinnvoll für Aufrufe der Programmteile sein sollte), müsste ich den laut MicrosoftDocs mit .Add(String, String) füllen.
    Den String der Nodes zu bekommen ist ja kein Problem, allerdings können sich dann parents und Childs nicht mehr orientieren und tauchen somit nicht mehr auf....

    Außerdem bekomme ich die Root-Nodes leider nicht in "Fett" dargestellt. :(
    Bilder
    • 01.png

      72,62 kB, 337×520, 148 mal angesehen
    • 02.png

      87,15 kB, 1.048×969, 350 mal angesehen
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    tragl schrieb:

    Um zusätzlich noch einen Key zu vergeben ....
    Das mit den Keys bei Treenodes findich total überbewertet.
    Treenode hat zB die Property .FullPath, das ist glaub besser als deine Keys.
    Weil der FullPath ist logisch aufgebaut (wie zB DateiPfade), und wennde die Treenodes anguckst, weiste, wie der FullPath lautet - das kann manchmal ein Vorteil sein, v.a. scheint mir das transparenter.

    Ziemlich fragwürdig finde ich, dass dein Treeview anders strukturiert als die Datenbank.
    Also der Node 2 fehlt in deinem Treeview, und 2.1 ist in Node 1 eingeschachtelt - ist das so gewollt?

    Ansonsten wäre mir das zuviel Datenbank für zuwenig Effekt.
    In meiner Welt würde die Spalte Bezeichnung reichen, und den Aufbau des Treeviews würde ich anhand der Bezeichnungs-Numern durchführen - die geben doch klar eine hierarchische Struktur an. Typ und Key brauchts dafür nicht - ist redundant und nur geeignet, Verwirrung zu stiften.
    Also ich würde nichtmal den Treenode.FullPath statt eines Keys brauchen - wie gesagt: die Bezeichnungs-Nummern sind zur Strukturierung doch perfekt geeignet.

    Eventuell würde ich die Nummer-Spalte vonne Bezeichnung-Spalte trennen - das gehört sich nicht inne Datenbänkerei, wenn man so eine Art Schlüssel mit der eigentlichen Bezeichnung in ein Feld zusammenmanscht.



    naja, vlt. ist das ja alles so gewollt (auch dass dein TV keine 4 anzeigt)
    auf jeden fall ist die Spalte Typ entbehrlich für den TV-Aufbau. Zähle einfach die . der ersten 4 Zeichen der Bezeichnung: Typ r entspricht 0, Typ p 1, Typ c 2.



    Tja, und als Key kannste ja dann ja ersatzweise den FullPath eintragen, wenn du das haben willst.
    Sieht halt doof aus wegen der Nummer.
    Aber das ist ja schon gesagt: Trenne Nummer vonne Bezeichnung - da zeigt sich das gleich, warum sich son zusammenmanschen nicht gehört.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

    VaporiZed schrieb:

    crasht es.
    Klar.
    Ich / wir hatten allerdings vorausgesetzt:

    VaporiZed schrieb:

    Das Ganze mag funktionieren, wenn die Reihenfolge richtig ist, d.h. wenn der reader die Reihenfolge r, p, c fest zurückgibt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Jo, und wo man jetzt die DB sieht: Die Reihenfolge ist tatsächlich korrekt, und tatsächlich sortiert Order By Bezeichnung die Datensätze so, dass Root-, Parent- und Child-Typen in für die Verarbeitung korrekter Reihenfolge antraben.
    Könnte nur imo hübscher gemacht wern: Spalte Typ abschaffen, SortKey und Bezeichnung trennen, evtl. Key auch abschaffen.



    Ups - da fällt mir ein anderer logischer Fehler auf: Order By Bezeichnung geht nur solange gut, wie der SortKey einstellig bleibt.
    Weil das wird ja als String sortiert, und da ist "11" kleiner als "9".

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ja, die ganzen Denkensweisen kenne ich bisher nicht und die waren auch in Excel-VBA nicht von Nöten.
    Der Punkt 2 wird nicht angezeigt, weil er in der Datenbank als aktiv = nein gesetzt ist (mein Fehler).
    Ich wollte mit dem Key arbeiten, um darüber Prozeduren aufzurufen. Ich stelle mir das so vor:

    Es gibt ein Modul namens "Logistik", darin sind Subs (z.B. "Tourenplan_load") welcher dann einen Code verarbeitet.
    Für den Aufruf aus dem Tree hatte ich das in Excel-VBA folgendermaßen gelöst:

    Visual Basic-Quellcode

    1. Private Sub tv_main_Click()
    2. On Error GoTo errhandler
    3. Dim usenode As String
    4. usenode = Me.tv_main.SelectedItem.Key
    5. If Not usenode Like "key*" Then
    6. Application.Run usenode & "_info"
    7. End If
    8. Me.tv_main.SetFocus
    9. Exit Sub
    10. errhandler:
    11. modulname = "frm_main.tv_main_Click"
    12. error.handler (ups)
    13. End Sub
    14. Private Sub tv_main_DblClick()
    15. On Error GoTo errhandler
    16. Dim usenode As String
    17. usenode = Me.tv_main.SelectedItem.Key
    18. If Not usenode Like "key*" Then
    19. Me.Hide
    20. Application.Run usenode & "_load"
    21. End If
    22. Exit Sub
    23. errhandler:
    24. modulname = "frm_main.tv_main_DblClick"
    25. error.handler (ups)
    26. End Sub


    ein einfaches selektieren hat die entsprechende TabPage im Hauptmenu (rechts neben dem tree) aktiviert, Code dazu hinterlegt in (modul.sub_info)
    ein Doppelklick hat den Code aus (modul.sub_load) ausgeführt und das hat für mich gut funktioniert. Wie soll ich das dann hier gestalten?

    Bzgl. der Sortierung und dem Aufbau der DB schaue ich nochmal nach.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    ich hab auch mal eine Treeview-Navigation auf TabPages gemacht. Aber nur die Navigation - Doppelklick zum iwas ausführen hab ich unterlassen.

    Guggemol TabControl ohne Reiter - TreeviewFrameset

    Naja, guggemol. Mag sein ist etwas advanced.
    Was ich noch unterlassen hab, die Programm-Modul-Namen (Alias Tab-Beschriftungen/Namen) aus einer Datenbank zu lesen. Das wird bei mir einfach im Treeview-Designer abgehandelt. Aber kann man natürlich auch anners machen.
    naja, wenn ich den TreeView "Dingfest" mache, dann kann ich die Knoten auch über den Designer machen, Indexieren und entsprechende Auslöser hinterlegen - das funzt schon.
    Will aber dennoch flexibel sein, dass wenn ich dem Programm was hinzufüge oder entferne, nicht auch noch an den Code des TreeView muss. So kann ich in der DB den entsprechenden Node hinzufügen bzw. entfernen samt entsprechendem Aufruf dahinter.Das Thema mit dem TabCOntrol ohne Reiter hab' ich mir schon gebookmarked - da ich das in meiner excel-version
    bereits so nutze, aber im Visual-Studio bestimmt mal wieder etwas anders gehandhabt wird :)

    Edit: Ob man nun mit "Click" oder "DblClick" im TreeView arbeitet, ändert am Code ja nix :) Werd' vermutlich auf den "nur" Doppelklick umsteigen, der mir dann eine Tabpage
    anzeigt, wo alle weiteren Controls für den Teil drin sind. Mit Excel muss man das etwas umständlicher lösen.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tragl“ ()

    tragl schrieb:

    Will aber dennoch flexibel sein, dass wenn ich dem Programm was hinzufüge oder entferne, nicht auch noch an den Code des TreeView muss.
    Wenn du am Programm was änderst, dann musst du eh am Programm was ändern - zB TabPage hnzufügen, Controls drauf und was.
    Und da eben noch im TV den Navigations-Node eintragen...
    Ist dann doch sogar einfacher, als in die DB wechseln, und da herumhampeln, und zusehen, dasses mittm Programm auch synchron ist etc.

    ErfinderDesRades schrieb:


    Ist dann doch sogar einfacher, als in die DB wechseln, und da herumhampeln, und zusehen, dasses mittm Programm auch synchron ist etc.


    Die Datenbank editier' ich ja über das gleiche Programm, nix Access :)
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    wie du wolle, und wie dem auch sei.
    Ich hab jedenfalls mal deinen Code bischen aufgehübscht - ich hoffe, du findest darin ein paar Techniken, die für dich auch im weiteren nützlich sind:

    VB.NET-Quellcode

    1. Public Sub DB_tree_lesen(Datenbank As String, Tabelle As String, TV As TreeView)
    2. TV.Nodes.Clear()
    3. DB_connect(Datenbank)
    4. Dim noAdminSegment = If(My.Settings.AppMode = "User", " AND (nur_admin = False)", "")
    5. Dim sql = $"SELECT * FROM `{Tabelle}` WHERE (Aktiv = True){noAdminSegment} ORDER BY `Bezeichnung`"
    6. Dim nodeCollections = {TV.Nodes, Nothing, Nothing, Nothing} ' die untergeordneten NodeCollections werden im Verlauf eingetragen/aktualisiert
    7. Dim types = "rpc"
    8. Using adp = New OleDbDataAdapter(sql, con), tbl = New DataTable
    9. con.Open()
    10. adp.Fill(tbl)
    11. For Each rw As DataRow In tbl.Rows
    12. Dim tnTyp = rw("Typ").ToString
    13. Dim iNodes = types.IndexOf(tnTyp)
    14. Dim nd = nodeCollections(iNodes).Add(rw("Bezeichnung").ToString)
    15. nodeCollections(iNodes + 1) = nd.Nodes ' untergeordnete NodeCollection aktualisieren
    16. Next
    17. con.Close()
    18. End Using
    19. End Sub
    20. 'oder noch besser:
    21. Public Sub DB_tree_lesen2(Datenbank As String, Tabelle As String, TV As TreeView)
    22. TV.Nodes.Clear()
    23. DB_connect(Datenbank)
    24. Dim noAdminSegment = If(My.Settings.AppMode = "User", " AND (nur_admin = False)", "")
    25. Dim sql = $"SELECT * FROM `{Tabelle}` WHERE (Aktiv = True){noAdminSegment} ORDER BY `Bezeichnung`"
    26. Dim nodeCollections = {TV.Nodes, Nothing, Nothing, Nothing} ' die untergeordneten NodeCollections werden im Verlauf eingetragen/aktualisiert
    27. Dim types = "rpc"
    28. Using adp = New OleDbDataAdapter(sql, con), tbl = New DataTable
    29. con.Open()
    30. adp.Fill(tbl)
    31. For Each rw As DataRow In tbl.Rows
    32. Dim iNodes = types.IndexOf(rw("Typ").ToString)
    33. 'Node zufügen und gleich untergeordnete NodeCollection in nodeCollections eintragen/aktualisieren
    34. nodeCollections(iNodes + 1) = nodeCollections(iNodes).Add(rw("Bezeichnung").ToString).Nodes
    35. Next
    36. con.Close()
    37. End Using
    38. End Sub

    Wichtige Punkte:
    • TryCatch weg. So wie der TryCatch war, war er unnötig kompliziert, und schiesst dir nur ins Knie.
      Wenn das Menü nicht gelesen werden kann, dann muss die Anwendung beenden. Also schmeiss eine Exception - nicht fangen.
      Oder besser noch wie ichs nu gemacht hab: Ich hab nix gemacht, weil dann fliegt ja eh eine Exception, und das ist auch sehr gut so.
      Wichtiges Tut dazu: TryCatch ist ein heisses Eisen
    • Reader-Gefummel weggemacht - mit einem DataAdapter und einer DataTable ist alles viel einfacher
    • Datenbank-Zugriffs-Objekte in einen Using-Block
      Derlei Objekte können vom Garbage-Collector nicht sauber aufgeräumt werden, daher müssen sie in einen Using-Block.
      Das ist .Net-Standard, dass Garbage-Collector-widrige Objekte die IDisposable-Schnittstelle implementieren, und am besten in einem Using-Block benutzt werden, welcher sicherstellt, dass beim Verlassen des Blocks dieses Variablen aufgeräumt werden.
      Such die MS-Dokumentation der VB.Net-Schlüsselworte auf, und schau Using nach - besorg dir ein gut Buch, lies erst das Kapitel über Interfaces nach, und das Kapitel über das IDisposable-Interface.
      Verlass dich nicht auf Foren-Posts oder YouTube-Videos, sondern informier dich an qualifizierter Stelle.
      Zieh dir zB das hier rein, und insbesondere die dort gegebenen Links: Grundlagen: Fachbegriffe
    • Kommentation: Korrekt, präzise, und nur wo es nötig ist
      Schwafel-Kommentare oder gar Unkorrektheiten sind das Gegenteil einer Hilfe, sind Vernebelung bzw. Irreleitung.
      Aber wo es nötig ist, dann auch kommentieren!
    Trickreich und ich finde elegant am gezeigten Code ist, wie er in 4 Zeilen gewährleistet, dass der neue Treenode jeweils in der richtigen TreeNodeCollection landet (zeilen #6,7 und #12 - 15 bzw noch kürzer in #28,29 und #34,35).
    Sieht vlt. voll kryptisch aus, aber sind nur Klassen verwendet, die du möglichst bald und möglichst gut kennenlernen solltest (String, Array, Treenode, TreenodeCollection).
    Probiers zu verstehen, und bei Fragen fragen.

    Achso - kopier den Code aus, und guck, ob er tut, wasser soll.

    Dieser Beitrag wurde bereits 14 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Vielen lieben Dank dafür, werde ich gleich testen und mich mit dem Code auch auseinandersetzen.
    2 Fragen hab' ich noch zur Verständnis:

    -mit {VARIABLE} können generell Variablen abgerufen werden? Oder "nur" in z.B. einem SQL-String? Ich kenn das nur mit & VARIABLE & - was dann auf den
    ersten Blick den Code unübersichtlich machen kann. mit den {} finde ich schöner.

    -das $-Zeichen vor dem Connect-String bewirkt genau was?

    Mit den Typen bzw. vor allem Arrays muss ich mich dringend auseinandersetzen, das macht einem das Leben an vielen Stellen leichter.
    In Excel war das noch recht einfach mit VAR = Array("wert1","wert2") - wird hier genauso einfach sein, aber eben "anders" :)

    An der Stelle auch nochmal ein großes Danke für deine Mühen und vor Allem auch Verständnis. Ich bin neu in VB.NET, in Excel-VBA bin ich auch kein
    Profi, aber finde mich zurecht. Ich probier meist Stunden oder Tage rum, dann schmeiß ich das Internet an und bemühe die Suchen - wenn das nix bringt dann wende
    ich mich dan das Forum. Das Projekt an dem ich sitze macht mir Spaß und wird weder jetzt noch später einen kommerziellen Nutzen haben.
    Hier wird nix verkauft oder ähnliches - wenn überhaupt erhalten das 1-2 Arbeitskollegen von mir. Von daher: Wenn's am Ende mal an 1-2 Stellen nicht zu 100% rund
    läuft ist das auch kein Weltuntergang, aber umso schöner ist es natürlich wenn alles klappt. Von daher bin ich schon bemüht das direkt richtig zu machen, allerdings
    bin ich kein Lesefuchs (mehr) und möchte daher erstmal von einem Buch absehen. Ich stell mir das schwer vor, das abends gemütlich im Bett zu lesen :)


    EDIT: Frage3: Schließt er denn die Verbindung wenn ein Fehler auftreten sollte?
    Und ja, der Code funzt prima.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

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