TreeView-Konfigurator erweitert

Im Beitrag TreeView-Konfigurator (www.access-im-unternehmen.de/667) haben wir Ihnen den TreeView-Konfigurator vorgestellt, mit dem Sie ganz einfach TreeViews mit den Daten aus Ihren Tabellen füllen könen. Diese Lösung haben wir kräftig überarbeitet: Sie können nun noch einfacher die Daten festlegen, die im TreeView-Steuerelement landen sollen, auf mehr Ereignisse reagieren und sogar Daten aus rekursiven Beziehungen dort unterbringen. Im vorliegenden Beitrag zeigen wir Ihnen, wie Sie den TreeView-Konfigurator einsetzen.

Vorbereitung

Die aktuelle Version des TreeView-Konfigurators liegt nicht mehr in Form einzelner Tabellen, Abfragen, Formulare und Module vor, die Sie in die Zieldatenbank kopieren müssen, sondern in einer Bibliotheksdatenbank. Das bedeutet, dass Sie diese Bibliothek in Ihren Verweisen referenzieren müssen. Anschließend reicht es aus, die Bibliotheksdatenbank im gleichen Verzeichnis zu speichern, in dem sich auch die Datenbank mit dem Verweis befindet.

Insgesamt sind folgende Schritte nötig:

  • Setzen Sie einen Verweis auf die Bibliotheksdatenbank TreeViewConfigurator.mde. Dies erledigen Sie, indem Sie im Verweise-Dialog auf die Schaltfläche Durchsuchen klicken und dort die entsprechende Datei auswählen (s. Bild 1).
  • pic013.png

    Bild 1: Verweis auf die TreeViewConfigurator-Datenbank

  • Importieren Sie die Tabelle tblNodes der Bibliotheksdatenbank in die Zieldatenbank und leeren Sie diese gegebenenfalls.

Außerdem benötigen Sie zwingend einen Verweis auf die Bibliothek Microsoft Office x.0 Object Library.

Den TreeView-Konfigurator an Bord holen

Der TreeView-Konfigurator tritt im Wesentlichen durch das Formular frmTreeViewHandler in Erscheinung. Dieses Formular erlaubt die vollständige Konfiguration eines oder mehrerer TreeViews. Das Formular steckt allerdings, genau wie die komplette Logik des TreeView-Konfigurators, in der Bibliotheksdatenbank TreeViewConfigurator.mde. Diese Datenbank enthält eine öffentliche Prozedur namens OpenTreeViewConf zum Anzeigen des TreeView-Konfigurator-Formulars. Sie können diese nun jeweils über das Direktfenster aufrufen, aber es gibt noch eine elegantere Lösung. Dazu legen Sie einfach ein neues Formular namens frmTreeViewHandler in der Zieldatenbank an. Fügen Sie diesem Formular lediglich eine Ereignisprozedur hinzu, die durch das Ereignis Beim Öffnen ausgelöst wird und die wie folgt aussieht:

Private Sub Form_Open(Cancel As Integer)
    OpenTreeViewConf _
    "{66EAB73D-990B-42DF-B28D-D06FFA989759}"
    Cancel = True
    End Sub

Diese Prozedur öffnet mit OpenTreeViewConf das Formular frmTreeViewConf in der Bibliotheksdatenbank. Die Angabe der GUID ist nötig, damit Sie den TreeView-Konfigurator für verschiedene Anwendungen nutzen können.

Der Konfigurator zeigt dann nur die TreeView-Daten an, die zur aktuellen Anwendung gehören. Vergeben Sie daher für jede Anwendung eine neue GUID. Durch das Einstellen des Parameters Cancel auf den Wert True wird das Öffnen des entsprechenden Formulars in der Zieldatenbank abgebrochen. Auf diese Weise öffnen Sie das Formular der Bibliotheksdatenbank so, als ob es sich selbst in der Zieldatenbank befinden würde (s. Bild 2).

pic019.png

Bild 2: Die Benutzeroberfläche des TreeView-Handlers

Grundgerüst

