TreeView LITE für Microsoft Access
Access bringt kein Baum-Steuerelement mit. Der TreeView LITE schließt diese Lücke mit dem EdgeBrowser – drei Codemodule, drei Datenquellen, kostenfrei.
Access hat kein Baum-Steuerelement
Wer in Access eine Hierarchie anzeigen will – Warengruppen, Standorte, Ordner, Stücklisten –, steht ohne Bordmittel da. Das alte TreeView-Steuerelement aus der Windows Common Controls Bibliothek ist an eine OCX-Registrierung gebunden, die auf modernen Systemen Ärger macht und in 64-Bit-Installationen ganz ausfällt. Die üblichen Auswege sind Listenfelder mit eingerückten Texten oder Endlosformulare mit Aufklapp-Logik. Beides funktioniert, sieht aber nicht danach aus.
Seit Access den acEdgeBrowser mitbringt, gibt es einen dritten Weg: eine HTML-Seite im Formular, die genau so aussieht und sich so verhält, wie man es von einem Baum erwartet – und die über VBA gesteuert wird.
Der TreeView im EdgeBrowser
Der TreeView LITE ist ein Baustein für eigene Anwendungen: drei Codemodule, die Sie in Ihre Datenbank importieren und an ein Formular binden. Er erzeugt die HTML-Seite selbst, lädt sie in den Browser und hält sie mit VBA in Verbindung. Für den Anwender ist das ein Steuerelement wie jedes andere.
Es sind keine Verweise nötig. Alle externen Objekte entstehen über CreateObject, das Produkt bleibt damit frei von Bibliotheksverweisen – und damit frei von der häufigsten Ursache für Kompilierfehler nach der Weitergabe.
| Datei | Art | Zweck |
|---|---|---|
DPcoreTV.bas | Standardmodul | Laufzeitkern: Fehlerbehandlung, temporäre Dateien, JSON |
clsDPwebBridgeTV.cls | Klassenmodul | Verbindung zwischen VBA und der Seite im Browser |
clsDPtreeView.cls | Klassenmodul | der TreeView selbst |
Der kürzeste lauffähige Code
Ein acEdgeBrowser namens webTreeView auf dem Formular, eine Tabelle als Datenquelle – mehr braucht es nicht:
Option Compare Database
Option Explicit
Private Const C_TIMER_MS As Long = 150 ' Abfrageintervall
Private objTreeView As clsDPtreeView ' Das Steuerelement
Private Sub Form_Load()
Set objTreeView = New clsDPtreeView
objTreeView.Init Me.webTreeView, "webTreeView", "tblTreeView_Demo"
Me.TimerInterval = C_TIMER_MS
End Sub
Private Sub Form_Timer()
On Error Resume Next
If Not objTreeView Is Nothing Then objTreeView.HandleTimer
End Sub
Private Sub webTreeView_DocumentComplete(URL As Variant)
On Error Resume Next
If Not objTreeView Is Nothing Then objTreeView.HandleNavigationComplete
End Sub
Private Sub Form_Close()
On Error Resume Next
Me.TimerInterval = 0
If Not objTreeView Is Nothing Then
objTreeView.Destroy
Set objTreeView = Nothing
End If
End Sub Diese vier Prozeduren sind der vollständige Lebenszyklus: aufbauen, abfragen, Seitenladen melden, aufräumen.
Ohne Timer keine Rückmeldung. Fehlt Form_Timer oder ist TimerInterval nicht gesetzt, erscheint der Baum zwar, meldet aber keine Auswahl zurück. Das ist der häufigste Einbaufehler.
Drei Datenquellen
Alle drei Betriebsarten nutzen dieselbe Klasse und dieselben Eigenschaften. Der Unterschied liegt allein darin, woher die Knoten kommen.
| Betriebsart | Datenquelle | Aufruf |
|---|---|---|
| Tabelle | eine Tabelle mit festem Spaltenschema | Init |
| SQL | eine beliebige SELECT-Anweisung | InitSQL |
| Explorer | das Dateisystem | InitExplorer |
Tabelle
Die Tabelle braucht fünf Spalten. ParentID verweist auf die ID des übergeordneten Knotens; bleibt sie leer, steht der Knoten auf der obersten Ebene.
| Spalte | Typ | Bedeutung |
|---|---|---|
ID | Autowert, Primärschlüssel | eindeutige Kennung |
ParentID | Zahl (Long) | übergeordneter Knoten; leer = oberste Ebene |
Caption | Text (255) | angezeigte Beschriftung |
Picture | Zahl (Long) | Unicode-Codepunkt des Symbols; 0 = automatisch |
SortOrder | Zahl (Long) | Reihenfolge innerhalb der Geschwister |
Picture enthält den Unicode-Codepunkt als Zahl, nicht als Zeichen – 128193 ergibt einen Ordner, 128196 ein Dokument, 0 überlässt die Wahl der Seite. Dass hier eine Zahl steht, ist Absicht: Eine Zahl kann kein Markup transportieren und damit nie zum Einfallstor für eingeschleusten HTML-Code werden.
SQL
Sobald der Baum nicht die ganze Tabelle zeigen soll – gefiltert, verknüpft oder mit berechneter Beschriftung –, übergeben Sie statt des Tabellennamens eine Abfrage. Sie muss ID, ParentID und Caption unter genau diesen Namen liefern; Picture ist optional.
Private Sub btnLoadSQL_Click()
Dim sSQL As String ' Anweisung für das Steuerelement
sSQL = "SELECT ID, ParentID, Caption, Picture FROM [tblTreeView_Demo] " & _
"ORDER BY SortOrder, ID"
Set objTreeView = New clsDPtreeView
objTreeView.InitSQL Me.webTreeView, "webTreeView", sSQL
End Sub Eigene Sortierung angeben. Ohne ORDER BY bestimmt die Datenbank die Reihenfolge der Geschwister. Das Ergebnis wirkt zufällig und ändert sich mit der Zeit.
Dateisystem
Im Explorer-Modus zeigt der Baum Ordner und Dateien. Beim Aufbau wird nur die Wurzel mit ihrer ersten Ebene gelesen, jeder weitere Ordner erst beim ersten Aufklappen. Deshalb öffnen sich auch große Verzeichnisse ohne Wartezeit.
Set objTreeView = New clsDPtreeView
With objTreeView
.Explorer = True
.Path = "C:\Program Files"
.ShowFiles = True
.IncludeHidden = False
.InitExplorer Me.webTreeView, "webTreeView"
End With
Set objTreeView.OnChangeTargetCaption = Me.txtReturn_caption
Set objTreeView.OnChangeTargetPath = Me.txtReturn_path Ordner stehen vor Dateien, beide Gruppen nach Namen aufsteigend. Die Symbole ergeben sich aus der Dateiendung.
Die Knoten-ID im Explorer ist kein Schlüssel. Sie wird bei jedem Einlesen neu vergeben. Um eine Datei später wiederzufinden, speichern Sie den Pfad, nicht die Nummer.
Auswahl entgegennehmen
Für den häufigsten Fall – die Auswahl soll einfach in Textfelder – genügen drei Zuweisungen. Der Rest passiert von selbst:
Set objTreeView.OnChangeTargetId = Me.txtReturn_id
Set objTreeView.OnChangeTargetCaption = Me.txtReturn_caption
Set objTreeView.OnChangeTargetPath = Me.txtReturn_path Wer mehr tun will als anzeigen, etwa einen abhängigen Datensatz laden, greift zum Ereignis:
Private WithEvents objTreeView As clsDPtreeView
Private Sub objTreeView_NodeSelected(ByVal sId As String)
' hier eigene Verarbeitung
End Sub Die zuletzt getroffene Auswahl steht zusätzlich in SelectedId, SelectedCaption und SelectedPath bereit.
FlushNow vor dem Lesen aus einer Schaltfläche. Ein Klick im Baum wartet unter Umständen noch in der Warteschlange der Seite. Ohne FlushNow liest die Schaltfläche den Stand von vor diesem Klick – und zeigt den vorher gewählten Knoten.
Warum ein Timer und kein direktes Auslesen
Ein Klick in der Seite ruft keine VBA-Prozedur auf. Die Seite legt ihn in eine Warteschlange, HandleTimer leert sie und löst daraus die Meldungen aus. Dieser Umweg ist Absicht: Ein unmittelbarer Zugriff aus einem Browser-Ereignis heraus führt bei WebView2 zu einem Wettlauf zwischen Access und dem Seitendarsteller – mit Einfrieren als Folge.
Gelesen wird dabei nicht bei jedem Takt, sondern erst, wenn der Anwender kurz stillhält: keine Maustaste gedrückt, 250 ms Ruhe, dazu ein Mindestabstand, der wächst, während niemand arbeitet. Eine Obergrenze von vier Sekunden sorgt dafür, dass Klicks auch dann ankommen, wenn jemand pausenlos die Maus bewegt. Der Grund ist spürbar: Jede Abfrage hält den Seitendarsteller kurz an, und im falschen Moment ruckelt sonst die Maus im Steuerelement.
LITE und FULL
Der TreeView LITE ist die kostenfreie Fassung. Es gibt eine FULL-Version, die denselben Kern nutzt und deutlich mehr mitbringt:
| Funktion | LITE | FULL |
|---|---|---|
| Tabelle, SQL, Dateisystem | ✅ | ✅ |
| Nachladen von Ordnern bei Bedarf | ✅ | ✅ |
| Symbole je Knoten | ✅ | ✅ |
| Alles auf- und zuklappen | ✅ | ✅ |
| Suche im Baum | ❌ | ✅ |
| Kontextmenü und Drag and Drop | ❌ | ✅ |
| TreeView-Builder (Editor für Bäume) | ❌ | ✅ |
| Symbolauswahl mit 1377 Symbolen | ❌ | ✅ |
| Farben frei einstellbar | ❌ | ✅ |
| Anzahl-Marken und Verbindungslinien | ❌ | ✅ |
| Knotenwerte und Kommentare | ❌ | ✅ |
| Explorer: Sortierung und Dateifilter | ❌ | ✅ |
| Fehlerprotokoll in eine Datei | ❌ | ✅ |
Die öffentliche Schnittstelle der LITE-Version ist eine Teilmenge der FULL-Version. Code, der gegen LITE geschrieben wurde, läuft nach einem Wechsel unverändert weiter, und eine Tabelle der FULL-Version funktioniert in LITE ebenso – deren zusätzliche Spalten werden schlicht nicht gelesen. Die FULL-Version ist auf www.dieterle-programmierung.de erhältlich.
Grenzen und Konventionen
| Punkt | Verhalten in LITE |
|---|---|
| Farben | fest: Weiß, #333333, Akzent #1976d2 |
| Menüleiste | nur im Tabellen- und SQL-Modus, zwei Schaltflächen |
| Explorer-Sortierung | Name aufsteigend, bis 2000 Einträge je Ordner |
| Nicht lesbare Ordner | werden übersprungen, der Vorgang läuft weiter |
| Leerer Ordner | zeigt zunächst einen Pfeil; er verschwindet beim ersten Klick |
| Nicht vorhandener Pfad | der Baum bleibt leer |
| Fehler | Dialog, kein Protokoll |
Keine Ringschlüsse in der Tabelle. Zeigt ParentID auf den eigenen Datensatz, oder verweisen zwei Datensätze gegenseitig aufeinander, entsteht ein Kreis. Das Steuerelement bricht nach 1000 Schritten ab, der betroffene Zweig lässt sich danach aber nicht mehr sinnvoll darstellen.
Einbindung
Drei Module importieren, einen acEdgeBrowser auf das Formular setzen, die vier Prozeduren aus dem Schnellstart übernehmen – fertig. Alles Weitere ist Feinarbeit:
| Ereignis | Was dort hineingehört |
|---|---|
Form_Load | Instanz erzeugen, Eigenschaften setzen, Init… aufrufen, Zielfelder zuweisen, TimerInterval setzen |
Form_Timer | HandleTimer |
DocumentComplete des Browsers | HandleNavigationComplete |
Form_Close | TimerInterval = 0, Destroy, Objektvariable leeren |
Eigenschaften werden vor dem Init-Aufruf gesetzt – der erste Aufbau der Seite geschieht darin, später gesetzte Werte wirken sich nicht mehr aus. Beim Wechsel auf eine andere Tabelle spart SetDataSource den vollständigen Neuaufbau:
If objTreeView.IsAttached Then
objTreeView.SetDataSource "tblTreeView_Andere"
End If Mehrere Bäume auf einem Formular sind ausdrücklich zulässig. Jede Instanz braucht ihren eigenen Browser, ihre eigene Objektvariable und ihren eigenen Aufruf in Form_Timer und DocumentComplete. Jede erhält eine eigene temporäre Datei und arbeitet unabhängig.
Aufräumen erledigt das Steuerelement. Destroy löscht die temporäre Datei der Instanz. Bleibt sie nach einem Absturz liegen, entfernt sie die nächste Access-Sitzung von selbst.
Dem Paket liegt ein Testformular bei, das beide Betriebsarten gleichzeitig zeigt – oben einen Baum aus der Tabelle, unten einen aus dem Dateisystem. Es ist der schnellste Weg, das Verhalten auszuprobieren, und zugleich die Vorlage für den eigenen Einbau.
Download
Kostenfreies Baum-Steuerelement für Microsoft Access auf Basis des acEdgeBrowser. Zeigt Daten aus einer Tabelle, einer SQL-Abfrage oder dem Dateisystem.
Voraussetzungen: Microsoft 365, Access 2024+, 32/64-bit




