TreeView nach Bedarf füllen

Das TreeView-Steuerelement ist die unangefochtene Nummer eins, wenn es um die Anzeige hierarchischer Daten geht. Es hat aber gegenüber den eingebauten Steuerelementen von Access den Nachteil, dass Sie es nicht an eine Datenherkunft binden können und somit selbst für das Füllen verantwortlich sind. Dies dauert mit wachsender Datenmenge recht lange, daher zeigen wir Ihnen, wie Sie die Daten des TreeView-Elements erst bei Bedarf laden.

Je nachdem, wie Sie ein TreeView gestalten, kann das Füllen schon einige Sekunden in Anspruch nehmen. Das gilt insbesondere dann, wenn Sie auch noch benutzerdefinierte Icons verwenden, die zur Laufzeit noch ein ein ImageList-Steuerelement geladen werden. Gestalterische Spielereien bleiben in diesem Beitrag jedoch außen vor. Wir verwenden eine möglichst einfache Datenstruktur, um Ihnen die für das performante Füllen von TreeView-Steuerelementen benötigten Techniken vorzustellen.

Beispieldaten

Die verwendeten Tabellen sehen daher sehr schlicht aus und sollen eine reflexive Beziehung der Mitglieder einer einzigen Tabelle wiedergeben. Dies geschieht nicht über ein Fremdschlüsselfeld der Haupttabelle, das mit dem Primärschlüsselfeld der gleichen Tabelle verknüpft ist, sondern über eine zusätzliche Verknüpfungstabelle. Das Datenmodell sieht wie in Bild 1 aus. Die Tabelle tblElemente enthält neben der ID als Primärschlüsselfeld noch ein Feld namens Element für die Bezeichnung und eine ImageID, die sich auf eines der anzuzeigenden Icons bezieht – dazu später mehr.

abb001.tif

Bild 1: Datenmodell der reflexiven Beziehung als Grundlage für das Füllen eines TreeView-Steuerelements

Für Testzwecke haben wir diese Tabellen mit 2.000 Elementen und fast ebenso vielen Zuordnungen gefüllt (einige Elemente sind Root-Elemente und keinem anderen Element untergeordnet). Damit kommt ein Füllvorgang zustande, der je nach System eine oder mehrere Sekunden dauert; das reicht aus, um eine merkliche Verzögerung beim Laden festzustellen. Die Routine zum Füllen der Tabellen mit Testdaten können Sie im Modul mdlTestdaten der Beispieldatenbank einsehen.

TreeView mit kompletter Füllung

Im ersten Schritt schauen wir uns ein auf normale Weise gefülltes TreeView-Steuerelement an, was bedeutet, dass dieses auf einen Rutsch mit allen Daten gefüllt wird. Das Ergebnis soll wie in Bild 2 aussehen (das gleiche Ergebnis wird auch später für die optimierte Variante angestrebt). Die Elemente des TreeViews sollen jeweils mit einer von acht möglichen Flaggen als Icon versehen werden, wozu Sie zum Formular neben dem TreeView-Steuerelement, das den Namen ctlTreeView erhält, noch ein ImageList-Steuerelement namens ctlImageList hinzufügen (siehe Bild 3) und dieses für die Eigenschaft ImageList des TreeView-Steuerelements auswählen.

abb003.tif

Bild 2: TreeView mit einigen Beispiel-Elementen

abb002.tif

Bild 3: ImageList-Steuerelement mit den Icons für die TreeView-Einträge

Danach kann es schon losgehen: Im Klassenmodul des Formulars deklarieren wir an zentraler Stelle zunächst eine Objektvariablen für das TreeView-Steuerelement:

Dim objTreeView As µ
MSComctlLib.TreeView

Das TreeView-Steuerelement soll direkt beim Öffnen des Formulars gefüllt werden. Intuitiv verwendet man hier gern die durch das Ereignis Beim Öffnen ausgelöste Ereignisprozedur, was aber in vielen Fällen Probleme verursacht – vor allem im Zusammenhang mit ActiveX-Steuerelementen wie dem TreeView– und dem ListView-Steuerelement.

Verwenden Sie hier das Ereignis Beim Laden: Zum Zeitpunkt des Aufrufs dieses Ereignisses sind alle für das Füllen von ActiveX-Steuerelementen benötigten Elemente sicher initialisiert. In der entsprechenden Ereignisprozedur rufen Sie einfach nur eine weitere Routine auf:

Private Sub Form_Load()
    FillTree
    End Sub

Sie könnten das Füllen des TreeView-Steuerelements mit einer einzigen Routine auskommen (siehe frmTreeViewStandard_Einfach), schneller geht es aber mit einer rekursiven Funktion – also einer Funktion, die sich selbst immer wieder aufruft, bis alle Elemente der Hierarchie abgearbeitet sind.

Die Routine FillTree erledigt diese Aufgabe noch nicht. Sie füllt das TreeView-Steuerelement lediglich mit den Elementen, die kein übergeordnetes Element besitzen, deren ID also in der Tabelle tblZuordnungen nicht in der Spalte ChildID vorkommt.

Die Routine deklariert und instanziert zunächst einige Objekte (s. Listing 1):

Listing 1: TreeView-Füllen, die Basis-Funktion

Private Sub FillTree()
    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    Set db = CurrentDb
    Set objTreeView = Me.ctlTreeView.Object
    Set rst = db.OpenRecordset("SELECT * FROM qryRootelements", dbOpenDynaset)
    Do While Not rst.EOF
        objTreeView.Nodes.Add , , "e" & rst!ID, rst!Element, CLng(rst!ImageID)
        FillTreeRecursive rst!ID, db
        rst.MoveNext
    Loop
    End Sub
  • objTreeView: Enthält einen Verweis auf das TreeView-Steuerelement. Sie könnten zwar auch einfach direkt auf Me!ctlTreeView.Object verweisen, müssten dann aber auf die IntelliSense-Funktion des VBA-Editors verzichten.
  • db: Objektverweis auf die aktuelle Datenbank
  • rst: Objektvariable für das Recordset, das mit allen Elementen der obersten Ebene gefüllt werden soll.

Die Recordsetvariable rst füllen Sie mit einer Datensatzgruppe auf Basis der Abfrage qryRootelements. Diese ist in Bild 4 dargestellt und liefert alle Datensätze der Tabellen tblElemente und tblZuordnungen, bei denen das Feld ParentID der Tabelle tblZuordnung den Wert Null hat. Die Abfrage ist nicht ganz trivial, denn sie würde normalerweise nicht die gewünschten Datensätze, also die Root-Elemente der Hierarchie, zurückliefern, da diese ja überhaupt nicht mit dem Feld ChildID verknüpft sind. Deshalb soll die Abfrage auch alle Elemente der Tabelle tblElemente anzeigen, auch solche, die gar nicht über das Feld ChildID mit der Tabelle tblZuordnungen verknüpft sind.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar