Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Achtung: Dies ist nicht der vollständige Artikel, sondern nur ein paar Seiten davon. Wenn Sie hier nicht erfahren, was Sie wissen möchten, finden Sie am Ende Informationen darüber, wie Sie den ganzen Artikel lesen können.

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 3/2009.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

Zusammenfassung

Lernen Sie eine Lösung kennen, die das Konfigurieren von TreeViews maßgeblich vereinfacht.

Techniken

VBA, TreeView

Voraussetzungen

Access 2002 und höher

Beispieldateien

TreeViewConfigurator.mdb

Shortlink

667

TreeView-Konfigurator

André Minhorst, Duisburg

"Ein TreeView füllen - mit hierarchischen Daten? Das ist doch wohl ein alter Hut!" Das stimmt wohl, denn genau dafür ist dieses Steuerelement ja nun auch gemacht. Wir vereinfachen das Füllen des TreeViews aber ein wenig, indem wir eine Methode bereitstellen, bei der Sie nur noch die Namen der betroffenen Tabelle in eine weitere Tabelle schreiben und die beim Klicken auf die Elemente des TreeViews durchzuführenden Aktionen festlegen müssen.

Haben Sie schon mal ein TreeView programmiert, das zumindest die üblichen Funktionen wie das Hinzufügen untergeordneter Elemente, das Löschen des aktuellen Knotens, das Auf- und Zuklappen von Zweigen, sowie das automatische Speichern des Zustands des TreeViews implementiert?

Und welches zusätzlich, um die Performance zu verbessern, nur jeweils die sichtbaren Elemente plus der folgenden Ebene anlegt, damit nicht alle Elemente gleich zu Beginn geladen werden müssen und dies somit möglicherweise zu Verzögerungen führt?

Nun, dann wissen Sie, wie viel Arbeit so etwas verursachen kann - egal, ob Sie die Daten aus den Tabellen eines hierarchisch aufgebauten Datenmodells beziehen oder aus einer Tabelle, die reflexiv mit sich selbst verknüpft ist.

Wenn Sie sich mit ein paar Randbedingungen abfinden und die nachfolgend vorgestellten Standardfunktionen für Ihren Anwendungsfall ausreichen, können Sie die Lösung dieses Beitrags gleich einsetzen. Wenn nicht, müssen Sie entweder selbst noch Funktionen hinzufügen oder uns die fehlenden Funktionen mitteilen - wir werden uns nicht scheuen, sinnvolle Erweiterungen für Sie zu entwickeln und in einer späteren Ausgabe von Access im Unternehmen zu veröffentlichen.

Abb. 1 zeigt ein Beispiel für ein mit dem hier vorgestellten Tool gesteuerten TreeView-Steuerelement. Sie können damit sowohl die Daten aus hierarchisch angeordneten Tabellen als auch von Daten aus reflexiven Beziehungen darstellen - auch gemischt. In den folgenden Abschnitten erfahren Sie, wie dies funktioniert und welche Voraussetzungen nötig sind.

pic001.png

Abb. 1: TreeView mit hierarchischen und reflexiven Tabellen

Voraussetzungen des Datenmodells

