Klassenprogrammierung mit COM-Add-In vereinfachen

Lies in den Artikel rein und unten bekommst Du ein unschlagbares Angebot!

Menüeintrag unseres COM-Add-Ins

Bild 1: Menüeintrag unseres COM-Add-Ins

Im Artikel “VBA-Editor: Klasseneigenschaften per Mausklick” (www.vbentwickler.de/422) haben wir eine Prozedur vorgestellt, mit denen man aus einer einfachen Variablendeklaration innerhalb eines Klassenmoduls eine private Membervariable und jeweils eine Property Get-Methode und eine Property Set/Let-Methode erzeugen kann. Der einzige Haken bei dieser Lösung ist, dass man diese bisher noch über den Direktbereich aufrufen musste. Da das nicht sonderlich komfortabel ist, stellen wir in diesem Artikel eine Lösung vor, bei der wir mit twinBASIC ein COM-Add-In für den VBA-Editor erstellen, mit dem wir die Funktion aus dem oben genannten Artikel über die Menüleiste, die Symbolleiste oder auch über das Kontextmenü des VBA-Editors aufrufen kann.

Wir bauen hier auf den Vorbereitungen auf, die wir im Artikel twinBASIC: COM-Add-In für den VBA-Editor (www.vbentwickler.de/421) vorgestellt haben. Hier haben wir ein Basis-COM-Add-In für den VBA-Editor vorgestellt, das einfach nur ein paar Dummy-Einträge im Menü und im Kontextmenü anzeigt, die Meldungsfenster liefern. Den ersten sehen wir in Bild 1.

Menüeintrag unseres COM-Add-Ins

Bild 1: Menüeintrag unseres COM-Add-Ins

Den zweiten Eintrag, den wir im Kontextmenü untergebracht haben, finden wir im Kontextmenü in Bild 2 ganz unten.

Menüeintrag im Kontextmenü

Bild 2: Menüeintrag im Kontextmenü

In der Symbolleiste haben wir noch keinen Eintrag untergebracht. Auch das wollen wir gegebenenfalls noch erledigen. Erst einmal schauen wir uns jedoch die zu programmierende Funktion an – wo im Menü wir diese optimal unterbringen.

Umwandeln von Variablen in Property Get/Let/Set

Die Aufgabe lautet, die Prozedur, die wir im oben genannten Artikel entwickelt haben, über ein COM-Add-In für den VBA-Editor verfügbar zu machen. Diese Aufgabe ist einfach – wir brauchen eigentlich nur unsere Menüpunkte umzubenennen und diesen den Aufruf der gewünschten Prozedur hinzuzufügen.

Allerdings wollen wir das mit Bedacht tun, damit wir den bestmöglichen Ort für den Menüeintrag finden. Es geht darum, eine oder mehrere Variablen im Code eines Klassenmoduls zu markieren und dann die Prozedur VariableToProperty aufzurufen. Diese holt sich die aktuelle Markierung und passt den gefundenen Code entsprechend an.

Um diese Funktion nach dem Selektieren der zu bearbeitenden Code-Passagen aufzurufen: Was wäre der geeignete Ort? Wir wollen mit möglichst wenig Klicks und möglichst wenig Mausmetern zum Ziel kommen. Wenn wir also einen Eintrag im Menü verwenden, sollte dieser direkt erreichbar sein. Dazu bietet sicher eher die Symbolleiste an, in der wir den Befehl über ein geeignetes Icon anbieten können. Allerdings muss man für eine solche erklärungsbedürftige Aufgabe erst einmal ein passendes Icon finden.

Die zweite Möglichkeit ist, diesen Befehl in der Menüleiste selbst unterzubringen. Hier sollten wir allerdings keine Befehle in der Hauptmenüleiste unterbringen, sondern vielleicht einen Hauptmenüpunkt unterbringen, der nicht nur diesen, sondern gegebenenfalls noch andere Einträge mit Aufrufen unserer selbst definierten Funktionen enthält. Die Struktur mit Mein Menü|Mein Befehl ist daher schon passend. Damit wären wir nach dem Markieren der zu bearbeitenden Codezeilen mit zwei Mausklicks am Ziel.

Die nächste Möglichkeit ist das Kontextmenü. Hier benötigen wir grundsätzlich einen Klick mehr, weil wir diese erst einmal mit einem Rechtsklick anzeigen müssen. Wenn wir den Befehl dann direkt im Kontextmenü anzeigen, kommen wir schnell zum Ziel. Wenn das Kontextmenü noch keine Einträge weiterer COM-Add-Ins enthält, kann man das so machen. Wenn wir jedoch planen, noch weitere benutzerdefinierte Funktionen zu diesem oder anderen COM-Add-Ins hinzuzufügen, können wir auch einen Unterpunkt hinzufügen.