Legen Sie dann ein neues, leeres Formular an und speichern Sie es unter dem gewünschten Namen. Fügen Sie ein TreeView-Steuerelement und ein ImageList-Steuerelement hinzu und stellen Sie deren Namen auf ctlTreeView und ctlImageList ein. Ziehen Sie das TreeView-Steuerelement auf die gewünschte Größe. Das ImageList-Steuerelement platzieren Sie irgendwo – es erscheint ohnehin nicht in der Formularansicht.

Dann legen Sie eine Ereignisprozedur für das Ereignis Beim Laden des Formulars an. Dieses enthält die wesentlichen Schritte zum Füllen des TreeView-Steuerelements mit den gewünschten Daten:

Private Sub Form_Load()
    Set objTreeViewHandler = _
    New clsTreeViewHandler
    With objTreeViewHandler
    Set .ImageListInst = _
    Me!ctlImageList.Object
    Set .TreeViewInst = Me!ctlTreeView.Object
    .Appearance = ccFlat
    .LineStyle = tvwRootLines
    .Style = tvwTreelinesPlusMinusPictureText
    .Indentation = 5
    .InitTreeView 1
    .FillTree
    End With
    End Sub

Die hier referenzierte Objektvariable objTreeViewHandler deklarieren Sie wie folgt im Kopf des Klassenmoduls:

Dim WithEvents objTreeViewHandler As
clsTreeViewHandler

Die Prozedur erzeugt zunächst eine neue Instanz der Steuerungsklasse für das TreeView-Steuerelement. Dann weist sie den Eigenschaften der Steuerungsklasse Verweise auf das für Icons zu verwendende ImageList-Steuerelement sowie das TreeView-Steuerelement zu. Die weiteren Eigenschaften Appearance, LineStyle, Style und Indentation sorgen für die gewünschte Optik und entsprechen den gleichnamigen Eigenschaften des TreeView-Steuerelements. Interessant und notwendig sind die beiden letzten Anweisungen: InitTreeView initialisiert das TreeView-Steuerelement und FillTree füllt es mit den festgelegten Daten.

Speichern Sie dieses Formular nun unter dem Namen frmTreeView_Basis. Sie können es dann zum Nachvollziehen der folgenden Beispiele jeweils kopieren.

Sie brauchen es dann nur unter einem dem Beispiel entsprechenden Namen zu speichern und in der folgenden Zeile der Prozedur Form_Load den Platzhalter <ID> durch den im Formular frmTreeViewConf angezeigten Wert zu ersetzen:

.InitTreeView <ID>

Der Parameter der Methode InitTreeView entspricht der ID des im Formular frmTreeViewHandler festgelegten Baums. Das bedeutet: Sie können mehrere Bäume definieren und diese in verschiedenen Formularen anzeigen.

Ein Wechsel in die Formularansicht liefert nun lediglich die Meldung, dass noch keine TreeView-Konfiguration festgelegt wurde. Dies holen Sie nun nach, wobei dieser Beitrag verschiedene Konfigurationen vorstellt.

Kunden anzeigen

Öffnen Sie erstmalig das Formular frmTreeViewConf. Dieses fragt zunächst per InputBox den Namen des ersten anzulegenden TreeViews ab (s. Bild 3). Geben Sie hier einfach einen Namen ein, anhand dessen Sie das TreeView später identifizieren können – der Benutzer bekommt diese Bezeichnung nicht zu sehen.

pic014.png

Bild 3: Angabe des TreeView-Namens

Das erste Beispiel soll zeigen, wie Sie die Daten einer einfachen Tabelle im TreeView anzeigen. Dazu weisen Sie folgenden Eigenschaften des neuen TreeViewConf-Datensatzes die angegebenen Werte zu:

  • Tabelle/Abfrage: tblKunden
  • Basistabelle: tblKunden
  • Primärschlüssel: KundeID (kann aus dem Kombinationsfeld ausgewählt werden)
  • Schlüssel: beliebiger Wert, beispielsweise aa. Dieser dient zur eindeutigen Identifikation der TreeView-Elemente.
  • Elementtext: Kunde (Feld, dessen Wert im Baum als Text angezeigt werden soll – ebenfalls per Kombinationsfeld auswählbar)

