Problem:
COM-Add-Ins sind eigenständige Anwendungen. Sie können standardmäßig keine Shortcuts von Office-Anwendungen verarbeiten. Das ist misslich, denn wahrscheinlich hätte man ganz gern für die selbst
gebauten Funktionalitäten Tastenkombinationen, wie etwa Strg+Alt+A, vergeben.
Lösungsansatz:
Im Gegensatz zu COM-Add-Ins können in Word-Add-Ins Tastenkombinationen für Makros und Vorlagen vergeben werden.
Die Lösung, die hier vorgestellt wird, besteht nun darin, ein solches Word-Add-In zu erstellen und dort über Makros Methoden des COM-Add-Ins aufzurufen. Den Makros werden im Word-Add-In
Tastenkombinationen zugewiesen. Damit der Aufruf der COM-Add-In-Methoden funktioniert, müssen dies für andere Lösungen verfügbar gemacht werden.
Das Word Add-In kopiert man dann in das Start-Verzeichnis von MS Word. Damit wird es zu einer globalen Dokumentvorlage.
Die Akteure
Das COM-Add-In
- realisiert die eigentlichen Funktionalitäten und
- enthält eine Schnittstelle, die ausgewählte Methoden nach außen verfügbar macht.
Die globale Dokumentvorlage
- enthält eine allgemeine Prozedur, die verfügbare Methoden aus dem COM-Add-In aufruft,
- enthält Makros, die unter Verwendung dieser allgemeinen Prozedur verschiedene sichtbare COM-Add-In-Methoden aufrufen und
- setzt beim Öffnen die Tastaturbindungen auf diese Makros.
Was zu tun ist im COM-Add-In:
Das Assembly Microsoft.Office.Tools.Common (in Microsoft.Office.Tools.Common.dll) enthält die Schnittstelle IAddInExtension. Die IAddInExtension
-Schnittstelle definiert einen Satz von Elementen, die die Funktionalität des Add-in-Objektes erweitert. Implementiert wird sie durch den AddInBase-Host. Dies ist die Basisklasse für die
generierte ThisAddIn -Klasse in VSTO-Projekten.
Eine Methode dieser Schnittstelle ist RequestComAddInAutomationService. Diese Methode kann dazu genutzt werden, um Methoden des Add-Ins anderen Lösungen zur Verfügung zu
stellen.
Dazu muss sie überschrieben werden. Das passiert in der Klasse ThisAddIn.
Public Class ThisAddIn
Private au As IMyAddInUtilities
Protected Overrides Function RequestComAddInAutomationService() As Object
If au Is Nothing Then
au = New MyAddInUtilities()
End If
Return au
End Function
End Class
Es wird ein Objekt der Klasse MyAddINUtilities instanziiert.
MyAddINUtilities ist eine Klasse, die wir erstellen müssen, und die alle die Methodenaufrufe beinhaltet, die von außen verfügbar sein sollen. Im nachfolgenden Beispiel ist nur eine
Methode implementiert (CallFromVBA). Diese Methode hat einen Parameter (Was), der beim Aufruf darüber entscheidet, welche interne Add-In-Methode
aufgerufen werden soll.
Die Klasse MyAddINUtilities implementiert ein Interface IMyAddInUtilities, welches wir ebenfalls erstellen müssen.
Beide, die Schnittstelle und die Klasse, erhalten das Attribut <ComVisible(True)>. Dieses Attribut ist notwendig, um den Code für andere Lösungen
sichtbar zu machen.
Das Attribut <ClassInterface(ClassInterfaceType.None)> verhindert die Generierung der Klassenschnittstelle während des Exports
der Klassenmetadaten in eine Typbibliothek
Imports System.Runtime.InteropServices
<ComVisible(True)>
Public Interface IMyAddInUtilities
Sub CallFromVBA(Was As String)
End Interface
<ComVisible(True)>
<ClassInterface(ClassInterfaceType.None)>
Public Class MyAddInUtilities
Implements IMyAddInUtilities
Public Sub CallFromVBA(Was As String) Implements IMyAddInUtilities.CallFromVBA
Try
Select Case Was
Case "Gesperrt"
Globals.Ribbons.Ribbon1.rbb_Gesperrt_Click(Nothing, Nothing)
Case "Abschnitt_einfuegen"
Globals.Ribbons.Ribbon1.rbbAbchnitt_einfuegen_Click(Nothing, Nothing)
Case "Schnellbausteinkatalog"
Globals.Ribbons.Ribbon1.rbbSchnellbausteinkatalog_Click(Nothing, Nothing)
End Select
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class
Damit sind die Vorbereitungen im COM-Add-In abgeschlossen.
Was zu tun ist in der globalen Dokumentvorlage:
Um den Aufruf der COM-Add-In-Methoden zu vereinheitlichen, wird zuerst ein Modul erzeugt, indem der nachfolgende Programmcode steht:
Option Explicit
Option Compare Text
Public Const cCOMAddIN_ProgId As String = "Beispiel_Add-In"
Private Sub CallVSTOMethod(Was As String)
' Aufrufen einer COM-Add-In Methode
On Error GoTo er
Dim addIn As COMAddIn
' Erst einmal sicherstellen, dass das COM-Add-In überhaupt geladen ist.
Set addIn = Get_COMAddIn(cCOMAddIN_ProgId)
If addIn Is Nothing Then
Err.Raise 1, "Das Add-In '" & cComAddIn_ProgId & "' ist nicht geladen!"
Else
addIn.Object.CallFromVBA Was 'Das ist der Aufruf
End If
ex: Exit Sub
er: MsgBox Err.Description & vbNewLine & "in CallVSTOMethod()"
Resume ex
End Sub
Public Function Get_COMAddIn(ProgID As String) As COMAddIn
' Übergibt: die Referenz auf das COM-Add-In mit der entsprechenden ProgID
' Nothing, falls das COM-Add-In nicht geladen ist.
On Error GoTo er
Dim addIn as COMAddIn
Dim geladen As Boolean
geladen = False
Set Get_COMAddIn = Nothing
For Each addIn In Application.COMAddIns
If (addIn.ProgID = cCOMAddIN_ProgId) And (addIn.Connect = True) Then
geladen = True
Exit For
End if
Next addIn
If geladen then Set Get_COMAddIn = addIn
ex: Exit Function
er: Resume ex
End Function
'----Das sind die Makros, denen ein Tastenkürzel zugeordnet wird
Public Sub Schnellbausteinkatalog()
CallVSTOMethod "Schnellbausteinkatalog"
End Sub
Public Sub Gesperrt()
CallVSTOMethod "Gesperrt"
End Sub
Public Sub Abschnitt_anfuegen()
CallVSTOMethod "Abschnitt_einfuegen"
End Sub
CallVSTOMethod ruft die Methode CallFromVBA aus dem COM-Add-In auf. Dabei wird zuvor sichergestellt, dass das COM-Add-In überhaupt geladen ist. Um das festzustellen gibt es die Funktion Get_COMAddIn.
Die Prozeduren Schnellbausteinkatalog, Gesperrt und Abschnitt_einfuegen benutzen CallVSTOMethod. Diese
Makros werden mit einem Tastenkürzel verbunden.
Das Keybinding wird im AutoExec-Makro beim Starten der globalen Dokumentvorlage erledigt. Natürlich kann man auch manuell über die Benutzeroberfläche von Word in den
Optionen die Tastenkürzel setzen.
Public Sub AutoExec()
'Keybinding realisieren
On Error GoTo er
CustomizationContext = ThisDocument
KeyBindings.ClearAll
If Not Get_COMAddIn(cCOMAddIN_ProgId) Is Nothing Then
KeyBindings.Add wdKeyCategoryMacro, "Schnellbausteinkatalog", _
KeyCode:=BuildKeyCode(wdKeyControl, wdKeyAlt, wdKeyS)
KeyBindings.Add wdKeyCategoryMacro, "Gesperrt", _
KeyCode:=BuildKeyCode(wdKeyControl, wdKeyAlt, wdKeyG)
KeyBindings.Add wdKeyCategoryMacro, "Abschnitt_anfuegen", _
KeyCode:=BuildKeyCode(wdKeyControl, wdKeyAlt, wdKeyA)
End If
ThisDocument.Saved = True
ex: Exit Sub
er: MsgBox Err.Description & vbNewLine & " in AutoExec"
Resume ex
End Sub
FERTIG!