Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.
Im Beitrag „COM-Add-In für den VBA-Editor“ haben wir uns zunächst darum gekümmert, überhaupt eine COM-DLL zu programmieren und diese so in die Registry einzutragen, dass sie beim Starten des VBA-Editors geladen wird und die dort angelegten Ereignisprozeduren ausgelöst wurden. Damit sind wir noch lange nicht fertig. Im vorliegenden Artikel schauen wir uns an, wie Sie dem VBA-Editor Menüeinträge für den Aufruf der im COM-Add-In enthaltenen Funktionen hinzufügen – und zwar für die Menüleiste, die Symbolleiste sowie für Kontextmenüs.
Vorbereitung
Als Vorbereitung für die Beispiele dieses Artikels führen Sie die Schritte aus dem Artikel COM-Add-In für den VBA-Editor oder verwenden das dort enthaltene Beispielprojekt als Ausgangspunkt. Wir haben das Projekt einfach neu erstellt, und zwar unter dem Namen COMAddInMenues, und eine neue Registrierungsdatei namens COMAddInMenues.reg und eine neue GUID erzeugt, die wir an den entsprechenden Stellen eingefügt haben (also in der .reg-Datei und über der Connect-Klasse). Achten Sie auch darauf, den Namen COMAddInMenues an den entsprechenden Stellen der .reg-Datei einzufügen. Die Datei sieht für das neue Add-In wie in Listing 1 aus.
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE\6.0\Addins\COMAddInMenues.Connect] "CommandLineSafe"=dword:00000000 "Description"="Grundgerüst für ein COM-Add-In für den VBA-Editor" "LoadBehavior"=dword:00000003 "FriendlyName"="COMAddInMenues" [HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{ABA0B519-CB8C-4A03-9815-D99DFE3312C9}] @="COMAddInMenues.Connect" [HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{ABA0B519-CB8C-4A03-9815-D99DFE3312C9}\Implemented Categories] [HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{ABA0B519-CB8C-4A03-9815-D99DFE3312C9}\InprocServer32] @="mscoree.dll" "ThreadingModel"="Both" "Class"="COMAddInMenues.Connect" "Assembly"="COMAddInMenues" "RuntimeVersion"="v2.0.50727" "CodeBase"="file:///C:\...\COMAddInMenues.dll" [HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{ABA0B519-CB8C-4A03-9815-D99DFE3312C9}\ProgId] @="COMAddInMenues.Connect"
Listing 1: Inhalt der Datei für die Registry
Das Ladeverhalten stellen wir gleich auf den Wert 3 ein, damit das Add-In beim Starten des VBA-Editors aufgerufen wird und wir das Ladeverhalten nicht erst noch im Add-In-Manager anpassen müssen.
Die übrigen Schritte wie das Hinzufügen der Verweise und die benötigten Einstellungen haben wir im Artikel COM-Add-In für den VBA-Editor beschrieben.
Denken Sie vor dem Erstellen des Projekts immer daran, Visual Studio im Administrator-Modus zu öffnen, da das COM-Add-In sonst nicht erstellt werden kann.
Zugriff auf die eingebauten Menüs
Bevor wir eigene Menüpunkte anlegen können, wollen wir uns zunächst ansehen, wie wir überhaupt auf die Menüs des VBA-Editors zugreifen können.
Die Menüs und die für den Zugriff benötigten Objekte wie die CommandBars-Auflistung und das CommandBar-Objekt sowie deren untergeordnete Elemente und Eigenschaften sind Bestandteil der Office-Bibliothek. Diese fügen Sie über den Verweis-Manager hinzu, indem Sie nach dem Schlüsselwort Office suchen und dann den Eintrag aus Bild 1 auswählen.
Bild 1: Hinzufügen eines Verweises auf die Office-Bibliothek
Außerdem importieren wir den passenden Namespace in die Klasse Connect.vb:
Imports Microsoft.Office.Core
Die Befehle, die sich beim Start des COM-Add-Ins mit den Menüeinträgen befassen, wollen wir gleich in eine eigene Prozedur auslagen. Diese rufen wir gleich beim Start des COM-Add-Ins in der Methode OnConnection auf:
Public Sub OnConnection(Application As Object, _ ConnectMode As ext_ConnectMode, _ AddInInst As Object, _ ByRef custom As Array) _ Implements IDTExtensibility2.OnConnection _VBE = DirectCast(Application, VBE) _AddIn = DirectCast(AddInInst, AddIn) Select Case ConnectMode Case Extensibility.ext_ConnectMode.ext_cm_Startup CommandBarsAusgeben() End Select End Sub
Als Erstes wollen wir einfach die Auflistung der CommandBar-Elemente durchlaufen und diese in Meldungsfenstern ausgeben. Dazu füllen wir die Prozedur CommandBarsAusgeben wie folgt:
Private Sub CommandBarsAusgeben() Dim cbrs As CommandBars Dim cbr As CommandBar cbrs = _VBE.CommandBars For Each cbr In cbrs MessageBox.Show(cbr.Name) Next End Sub
Diese Prozedur verwendet die bereits beim Laden des COM-Add-Ins mit einem Verweis auf das Objekt VBE gefüllte Member-Variablen _VBE. VBE steht stellvertretend für das Objektmodell des VBA-Editors.
Diese stellt unter anderem die Auflistung CommandBars bereit, die alle CommandBar-Elemente des VBA-Editors enthält. Die Variable cbrs mit dem Typ CommandBars füllen wir mit einem Verweis auf die CommandBars-Auflistung des VBE-Objekts. In einer For Each-Schleife durchlaufen wir dann alle Elemente dieser Auflistung und geben den Namen des aktuellen Elements in einer Meldung aus.
Debuggen des Add-Ins
Das ist allerdings nicht wirklich komfortabel – immerhin gibt es einige Menüs in der Auflistung CommandBars. Wir wollen diese lieber in Visual Studio ausgeben, statt für jedes Menü ein neues Meldungsfenster zu öffnen. Wenn wir in Visual Studio den Menüeintrag Debuggen|Debugging starten… wählen, führt dies allerdings zur Meldung aus Bild 2.
Bild 2: Fehlermeldung beim Versuch, das Projekt zu debuggen
Um dies zu ändern, müssen wir in den Eigenschaften des Projekts eine Anwendung festlegen, die zusammen mit dem Add-In gestartet wird. Das Add-In selbst ist nämlich keine ausführbare Datei. Wir wollen das Add-In mit dem VBA-Editor unter Access testen, also legen wir Access als Startanwendung fest.
Dazu öffnen Sie die Eigenschaften des Projekts und wechseln dort zum Bereich Debuggen. Hier wählen Sie unter Projekt starten die Option Externes Programm starten aus und wählen über den mit der Schaltfläche Durchsuchen… zu öffnenden Dialog die Datei MSAccess.Exe aus (siehe Bild 3).
Bild 3: Startanwendung festlegen
Danach können Sie mit dem Menübefehl Debuggen|Debugging starten das Debuggen beginnen. Visual Studio startet dann Microsoft Access und wird, wenn Sie den VBA-Editor von Access aus aufrufen, die für das Laden des Add-Ins bestimmten Ereignisse auslösen. Sie können nun also beispielsweise Haltepunkte im Code platzieren und den Code so schrittweise durchlaufen. Beenden Sie das Debugging von Visual Studio aus, wird die gestartete Instanz von Visual Studio ebenfalls beendet.
Gegebenenfalls stoßen Sie dabei auf eine Fehlermeldung, dass die DLL nicht erzeugt werden konnte. Dies kann der Fall sein, wenn Sie bereits zuvor den VBA-Editor für eine Anwendung geöffnet haben und diese die bestehende DLL referenziert hat. Visual Studio kann diese dann nicht neu erstellen.
Wenn wir den Befehl in der Schleife wie folgt ändern, erhalten wir die Liste aller Menüs des VBA-Editors wie in Bild 4:
Bild 4: Ausgabe der Menüs des VBA-Editors
For Each cbr In cbrs Debug.Print(cbr.Name) Next
Nun erweitern wir die Schleife so, dass auch noch die Steuer-elemente eines jeden Menüs ausgeben werden. Dazu deklarieren wir eine Variable für die Steuer-elemente mit dem Typ CommandBarControl:
Dim cbc As CommandBarControl
In der Schleife fügen wir eine weitere Schleife über alle Elemente der Controls-Auflistung hinzu und geben die enthaltenen Elemente ebenfalls im Direktbereich von Visual Studio aus:
For Each cbr In cbrs Debug.Print(cbr.Name) For Each cbc In cbr.Controls Debug.Print(" " + cbc.Caption) Next Next
Für den Eintrag Menüleiste sieht das Ergebnis etwa wie folgt aus:
Menüleiste &Datei &Bearbeiten ... Add-&Ins &Fenster &
Genau genommen handelt es sich hierbei gar nicht um Schaltflächen, sondern um Untermenüs, die wiederum Control-Elemente enthalten – hier finden sich dann die eigentlichen Befehle.
Eine weitere Schleife wollen wir nun nicht mehr unterbringen, das System sollte nun verständlich sein.
Menü hinzufügen oder nur Steuerelemente
Wir können nun eigenen Menüs hinzufügen, bestehenden Menüs neue Untermenüs zuweisen oder auch bestehenden und neuen Menüs neue Steuer-elemente zuweisen. In der Regel werden wir jedoch neue Steuer-elemente zu bestehenden Menüs hinzufügen, um diese um die Funktionen des COM-Add-Ins zu erweitern.
Steuerelement hinzufügen
Dazu müssen wir zunächst einmal herausfinden, welchem Menü wir unseren Befehl hinzufügen wollen. In diesem Fall wollen wir, da wir ja noch keinen konkreten Anwendungszweck haben, einfach einmal einen Befehl zum Menüpunkt Add-Ins hinzufügen.
Damit es nicht zu leicht wird, soll dieses Menü noch ein Untermenü erhalten, dem wir dann unsere Schaltfläche hinzufügen. Gerade beim Auflisten des eingebauten Menüs namens Menüleiste haben wir ja bereits den Namen ermittelt.
Diesen können wir nun zum Referenzieren des entsprechenden CommandBar-Elements verwenden. Darunter finden wir das Untermenü namens Add-&Ins, das wir ebenfalls referenzieren. Schließlich legen wir darin mit der Add-Methode der Controls-Auflistung ein neues Unterelement des Typs msoControlPopup an, was dem Untermenü entspricht, und weisen diesem die Beschriftung Mein Add-In zu.
Außerdem soll vor diesem Untermenü ein Trennstrich eingefügt werden, was wir mit dem Wert True für die Eigenschaft BeginGroup erreichen:
Private Sub SteuerelementHinzufuegen() Dim cbr As CommandBar Dim cbrAddIns As CommandBarPopup = Nothing Dim cbrSub As CommandBarPopup = Nothing cbr = _VBE.CommandBars("Menüleiste") cbrAddIns = cbr.Controls.Item("Add-&Ins") cbrSub = cbrAddIns.Controls.Add(MsoControlType. msoControlPopup) With cbrSub .Caption = "Mein Add-In" .BeginGroup = True End With End Sub
Den Aufruf dieser Methode fügen wir schließlich noch der Ereignismethode OnStartupComplete zu:
Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete SteuerelementHinzufuegen() End Sub
Danach starten wir das Projekt, was automatisch Access öffnet, und laden dann eine Datenbank, für die wir den VBA-Editor öffnen. Das Add-Ins-Menü sieht dann nach dem Aufklappen wie in Bild 5 aus. Dieses zeigt dann natürlich noch keine Befehle an, da wir noch keine hinzugefügt haben.
Bild 5: Unser neues Untermenü
Schaltfläche zum Untermenü hinzufügen
Die Schaltfläche zum Ausführen eines benutzerdefinierten Befehls fügen wir nun hinzu. Dazu deklarieren wir zunächst eine Variable namens cbc mit dem Typ CommandBarButton in der Methode SteuerelementHinzufuegen. Diese fügen wir über die Add-Methode der Controls-Auflistung des soeben erstellten Untermenüs aus cbrSub hinzu und legen dabei den Typ des Steuerelements auf msoControlButton fest. Schließlich füllen wir die Eigenschaft Caption mit dem Wert Meine Schaltfläche:
Private Sub SteuerelementHinzufuegen() ... Dim cbc As CommandBarButton = Nothing ... With cbrSub ... cbc = .Controls.Add(MsoControlType.msoControlButton) With cbc .Caption = "Meine Schaltfläche" End With End With End Sub
Die Schaltfläche erscheint nun so wie in Bild 6.
Bild 6: Neue Schaltfläche im Untermenü
Schaltfläche mit Funktion versehen
Nun soll die Schaltfläche auch noch eine Aufgaben ausführen – in diesem Fall beispielsweise einfach das Anzeigen eines Meldungsfensters. Dazu müssen wir irgendwie festlegen, dass wir für das mit cbc deklarierte Element Ereignisse implementieren können.
Dazu versehen wir die Deklaration der Variablen mit dem zusätzlichen Schlüsselwort WithEvents.
Eine solche Deklaration ist allerdings innerhalb einer Methode unzulässig, die Variable muss daher unabhängig von der Methode deklariert werden. Wir verschieben die folgende Zeile daher in den allgemeinen Teil der Klasse:
Dim WithEvents cbc As CommandBarButton = Nothing
Das Anlegen der Ereignisprozedur, die beim Anklicken des Menüeintrags ausgelöst wird, legen wir nun auch auf einfache Weise an.
Dazu wählen Sie im mittleren Kombinationsfeld oben im Codefenster den Eintrag cbc aus und selektieren dann im rechten Kombinationsfeld den Eintrag für die gewünschte Ereignismethode – in diesem Fall gibt es nur eine einzige Auswahlmöglichkeit, nämlich Click (siehe Bild 7).
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
Testzugang
eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel
diesen und alle anderen Artikel mit dem Jahresabo