Die Konfiguration ist fertig, nun kopieren Sie das Basisformular frmTreeView_Basis nach frmTreeView_NurKunden und stellen die ID in der oben angegegebenen Codezeile auf den oben im Formular frmTreeViewConf angegebenen Wert für Aktuelle ID: ein (in der Beispieldatenbank steht dort der Wert 7). Wenn Sie nun in die Entwurfsansicht wechseln, sollte der Baum wie in Bild 4 gefüllt werden.

pic001.png

Bild 4: Ein TreeView mit Kunden-Elementen, aber ohne Images

Images hinzufügen

Jeder Kunde soll durch das gleiche Bild repräsentiert werden. Sie benötigen dazu Bilddateien in einem gängigen Format, wir haben PNGs dazu verwendet. Alle Bilddateien, die im TreeView erscheinen sollen, speichern Sie in der Tabelle tblImages. Am einfachsten gelingt dies mit dem Tool Picture2OLE (www.acciu.de/picture2ole).

Die in der Tabelle tblImages gespeicherten Bilder können Sie über eines der beiden Kombinationsfelder der Eigenschaft Icon im Formular frmTreeViewConf auswählen. Mit dem linken der beiden Kombinationsfelder legen Sie ein Feld der unter Tabelle/Abfrage angegebenen Tabelle oder Abfrage fest, das den Namen einer Bilddatei liefern soll, mit dem rechten ein Standardbild für Elemente dieser Tabelle/Abfrage.

Die erste Variante ermöglicht, dass Sie für jeden Datensatz ein individuelles Icon anzeigen können. Das bietet sich beispielsweise an, wenn Sie männliche und weibliche Kunden mit unterschiedlichen Symbolen darstellen möchten.

Als Erstes testen wir die Variante mit dem fixen Icon für alle Datensätze der Hierarchie-Ebene des Baums. Wählen Sie einen Eintrag des rechten Kombinationsfelds der Eigenschaft Icon aus. Speichern Sie den Datensatz und öffnen Sie erneut das Formular frmTreeView_NurKunden. Das Ergebnis sieht schon besser aus (s. Bild 5).

pic002.png

Bild 5: Kunden mit Icon

Kunden mit Root-Knoten

Die Kunden-Elemente befinden sich auf der ersten Hierarchie-Ebene des TreeView-Steuerelements. Wenn Sie nicht nur Kunden, sondern noch weitere Elemente auf der gleichen Ebene unterbringen möchten, sollten Sie diese jeweils unterhalb eines Hauptknotens organisieren. Dies ist allein deshalb praktisch, weil sich so komplette Elementgruppen ausblenden lassen.

Fügen wir der TreeView-Konfiguration also nun einen Hauptknoten für die Kunden hinzu (Beispieldatenbank: frmTreeView_KundenMitRoot, TreeView-ID 9). Dazu legen Sie im Formular frmTreeViewConf einen neuen Datensatz an, der folgende Eigenschaften enthält:

  • Generische Ebene: Wahr
  • Tabelle/Abfrage: Hier eine eindeutige Bezeichnung für diese Ebene eingeben, beispielsweise KundenRoot.
  • Schlüssel: eindeutiger Wert aus zwei Zeichen, hier ab
  • Elementtext: anzuzeigender Wert, etwa Kunden
  • Icon: im zweiten Kombinationsfeld (also als Standardbilddatei) eine Bilddatei angeben, die dieser Knoten anzeigen soll

Fügen Sie eine weitere Tabelle mit der Schaltfläche Neue Tabelle hinzu. Tragen Sie für diese genau die gleichen Daten wie für tblKunden im ersten Beispiel ein.

