Menüs für das COM-Add-In für den VBA-Editor

Wenn Sie ein Abonnement des Magazins 'Access im Unternehmen' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

Menüs für das COM-Add-In für den VBA-Editor

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_USERSoftwareMicrosoftVBAVBE6.0AddinsCOMAddInMenues.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_ROOTWOW6432NodeCLSID{ABA0B519-CB8C-4A03-9815-D99DFE3312C9}]
@="COMAddInMenues.Connect"
[HKEY_CLASSES_ROOTWOW6432NodeCLSID{ABA0B519-CB8C-4A03-9815-D99DFE3312C9}Implemented Categories]
[HKEY_CLASSES_ROOTWOW6432NodeCLSID{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_ROOTWOW6432NodeCLSID{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.

Hinzufügen eines Verweises auf die Office-Bibliothek

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.

Fehlermeldung beim Versuch, das Projekt zu debuggen

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).

Startanwendung festlegen

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:

Ausgabe der Menüs des VBA-Editors

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

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Ich habe die Datenschutzbestimmungen zur Kenntnis genommen.