Das wäre dann zwar ein Mausklick mehr, aber letztlich sparen wir durch die Funktion an sich schon so viel Zeit, dass sich das nicht besonders auswirken sollte.

Also starten wir wie folgt:

  • Wir fügen der Menüleiste einen Menüpunkt beispielsweise namens AMV-Tools hinzu. Unter diesem legen wir den Aufruf zum Umwandeln der Variablen in Property Get/Let/Set-Prozeduren an.
  • Wir fügen auch dem Kontextmenü einen Menüpunkt namens AMV-Tools hinzu. Dieser enthält wiederum eine Schaltfläche zum Aufrufen der gewünschten Funktion.
  • Schließlich wollen wir den Befehl auch noch in der Symbolleiste unterbringen. Hier können wir den Befehl direkt unterbringen, sollten uns jedoch auf ein Icon beschränken.
  • Außerdem fügen wir die gewünschte Funktion zum Umwandeln von Variablen in Propertys hinzu und testen diese ausführlich.

Passende Symbolleiste finden

Der VBA-Editor enthält einige Symbolleisten. Welche verwenden wir optimalerweise für unsere Funktion? Schauen wir uns erst einmal an, welche eingebauten Symbolleisten der VBA-Editor alle anbietet. Dazu lassen wir in einer VBA-Anwendung die folgende Prozedur laufen:

Public Sub ListMenus()
     Dim cbr As Office.CommandBar
     For Each cbr In VBE.CommandBars
         If cbr.Type = msoBarTypeNormal Then
             Debug.Print cbr.Name
         End If
     Next cbr
End Sub

Dies liefert das folgende Ergebnis:

Voreinstellung
Bearbeiten
Debuggen
UserForm
Clipboard

Wenn wir uns diese Symbolleisten einmal anschauen, können wir besser entscheiden, welche der richtige Ort ist. Dazu blenden wir einmal alle Symbolleisten ein. Das erledigen wir über den Menüpunkt Ansicht|Symbolleisten. Hier finden wir alle verfügbaren Symbolleisten vor – wobei aus der per VBA ausgegebenen Liste der Eintrag Clipboard fehlt. Dafür finden wir einen zusätzlichen Eintrag namens Anpassen… (siehe Bild 3).

Einblenden aller Symbolleisten

Bild 3: Einblenden aller Symbolleisten

Die eingeblendeten Symbolleisten erscheinen zunächst freischwebend, was normalerweise nicht erwünscht ist – außer, man benötigt die entsprechende Funktion direkt in der Nähe der damit zu bearbeitenden Elemente. Dann stellt sich jedoch die Frage, ob der Einsatz eines Kontextmenüs nicht ohnehin die bessere Lösung wäre.

Für unseren Zweck scheint uns jedenfalls die Symbolleiste Bearbeiten am geeignetsten zu sein. Also fügen die unseren Befehl dort hinzu.

Einfügen eines Befehls in der Bearbeiten-Symbolleiste und mehr

Nun schauen wir uns an, wie wir die im Artikel twinBASIC: COM-Add-In für den VBA-Editor (www.vbentwickler.de/421) vorgestellte Vorlage genau anpassen, um unsere Funktionen im VBA-Editor bereitzustellen. Wir gehen an dieser Stelle nicht mehr auf alle dort beschriebenen Details ein.

Um die Menüs mit unseren Schaltflächen zu füllen, benötigen wir zuerst einmal die Prozedur, die beim Verbinden des VBA-Editors mit dem COM-Add-In ausgelöst wird.

Diese weist der Objektvariablen objVBE, die wir öffentlich in einem Modul namens mdlGlobal definieren, den mit dem Parameter Application gelieferten Verweis auf die aufrufende Anwendung zu:

Public objVBE As VBIDE.VBE

Außerdem rufen wir in dieser Prozedur, die in Listing 1 abgebildet ist, die Prozedur CreateToolbar auf.

Sub OnConnection(ByVal Application As Object, ByVal ConnectMode As ext_ConnectMode, ByVal AddInInst As Object, _
         ByRef custom As Variant()) Implements IDTExtensibility2.OnConnection
     Set objVBE = Application
     Set objAddIn = AddInInst
     isConnected = True
     CreateToolBar()
End Sub

Listing 1: Diese Prozedur wird beim Verbinden des COM-Add-Ins ausgelöst.

