Ribbon für VBA – Status Abholdienst

Unser Problem mit dem nicht automatisch aktualisierenden Toggle Button aus der vorherigen Runde werden wir jetzt schrittweise lösen. Für VBA ist das Ribbon erstmal auch nur ein Objekt, genau wie das aktuelle Dokument oder ein Absatz. Allerdings kann sich das Ribbon nicht ganz automatisch bekannt machen, da es ja praktisch nur etwas XML Code ist. Wie bei den anderen Buttons können wir aber eine Funktion anlegen, mit der das Ribbon Objekt an VBA übergeben werden kann. Dafür wird in der ersten Zeile onLoad="vbaCoreRibbon_Load" hinzugefügt. Wenn das Ribbon also geladen wird, dann ruft es diese Funktion auf. Nicht vergessen das Callback vor dem Schließen des Editors zu kopieren. 😉

Beim Öffnen der dotm gibt es Fehlermeldungen, logisch, die Funktion ist ja nicht da. Da hat Word schon recht. Völlig zurecht fügen wir im VBA Editor das Callback ein und testen das aus Spaß mal mit einer MsgBox.

Alles speichern, Datei schließen > wieder öffnen und wuhuu, Nummer 5 lebt! 😍

OK cool, aber irgendwelche Fensterchen waren ja gar nicht das Ziel. Wir brauchen doch das Ribbon Objekt um es aktualisieren zu können, wenn sich was geändert hat. Deshalb speichern wir das Objekt doch erstmal ab und gucken dann weiter was geht. Damit wir auch in anderen Funktionen darauf zugreifen können, wir die Variable logischerweise außerhalb der onLoad Methode definiert und in der Methode initialisiert.

Dim VbaCoreRibbon As IRibbonUI
Sub vbaCoreRibbon_Load(ribbon As IRibbonUI)
  Set VbaCoreRibbon = ribbon
End Sub

Damit können wir jetzt zum Kern voranschreiten. Für uns sind zwei Methoden relevant die das Ribbon Objekt zu bieten hat: Invalidate und InvalidateControl. Fangen wir mal mit dem zweiten an und integrieren eine neue Funktion, die auch nach außen sichtbar ist.

Public Sub InvalidateRibbon()
    VbaCoreRibbon.Invalidate
End Sub

Zusätzlich wollen wir das mal händisch ausprobieren und rufen deshalb mit dem zweiten Button diese Funktion anstatt der MsgBox auf.

Jetzt unbedingt speichern und die dotm neu öffnen, ansonsten ist das Ribbon Objekt nicht verfügbar. Wir haben den Code ja erst nach dem Öffnen geschrieben. Und dann können wir testen ob Nummer 5 immernoch lebt. 👻

Yeah, es funktioniert. So kann man doch langsam arbeiten. 😁 Praktisch passiert etwas sehr einfaches. Die Invalidate Methode veranlasst das Ribbon seine Get Methoden von jedem Element auszuführen. Wir haben nur eine, nämlich die vom Toggle Button, der nachguckt, wie der Status der Schrifteinbettung ist.

Nun ist es ja nicht notwendig immer das gesamte Ribbon zu checken, Rechenzeit und so. Deshalb kommt die zweite Variante ins Spiel: InvalidateControl. Diese Methode möchte den Namen des Elements wissen, welches neu geladen werden soll. Das bekommen wir doch auch umgesetzt oder?

Public Sub InvalidateControl(ElementId As String)
    VbaCoreRibbon.InvalidateControl (ElementId)
End Sub

Der Funktionstest lässt sich wie beim kompletten Invalidate durchführen, optisch passiert das gleiche – der Toggle Button ändert seinen Zustand. Wer jetzt den Unterschied testen möchte, kann ja testweise mal den ToggleEmbedFonts als ToggleEmbedFontsZwei duplizieren und trotzdem InvalidateControl "ToggleEmbedFonts“ über den Button aufrufen. Einer sollte sich aktualisieren, der andere nicht.

Damit können wir also schonmal unser fesches Ribbon aktualisieren lassen. Grundsätzlich haben wir also die Möglichkeit vom Ribbon in VBA und umgekehrt zu kommen. Als nächstes wollen wir natürlich, dass sich die Elemente selbstständig ohne Klicken auf ein Button aktualisieren. 😎