Nun würde das Formular frmTreeView_Kunden den Eintrag Kunden auf der gleichen Ebene wie die Kundeneinträge selbst anzeigen. Damit die Kunden unterhalb dieses Eintrags erscheinen, bearbeiten Sie nun den zuerst angelegten Datensatz im Formular frmTreeViewConf. Dort legen Sie für die Eigenschaft Übergeordnete Tabelle schlicht und einfach den Namen des Wertes von Tabelle/Abfrage des Eintrags für den Kunden-Basisknoten fest, also KundenRoot. Außerdem aktivieren Sie die Option Alle anzeigen.

Kopieren Sie das Formular frmTreeView_Base nach frmTreeView_KundenMitRoot und legen Sie in der Ereignisprozedur Beim Laden die TreeView-ID aus dem TreeViewConf-Formular fest (in der Beispieldatenbank 9).

Beim Öffnen des Formulars frmTreeView_Kunden erscheint nun der minimierte Kunden-Knoten, den Sie wie in Bild 6 durch einen Mausklick auf das Plus-Zeichen erweitern können.

pic003.png

Bild 6: Kunden-Hauptknoten mit Untereinträgen

Sie können auch festlegen, dass das Kunden-Basiselement direkt beim Anzeigen des Formulars ausgeklappt wird. Dazu aktivieren Sie einfach das Kontrollkästchen rechts neben der Eigenschaft Expanded-Wert für die Tabelle/Abfrage KundenRoot im Formular frmTreeViewConf. Mit dem Kombinationsfeld links daneben können Sie wiederum ein Feld auswählen, das den individuellen Expanded-Wert für jeden einzelnen Knoten für eine Tabelle/Abfrage liefert. Sie haben dann die Möglichkeit, durch entsprechenden Code das Ein-/Ausklappen-Ereignis des TreeViewHandlers abzugreifen und den Expanded-Wert in der jeweiligen Tabelle zu speichern.

Eine weitere Ebene: Projekte

Nun soll das TreeView-Steuerelement Einträge aus einer per 1:n-Beziehung verknüpften Tabelle anzeigen, in diesem Fall tblProjekte (mit den Feldern ProjektID, Projektbezeichnung und KundeID). Die Datensätze dieser Tabelle werden über das Fremdschlüsselfeld KundeID mit den Datensätzen der Kundentabelle verknüpft.

Damit diese Datensätze im TreeView-Steuerelement unterhalb der Kunden-Datensätze angezeigt werden, erstellen Sie im TreeViewConf-Formular ein neues TreeView. In einer zusätzlich zu den bestehenden Tabellen-Ebenen angelegten Ebene im TreeView-Konfigurator legen Sie die folgenden Eigenschaften fest (in der Beispieldatenbank im Formular frmTreeView_KundenMitProjekten beziehungsweise TreeView-ID 10 zu finden):

  • Tabelle/Abfrage: tblProjekte
  • Basistabelle: tblProjekte
  • Übergeordnete Tabelle: tblKunden
  • Primärschlüssel: ProjektID
  • Fremdschlüssel: KundeID
  • Schlüssel: ac
  • Elementtext: Projektbezeichnung
  • Icon: box.png als Standardwert

Dadurch, dass Sie der Eigenschaft Übergeordnete Tabelle den Wert tblKunden und der Eigenschaft Fremdschlüssel den Wert KundeID zuweisen, erkennt der TreeView-Konfigurator automatisch, dass das TreeView-Steuerelement unterhalb eines Elements aus der Tabelle tblKunden alle Elemente der Tabelle tblProjekte anzeigen soll, deren Fremdschlüsselfeld KundeID dem gleichnamigen Primärschlüsselfeld der übergeordneten Tabelle entspricht. Das Ergebnis sieht schließlich wie in Bild 7 aus.

pic004.png

Bild 7: Tabellen einer 1:n-Beziehung im TreeView

Zwischenelement für Projekte