Die Voraussetzungen beziehen sich in erster Linie auf den Aufbau der Tabellen, deren Daten im TreeView angezeigt werden sollen. Diese sehen so aus:

  • Jede Tabelle muss einen aus einem einzigen Feld bestehenden Primärschlüssel mit dem Datentyp Long besitzen.
  • Jede Tabelle, die einer Tabelle untergeordnet ist, muss ein Fremdschlüsselfeld zur Herstellung der Verknüpfung mit der übergeordneten Tabelle besitzen (nur die Tabelle mit den Elementen der obersten Ebene braucht kein Fremdschlüsselfeld).
  • Wenn eine Tabelle mit sich selbst verknüpft ist, muss sie ein zusätzliches Fremdschlüsselfeld besitzen, das den Wert des Primärschlüsselfelds des übergeordneten Datensatzes enthält.
  • Wenn eine Tabelle mit sich selbst verknüpft ist und das Root-Element, also das oberste Element, mit einem Element aus einer anderen Tabelle verknüpft werden soll, muss es natürlich noch ein weiteres Fremdschlüsselfeld zur Verknüpfung mit dieser anderen Tabelle aufweisen - neben dem Fremdschlüsselfeld für die Herstellung der reflexiven Beziehung. Es darf dann nur eines der beiden Fremdschlüsselfelder gefüllt sein.
  • Jede Tabelle muss ein Feld mit dem anzuzeigenden Text enthalten.
  • Jede Tabelle muss ein Ja/Nein-Feld zum Speichern der Expanded-Eigenschaft des entsprechenden Elements besitzen. Dieses legt fest, ob eventuell untergeordnete Elemente direkt beim Öffnen des TreeViews ausgeklappt werden.
  • Jede Tabelle muss ein Feld zum Speichern des Namens einer Bilddatei enthalten, das in Zusammenhang mit dem jeweiligen Element angezeigt werden soll. Auch wenn dieses Feld nicht mit Daten gefüllt werden muss, so sollte es doch vorhanden sein. Die Bilddateien werden in einer speziellen Tabelle gespeichert - dazu später mehr.

Abfragen statt Tabellen

Die geforderten Informationen können auch in Form einer Abfrage bereitgestellt werden. Dies macht beispielsweise Sinn, wenn Personennamen im TreeView angezeigt werden sollen und diese Namen nicht in einem einzelnen Feld, sondern in Feldern wie Vorname und Nachname liegen. Sie können dann eine Abfrage definieren, die diese Felder zu einem Feld zusammenfasst, das dann als Herkunft für die anzuzeigenden Felder dient.

Auch kann es sein, dass eine reflexive Beziehung nicht direkt über ein in der Tabelle befindliches Fremdschlüsselfeld hergestellt wird, sondern über eine Verknüpfungstabelle, welche neben einem Primärschlüsselfeld zwei Fremdschlüsselfelder für die Aufnahme der beiden Primärschlüsselwerte der beteiligten Datensätze aufnehmen soll. Auch hier müssen Sie eine Abfrage so erstellen, dass diese die eigentlichen Daten der Tabelle enthält und auch die Verknüpfungstabelle aufnimmt. Ein Beispiel finden Sie weiter unten.

Notwendige Elemente

Die hier vorgestellte Lösung ist kein externes Tool, das Ihnen den Code für das TreeView-Steuerelement zusammenbaut, sondern es liefert selbst den Code. Es erstellt also kein TreeView, sondern es steuert seine Erstellung und auch das TreeView und seine Elemente selbst. Aus der Beispieldatenbank zu diesem Beitrag müssen Sie die folgenden Elemente in die Zieldatenbank importieren:

  • Tabelle tblContextMenuItems
  • Tabelle tblImages
  • Tabelle tblTreeViewConf
  • Tabelle tblTreeViews
  • Abfrage qryImages
  • Formular frmTreeViewConf
  • Formular sfmContextmenuItems
  • Formular sfmTreeViewConf
  • Modul mdlDatabase
  • Modul mdlErrorHandlung
  • Modul OGL2007
  • Modul mdlOLE
  • Klassenmodul clsCommandBarButton
  • Klassenmodul clsCommandBarButtonCollection
  • Klassenmodul clsTreeView

Notwendige Verweise

Außerdem brauchen Sie einen Verweis auf die Microsoft Office x.0 Object Library sowie OLE Automation, die Sie im Verweise-Dialog (Extras|Verweise) des VBA-Editors einstellen.

Grundgerüst

Das Grundgerüst unserer Lösung besteht aus einem Formular mit den folgenden Steuerelementen:

  • Microsoft TreeView Control 6.0
  • Microsoft ImageList Control 6.0

Hinzu kommt, soweit gewünscht, ein Unterformularsteuerelement zur Anzeige der Unterformulare mit den Detaildaten zum jeweils im TreeView-Steuerelement ausgewählten Element. Wenn Sie die oben genannten Steuerelemente zu einem neuen Formular namens frmProjekte hinzugefügt haben, können Sie das Projekt erstmalig kompilieren, was im Erfolgsfall heißt, dass alle Komponenten und Verweise vorliegen.

