Wenn man das TreeView-Steuerelement professioneller nutzt, programmiert man unter anderem Ereignisse, die durch das Anklicken von Elementen ausgelöst werden. Damit kann man Ereignisprozeduren auslösen, die beispielsweise Daten zum angeklickten Element in einem Unterformular anzeigen oder man blendet ein Kontextmenü zum jeweils angeklickten Element mit weiteren Optionen ein. Dazu ist es notwendig, zu identifizieren, auf welches Element der Benutzer geklickt hat. Die notwendigen Informationen liefern die Parameter der Prozeduren, das Ermitteln des angeklickten Elements erledigt man mit einer bestimmten Funktion. Seit Kurzem erreichen uns allerdings Meldungen von Lesern, bei denen dies nicht mehr zuverlässig funktioniert: Es werden keine Kontextmenüs mehr angezeigt und auch das Anklicken gelingt nicht mehr wie gewünscht. Interessanterweise tritt das Problem nur bei Verwendung von Office 365 auf. Wir schauen uns in diesem Beitrag an, woher das Problem rührt und wie Sie es lösen können.
Vorbereitung
Für die folgenden Experimente legen wir in einem neuen, leeren Formular einfach ein TreeView-Steuerelement namens ctlTreeView an.
Dazu wählen wir im Ribbon den Befehl Formularentwurf|Steuerelemente|ActiveX-Steuerelemente aus (siehe Bild 1).
Bild 1: ActiveX-Steuerelement hinzufügen
Dies öffnet den Dialog ActiveX-Steuerelement einfügen, wo wir den Eintrag Microsoft TreeView Control, version 6.0 auswählen (siehe Bild 2).
Bild 2: TreeView-Steuerelement selektieren
Danach sehen wir das neue TreeView-Steuerelement im Formular und passen seine Größe entsprechend an (siehe Bild 3). Damit können wir zu den Feinheiten der Referenzierung und Programmierung übergehen.
Bild 3: TreeView-Steuerelement nach dem Einbau
Nach dem Einfügen des TreeView-Steuerelements passen wir noch seinen Namen auf ctlTreeView an.
TreeView als Steuerelement oder als Objektvariable referenzieren
Es gibt zwei Wege, wie man ein TreeView-Steuerelement per VBA referenzieren kann. Der erste ist, dieses wie bei den eingebauten Steuerelementen einfach über das Schlüsselwort Me in Verbindung mit dem Steuerelementnamen zu referenzieren, hier also ctlTreeView. Wenn wir dies im VBA-Editor erledigen und einen weiteren Punkt anfügen, um per IntelliSense auf die Methoden und Eigenschaften des TreeView-Steuerelements zuzugreifen, erhalten wir das Ergebnis aus Bild 4. Hier erkennen wir, dass wir nur die allgemeinen Eigenschaften von Steuerelementen anwählen können, nicht jedoch die speziellen Elemente des TreeView-Steuerelements.
Bild 4: Referenzieren des Steuerelements
Dazu müssen wir eine Objektvariable anlegen, die wir wie folgt deklarieren:
Dim objTreeView As MSCOMCTLLib.TreeView
Diese Variable füllen wir wie folgt:
Set objTreeView = Me!ctlTreeView.Object
Wir können das TreeView-Steuerelement nicht direkt über Me!ctlTreeView referenzieren, weil wir damit nur die Hülle des Steuerelements referenzieren würden. Diese hat den Datentyp CustomControl. Dies können wir belegen, indem wir zuerst den Typ von ctlTreeView ausgeben:
Debug.Print TypeName(Me!ctlTreeView)
CustomControl
Erst über das Object-Element erhalten wir den gesuchten Typ:
Debug.Print TypeName(Me!ctlTreeView.Object)
TreeView
Mit der Referenzierung über die Objektvariable objTreeView erhalten wir schließlich auch die TreeView-spezifischen Eigenschaften und Methoden per IntelliSense (siehe Bild 5).
Bild 5: Referenzieren des TreeView-Steuerelements per Objektvariable
Sie sehen: Ein Grund, das TreeView-Steuerelement nicht über das als Container verwendete Steuerelement CustomControl, sondern über das darin enthaltene TreeView-Steuerelement zu referenzieren, erlaubt den Zugriff auf die Eigenschaften und Methoden per IntelliSense.
Verwendung von Ereignissen
Wir wollen exemplarisch das Ereignis MouseDown verwenden, weil es das Problem verdeutlicht. Wir können das Ereignis auf zwei Arten in Form einer Ereignisprozedur implementieren. Bei der ersten verwenden wir die Ereignisse des Steuerelements ctlTreeView. Um das Ereignis anzulegen, wählen wir im Codefenster des Klassenmoduls des Formulars oben links den Eintrag für das TreeView-Steuerelement ctlTreeView aus und aus der nun aufgeklappten Liste auf der rechten Seite den Eintrag MouseDown. Die automatisch hinzugefügte Ereignisprozedur ctlTreeView_Updated können wir wieder löschen (siehe Bild 6).
Bild 6: Anlegen des MouseDown-Ereignisses für ctlTreeView
Die neue Ereignisprozedur hat die folgende Signatur:
Private Sub ctlTreeView_MouseDown( _ ByVal Button As Integer, _ ByVal Shift As Integer, _ ByVal x As Long, _ ByVal y As Long)
Button liefert einen Hinweis, ob die linke oder rechte Maustaste gedrückt wurde, Shift gibt an, ob eine der Tasten Alt, Strg oder Umschalt beim Betätigen der Maustaste gehalten wurde.
Mit x und y erhalten wir die Koordinaten, an denen der Mausklick erfolgte. Wie es unter Access üblich ist, werden diese Koordinaten im Format Twips geliefert.
Ereignis für die Objektvariable anlegen
Wir können das Ereignis allerdings auch für die oben vorgestellte Objektvariable objTreeView anlegen. Dazu müssen wir die Deklaration dieser Variablen nur aus der Prozedur Form_Load herausholen und in den allgemeinen Teil des Moduls verschieben (siehe Bild 7). Außerdem fügen wir das Schlüsselwort WithEvents hinzu, damit der VBA-Editor weiß, dass wir in diesem Klassenmodul Ereignisse für dieses Element implementieren können wollen.
Bild 7: Änderung der Deklaration von objTreeView
Damit können wir nun wie zuvor für ctlTreeView auch für objTreeView die Ereignisse über die Auswahlfelder oben im Codefenster hinzufügen (siehe Bild 8).
Bild 8: Anlegen des MouseDown-Ereignisses für die Objektvariable objTreeView
Das erledigen wir wie zuvor und sehen uns dann die Signatur des MouseDown-Ereignisses für die Objektvariable objTreeView an:
Private Sub objTreeView_MouseDown( _ ByVal Button As Integer, _ ByVal Shift As Integer, _ ByVal x As stdole.OLE_XPOS_PIXELS, _ ByVal y As stdole.OLE_YPOS_PIXELS)
Die Signatur ist bezüglich der Anzahl und der Benennung der Elemente identisch, jedoch unterscheidet sich der Datentyp bei den Parametern x und y. Während wir es zuvor mit Long-Werten zu tun hatten, finden wir nun den Datentyp stdole.OLOE_XPOS_PIXELS vor. Lassen wir uns innerhalb dieses Ereignisse jedoch einmal den Datentyp mit Typename ausgeben, erhalten wir hier ebenfalls Long als Datentyp. Allerdings sehen wir, dass der Datentyp die Zeichenkette PIXELS enthält, war darauf hindeutet, dass hier nicht Twips wie bei der gleichnamigen Ereignisprozedur für das Steuerelement geliefert werden, sondern Pixel.
Die Frage ist nun: Ist das auch der Fall?
Dazu fügen wir dem Formular vier Textfelder namens txtCtlX, txtCtlY, txtObjX und txtObjY hinzu (siehe Bild 9). Die Textfelder füllen wir beim Auslösen der Ereignisprozeduren beim Ereignis MouseDown mit den Werten für die Parameter x und y:
Bild 9: Steuerelemente zum Anzeigen der x- und y-Werte für die beiden Ereignisprozeduren
Private Sub ctlTreeView_MouseDown(_ ByVal Button As Integer, _ ByVal Shift As Integer, _ ByVal x As Long, ByVal y As Long) Me!txtCtlX = x Me!txtCtlY = y End Sub Private Sub objTreeView_MouseDown( _ ByVal Button As Integer, ByVal Shift As Integer, _ ByVal x As stdole.OLE_XPOS_PIXELS, _ ByVal y As stdole.OLE_YPOS_PIXELS) Me!txtObjX = x Me!txtObjY = y End Sub
Und hier wird es spannend: Unter Access in der Version von Office 365 erhalten wir für beide Ereignisprozeduren beim einem Klick in die rechte, untere Ecke unterschiedliche Werte für die Parameter x und y (siehe Bild 10).
Bild 10: Ergebnis beim Anklicken unter Office 365
Das Ereignis für ctlTreeView liefert die Werte in der Einheit Twips, das Ereignis für objTreeView in der Einheit Pixel.
Richtig interessant wird es, wenn wir das gleiche Formular in Access 2010 öffnen (Gleiches gilt für Access 2013 und 2016). Hier erhalten wir für das Ereignis MouseOver des Steuerelements ctlTreeView und der Objektvariablen objTreeView beim Anklicken des Steuerelements in der rechten, unteren Ecke alle Werte in der Einheit Twips (siehe Bild 11).
Bild 11: Ergebnis beim Anklicken unter Access 2010
Aber warum sollte das ein Problem sein? Das schauen wir uns im Anschluss an.
Probleme durch unterschiedliche Einheiten
Wir füllen nun das TreeView-Steuerelement beim Laden des Formulars mit drei einfachen Node-Elementen:
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