Nun kann es auch beim Kunden-Element vorkommen, dass Sie diesem nicht nur die Projekte des Kunden, sondern beispielsweise auch seine Ansprechpartner unterordnen möchten. ähnlich wie beim Root-Element für die Kunden wäre auch hier ein Zwischenelement wie Projekte (beziehungsweise Ansprechpartner) sinnvoll. Dieses legen Sie in einer neuen Ebene an, die folgende Eigenschaften erhält (siehe Formular frmTreeView_KundenMitProjektenRoot, TreeView-ID 11):

  • Generische Ebene: Wahr
  • Tabelle/Abfrage: ProjekteRoot
  • Übergeordnete Tabelle: tblKunden
  • Alle anzeigen: Wahr
  • Schlüssel: ad
  • Elementtext: Projekte
  • Icon: box.png

Außerdem müssen Sie wieder, wie schon bei den Kunden und dem Kunden-Root-Element, den Eintrag für die Tabelle tblProjekte anpassen. Dort wählen Sie unter Übergeordnete Tabelle den Eintrag KundenRoot aus.

Zwischen Kunden und Projekte schiebt sich nun noch jeweils ein Projekte-Element (s. Bild 8).

pic005.png

Bild 8: Projekte mit Rootknoten

Daten aus m:n-Beziehungen

Wenn Sie den jeweiligen Projekten noch die Mitarbeiter zuordnen möchten, die sich mit einem Projekt beschäftigen, benötigen Sie eine m:n-Beziehung zwischen der Tabelle tblProjekte und einer weiteren Tabelle namens tblMitarbeiter mit den beiden Feldern MitarbeiterID und Mitarbeiter (dieses enthält den kompletten Namen des Mitarbeiters in der Form <Nachname>, <Vorname>). Die Verknüpfungstabelle heißt tblMitarbeiterProjekte und enthält neben dem Primärschlüsselfeld MitarbeiterProjektID zwei Fremdschlüsselfelder namens MitarbeiterID und ProjektID.

Um nun unter jedem Projekt die richtigen Mitarbeiter anzuzeigen, benötigen Sie eine Abfrage, welche die benötigten Felder aus den beiden Tabellen tblMitarbeiterProjekte und tblMitarbeiter zusammenführt (s. Bild 9).

pic006.png

Bild 9: Zuordnung von Mitarbeitern zu Projekten

Sie benötigen folgende Felder aus den beiden Tabellen: Aus der Tabelle tblMitarbeiterProjekte benötigen Sie das Feld ProjektID, um die Mitarbeiter-Elemente dem jeweiligen Projekt-Element zuordnen zu können. Außerdem benötigen Sie das Primärschlüsselfeld der Verknüpfungstabelle, MitarbeiterProjektID. Wenn über das TreeView-Steuerelement ein Mitarbeiter von einem Projekt abgezogen werden soll, darf schließlich nicht der Mitarbeiter gelöscht werden, sondern nur der Datensatz der Tabelle tblMitarbeiterProjekte, der den Mitarbeiter mit dem Projekt verknüpft. Außerdem benötigen Sie aus der Tabelle tblMitarbeiter die Bezeichnung des jeweiligen Mitarbeiters und, egal aus welcher Tabelle, das Feld MitarbeiterID. Darüber können Sie bei einem Klick auf einen Mitarbeiter-Knoten gegebenenfalls Details zu diesem Mitarbeiter anzeigen.

Für dieses Beispiel verwenden wir in der Beispieldatenbank das Formular frmTreeView_ProjekteKundenMitarbeiter sowie die TreeView-ID 11.

Bei der Zuweisung der Werte für die Eigenschaften ergeben sich einige Neuerungen gegenüber den vorherigen Beispielen:

  • Tabelle/Abfrage: qryMitarbeiterProjekte, als die Abfrage, die alle benötigten Werte liefert.
  • Basistabelle: Abweichend von Tabelle/Abfrage landet hier die Tabelle tblMitarbeiterProjekte. Faustregel: Diese Eigenschaft erwartet die Tabelle, aus der gegebenenfalls Datensätze gelöscht werden, um ein Element aus dem TreeView zu entfernen – hier also die Verknüpfungstabelle.
  • Übergeordnete Tabelle: tblProjekte
  • Primärschlüssel: MitarbeiterID (also das Feld, über das Sie Detaildaten in weiteren Formularen anzeigen können)
  • Fremdschlüssel: ProjektID
  • Primärschlüsselfeld der Basistabelle: MitarbeiterProjektID, als der Primärschlüssel aus der Tabelle, aus der gegebenenfalls Werte gelöscht werden sollen.
  • Schlüssel: ae
  • Elementtext: Mitarbeiter
  • Icon: user.png
  • m:n-Beziehung: Aktivieren