Steuerelemente benennen

Da das ImageList-Steuerelement und das TreeView-Steuerelement später vom Code aus referenziert werden sollen, vergeben Sie nun aussagekräftige Namen für diese Elemente, am besten die folgenden:

  • TreeView-Steuerelement: ctlTreeView
  • ImageList-Steuerelement: ctlImageList

TreeView konfigurieren

Wir kümmern uns zunächst nur um das Anlegen der nötigen Tabellen und um das Füllen des TreeView-Steuerelements. Zuallererst benötigen wir eine Tabelle, welche die Daten für die Elemente der ersten Ebene liefert.

Diese Tabelle nennen wir tblProjekte und füllen sie mit den Feldern aus Abb. 2. Dies sind die mindestens notwendigen Felder für die Integration der Daten einer Tabelle in das TreeView - zumindest unter Verwendung unserer Lösung. Legen Sie dann zu Beispielzwecken einige Datensätze wie in Abb. 3 an.

pic002.png

Abb. 2: Die Tabelle mit den Elementen der obersten Ebene in der Entwurfsansicht ...

pic003.png

Abb. 3: ... und in der Datenblattansicht mit einigen Einträgen.

TreeViewHandler aufrufen

Damit das Formular beim Öffnen mit den gewünschten Daten gefüllt wird, müssen Sie dafür sorgen, dass es eine spezielle Klasse namens clsTreeViewHandler instanziert und dieser einige Informationen zuweist. Dies ist nicht besonders aufwendig und kann in der Ereignisprozedur Form_Load geschehen. Theoretisch ginge auch Form_Open, hier kann es jedoch zu Problemen kommen, weil die ActiveX-Steuerelemente möglicherweise noch nicht initialisiert sind.

Für den Verweis auf die Klasse clsTreeViewHandler legen Sie folgende modulweit gültige Variable im Klassenmodul des Formulars fest:

Private WithEvents objTreeViewHandler As µ

clsTreeViewHandler

Diese instanzieren Sie gleich in der ersten Zeile der Ereignisprozedur Form_Load. Anschließend weisen Sie dem neu erzeugten Objekt Verweise auf das TreeView-Steuerelement und das ImageList-Steuerelement zu und rufen die beiden Methoden InitTreeView und FillTree auf:

Private Sub Form_Load()

    Set objTreeViewHandler = New clsTreeViewHandler

    With objTreeViewHandler

    Set .TreeViewInst = Me.ctlTreeView.Object

    Set .ImageListInst = Me.ctlImageList.Object

    .InitTreeView (1)

    .FillTree

    End With

    End Sub

InitTreeView erwartet noch einen Parameter, zu diesem kommen wir gleich. Erstmal müssen wir noch festlegen, welche Daten überhaupt im TreeView angezeigt werden sollen - wir sind noch nicht so weit, dass sich der TreeViewHandler die benötigten Tabellen selbst zusammensucht.

Dazu öffnen Sie das Formular frmTreeViewConf, das erst einmal eine InputBox zur Eingabe des Namens eines TreeViews voranschickt (s. Abb. 4). Die Eingabe speichert der TreeView-Konfigurator in der Tabelle tblTreeViews. Der Hintergrund ist, dass eine Datenbank durchaus mehr als ein TreeView-Steuerelement enthalten kann (genau genommen kann sogar ein einziges Formular mehr als ein TreeView-Steuerelement anzeigen) und der TreeView-Konfigurator diese auch verwalten können soll.

pic004.png

Abb. 4: Abfrage der Bezeichnung des TreeViews

Dann folgt der große Moment: Der TreeView-Konfigurator erscheint und erschlägt Sie vermutlich erstmal durch seine vielen Elemente (s. Abb. 5). Das TreeView-Steuerelement Projektbaum ist im oberen Kombinationsfeld bereits ausgewählt.

pic005.png

Abb. 5: Der TreeView-Konfigurator