Diese referenziert zuerst die Menüleiste mit der Variablen cbr und fügt dieser ein Untermenü hinzu (siehe Listing 2). Dieses platziert sie vor dem achten Untermenü, stellt die Beschriftung auf den Wert aus der Konstanten cStrMenu ein (AMV-Tools) und fügt diesem ein mit der Variablen cbb referenziertes CommandBarButton-Element hinzu.

Private Sub CreateToolBar()
     Dim cbr As CommandBar
     Dim cbp As CommandBarPopup
     Dim cbpContext As CommandBarPopup
     Set cbr = objVBE.CommandBars("Menüleiste") ''Eintrag in Menüleiste anlegen
     Set cbp = cbr.Controls.Add(msoControlPopup, Temporary:=True)
     With cbp
         .Move Before:=8
         .Caption = cStrMenu
         Set cbbMenu =.Controls.Add(msoControlButton, Temporary:=True)
     End With
     With cbbMenu
         .Caption = cStrCommandButton
         .BeginGroup = True
         .Picture = GetImage("GetSet.png")
         Set cbbMenuEvent = objVBE.Events.CommandBarEvents(cbbMenu)
     End With
     Set cbr = objVBE.CommandBars("Bearbeiten") ''Eintrag in Symbolleiste ''Bearbeiten'' anlegen
     Set cbbToolbar = cbr.Controls.Add(msoControlButton, temporary:=True)
     With cbbToolbar
         .BeginGroup = True
         .Picture = GetImage("GetSet.png")
         Set cbbToolbarEvent = objVBE.Events.CommandBarEvents(cbbToolbar)
     End With
     Set cbpContext = objVBE.CommandBars("Code Window").Controls.Add(msoControlPopup, Temporary:=True)
     With cbpContext
         .Caption = cStrMenu
     End With
     Set cbbContext = cbpContext.Controls.Add(Temporary:=True)
     With cbbContext
         .Caption = cStrCommandButton
         .Picture = GetImage("GetSet.png")
         .BeginGroup = True
         Set cbbContextEvent = objVBE.Events.CommandBarEvents(cbbContext)
     End With
End Sub

Listing 2: Diese Prozedur erstellt die CommandBarButton-Objekte in den verschiedenen Menüs.

Für dieses legt es die Beschriftung aus der Konstanten cStrCommandButton fest (Getter und Setter für Variable) und stellt das Icon mit der Picture-Eigenschaft auf das Ergebnis der Funktion GetImage mit dem Parameter GetSet.png ein. Schließlich weisen wir der Objektvariablen cbbMenuEvent die Ereignisse des CommandBarButton-Objekts zu.

Die Objektvariablen für die Menüs deklarieren wir im allgemeinen Teil des Menüs wie folgt:

Private cbbToolbar As CommandBarButton
Private cbbMenu As CommandBarButton
Private cbbContext As CommandBarButton

Direkt danach folgen die Deklarationen der Event-Klassen für die drei anzulegenden Schaltflächen:

Private WithEvents cbbToolbarEvent As _
     VBIDE.CommandBarEvents
Private WithEvents cbbContextEvent As _
     VBIDE.CommandBarEvents
Private WithEvents cbbMenuEvent As VBIDE.commandbarEvents

Damit legen wir nun den Eintrag in der Symbolleiste an. Dazu referenzieren wir die Symbolleiste Bearbeiten mit der Variablen cbr. Dieser fügen wir ein neues Element hinzu und referenzieren es mit cbbToolbar. Dieses erhält keine Beschriftung, aber ebenfalls das Icon. Außerdem referenzieren wir seine Ereignisse mit der Variablen cbbToolbarEvent.

Schließlich folgt noch der Eintrag im Kontextmenü. Dazu referenzieren wir das Kontextmenü mit dem Namen Code Window und weisen diesem ein neues Untermenü hinzu, das wir mit der Variablen cbpContext referenzieren und das wie das Untermenü in der Menüleiste die Beschriftung aus cStrMenu erhält.

Diesem Untermenü fügen wir eine Schaltfläche hinzu, die genauso aufgebaut ist wie die im Hauptmenü. Wir referenzieren sie aber mit der Variablen cbbContext und seine Events mit der Variablen cbbContextEvent.

Damit haben wir alle Menüeintrage hinzugefügt. Nun müssen wir die Ereignisprozeduren definieren.

Ereignisse für die drei Menübefehle programmieren

Dazu wählen wir im Codefenster von twinBASIC jeweils oben im mittleren Auswahlfeld den Namen des Klassenmoduls aus und im rechten dann den Eintrag Click (siehe Bild 4).

Anlegen der Ereignisprozeduren für die Menübuttons

Bild 4: Anlegen der Ereignisprozeduren für die Menübuttons

 

Schreibe einen Kommentar