Das Ergebnis finden Sie in Bild 10.

pic007.png

Bild 10: Kunden, Projekte und per m:n-Beziehung verknüpfte Mitarbeiter

Reflexive Beziehungen

Auch vor Daten aus reflexiven Beziehungen, also solchen, bei denen die Datensätze einer Tabelle mit einem oder mehreren anderen Datensätzen der gleichen Tabelle verknüpft werden, macht der TreeView-Konfigurator nicht Halt.

Als Test hängen wir an unser Beispiel die Hierarchie der Mitarbeiter an. Diese könnte man über ein zusätzliches Fremdschlüsselfeld in der Tabelle tblMitarbeiter realisieren, aber günstiger ist es, eine m:n-Beziehung zwischen den Primärschlüsselfeldern zweier in Beziehung stehender Mitarbeiter herzustellen.

Die m:n-Beziehung heißt tblVorgesetzteMitarbeiter und enthält zwei Fremdschlüsselfelder namens VorgesetzterID und UntergebenerID, die beide mit dem Feld MitarbeiterID der Tabelle tblMitarbeiter verknüpft sind (s. Bild 11).

pic008.png

Bild 11: Reflexive Beziehung zwischen Vorgesetzten und Untergebenen

Wie können wir diese reflexive Beziehung nun mithilfe des TreeView-Konfigurators darstellen

Als Erstes fügen Sie dem Baum einen weiteren Root-Knoten namens MitarbeiterRoot und mit dem Text Mitarbeiter hinzu, der auf der gleichen Ebene wie der Root-Knoten Kunden liegt.

In der Beispieldatenbank finden Sie das Formular unter dem Namen frmTreeView_VorgesetzteUntergebene, die TreeView-ID lautet 12.

Das Mitarbeiter-Root-Element hat folgende Eigenschaften:

  • Generische Ebene: Wahr
  • Tabelle/Abfrage: MitarbeiterRoot
  • Schlüssel: af
  • Elementtext: Mitarbeiter (als Standardwert)
  • Icon: users.png (als Standardwert)

Reihenfolge hinzufügen

Das TreeView-Steuerelement zeigt nun zwei Root-Elemente an, Kunden und Mitarbeiter. Wenn Sie die Reihenfolge fest vorgeben wollen, weisen Sie der Eigenschaft Reihenfolge beider Root-Elemente im TreeView-Konfigurator entsprechende Zahlenwerte zu, beispielsweise 1 und 2.

Darstellung reflexiver Elemente

Für die Darstellung reflexiver Elemente brauchen wir insgesamt drei Einträge im TreeView-Konfigurator: Einer soll alle Mitarbeiter liefern, die keinen Vorgesetzten haben.

Diese sind selbst Vorgesetzte und landen dementsprechend direkt in der ersten Ebene unterhalb des generischen Mitarbeiter-Elements.

Der zweite Eintrag im TreeView-Konfigurator bildet die erste Ebene der reflexiven Beziehung unterhalb der obersten Ebene ab. Die dritte bedient schließlich alle weiteren Ebenen.

Erstellen Sie zunächst eine Abfrage für die oberste Ebene. Diese sieht wie in Bild 12 aus. Sie enthält die Tabellen tblMitarbeiter und tblVorgesetzteUntergebene.

pic010.png

Bild 13: TreeView-Steuerelement mit einem Vorgesetzten

Damit diese nur Vorgesetzte anzeigt, also Mitarbeiter, die in der Tabelle tblVorgesetzteMitarbeiter nirgends als Untergebener aufgeführt werden, nehmen Sie zwei Einstellungen vor:

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