Der obere Teil zeigt eine Übersicht aller im TreeView anzuzeigenden Tabellen an. Dort wählen Sie eine Tabelle aus und erhalten im Bereich darunter alle Details dieser Tabelle, die Sie dort auch direkt bearbeiten können. Außerdem finden Sie dort Steuerelemente zum Anlegen einer neuen Tabelle, zum Löschen der aktuell angezeigten Tabelle, sowie zum Speichern.

Der untere Bereich zeigt ebenfalls eine Liste an, die Sie allerdings direkt bearbeiten können. Dort tragen Sie alle Kontextmenüeinträge ein, die in Zusammenhang mit den Elementen der aktuellen Tabelle im TreeView erscheinen sollen, wenn der Benutzer mit der rechten Maustaste darauf klickt. Wie Sie Code anlegen, um auf diese Mausklicks zu reagieren, erfahren Sie später.

Nun tragen Sie die bereits angelegte Tabelle tblProjekte in den TreeView-Konfigurator ein. Die Daten dieser Tabelle sehen nun etwa so wie in Abb. 6 aus. Im Einzelnen bedeuten diese Einträge Folgendes:

pic006.png

Abb. 6: Die Werte für die erste Tabelle im TreeView-Konfigurator

  • ThisTable: Name der Tabelle, welche die Daten für die Elemente dieser Ebene liefert
  • KeyChar: Jedes TreeView-Element erhält als eindeutige Kennung einen Key, der aus einem Buchstaben und dem Wert des Primärschlüsselfelds des entsprechenden Datensatzes besteht. Der hier festgelegte KeyChar muss innerhalb des TreeViews eindeutig sein, da über ihn die Tabelle identifiziert wird, aus der ein Element stammt.
  • PKIDField: Name des Primärschlüsselfeldes der Tabelle dieser Ebene
  • NodetextField: Name des Feldes, das den im TreeView-Element anzuzeigenden Text enthält
  • NodeImageField: Name des Feldes, das die Bezeichnung des Bilds aus dem ImageList-Steuerelement enthält, das für die Elemente dieser Tabelle standardmäßig angezeigt werden soll
  • NodeExpandedField: Name des Ja/Nein-Feldes, das den Expanded/Collapsed-Zustand des vom Element des aktuellen Datensatzes ausgehenden Zweigs festlegt

Der erste Test

Vor dem ersten Test ist noch eine Anpassung im Code nötig: Wir haben der Methode InitTreeView in der Ereignisprozedur Form_Load zunächst den Wert 1 als Parameter mitgegeben.

Dort muss aber die ID der soeben im TreeView-Konfigurator angelegten TreeViews-Konfiguration stehen, die Sie dem Textfeld aus Abb. 7 entnehmen können.

pic017.png

Sie haben das Ende des frei verfügbaren Teils des Artikels erreicht. Lesen Sie weiter, um zu erfahren, wie Sie den vollständigen Artikel lesen und auf viele hundert weitere Artikel zugreifen können.

Sind Sie Abonnent?Jetzt einloggen ...
 

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Verwandte Beiträge:

TreeView-Elemente im Griff

TreeView nach Bedarf füllen

Das Treeview-Steuerelement

Ereignisse im Eigenbau

Kontextmenüs von A bis Z

Ereignisprozeduren

Hierarchien visualisieren

Registersteuerelemente von A-Z

Globale Suche

VBA-Code mit Doxygen dokumentieren

Grundlagen der Quellcodeverwaltung

Effizientes Codieren

Ereignisprozeduren implantieren

Erweitern des VBA-Editors

Softwareprojekte verwalten

Das Optionsgruppen-Steuerelement

Trojanische Kontextmenüs am Beispiel Excel

Flexible Datumstextfelder

Tipps und Tricks

Access 2007: Bilder und Schaltflächen

Tipps und Tricks

Zippen ohne Zusatzkomponente

Formulare generieren

Steuerelemente zur Laufzeit verschieben

Das Append-Only-Memofeld

Auswahlfelder im Ribbon

Modale Dialoge mal anders

Listenfeld und Details in einem Formular

© 2003-2015 André Minhorst Alle Rechte vorbehalten.