öffentlich
Redaktion Druckversion

Die neuen Ribbons in Office 2007 sehen nicht nur toll aus, sie bieten auch viele neue Möglichkeiten. So können die Elemente auf den neuen Office 2007-Ribbons weitaus dynamischer sein, als es bisherige Menüs oder Symbolleisten zuließen. Allerdings ist die dabei verwendete Technik auch komplett anders als bisher, denn es gibt kein Objektmodell zum VBA-Zugriff auf die Ribbons.

Office 2007 verfügt über eine neue Benutzeroberfläche (Office Fluent). Die Menüs und Funktionen wurden in eine Multifunktionsleiste (Ribbon) integriert. Im Beitrag "Ribbons erstellen in Word 2007" bzw. in "Ribbons erstellen in Excel 2007" finden Sie die grundsätzlichen Tipps zur Erstellung und Programmierung der Ribbons und was dabei zu beachten ist.

Auch wenn die Beispiele hier für Word 2007 beschrieben wurden, funktionieren sie grundsätzlich genauso in den anderen Programmen von Office 2007.

Die einzige Chance, ein Ribbon zur Aktualisierung zu veranlassen, besteht im Invalidate-Befehl. Dieser nötigt das Ribbon, sich selbst erneut einzulesen. Es gibt noch eine "Sparversion" davon mit InvalidateControl, damit nur ein Element statt des ganzen Ribbons eingelesen wird, aber das war's dann auch schon.

Das Ribbon selbst muss in der XML-Beschreibung alle benötigten VBA-Prozeduren kennen, die für seine Darstellung sorgen. Diese werden beim Invalidate aufgerufen.

Lösungsdatei

Laden Sie zum Vergleich die Lösungsdatei Invalidate01.docm herunter.

Erstellen Sie zum Testen ein neues leeres Word 2007-Dokument mit Makros im *.docm- oder *.dotm-Format. Schließen Sie die Datei in Word.

Öffnen Sie diese dann im Custom UI Editor und fügen Sie den folgenden Code ein:

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="OnLoadRibbon">
	<ribbon startFromScratch="false">
		<tabs>
			<tab id="tabTest" label="akademie">
				<group id="grpTest" label="Dynamisch">
					<button id="btnUhrzeit" label="Uhrzeit" onAction="OnActionButton" />
                                        <labelControl id="lblUhrzeit" getLabel="GetLabel" />
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

Bild vergrößernDer XML-Code für die dynamische Anzeige

Wenn Sie diese Datei in Word öffnen, erhalten Sie sofort eine Fehlermeldung. Klicken Sie auf OK.

Bild vergrößernDer VBA-Code müsste schon beim Öffnen ausgeführt werden.

Bisher waren Fehler erst beim Klick auf eine Schaltfläche gemeldet worden, weil das der erste Anlass gewesen war, ein onAction-Attribut auszuführen. Jetzt steht aber bereits im <customUI>-Element ein onLoad-Attribut und dessen VBA-Code soll auch direkt ausgeführt werden.

Ergänzen Sie daher im VBA-Editor in Word in einem neuen Modul die folgenden Prozedur-Rümpfe, wie sie für die XML-Beschreibung gebraucht werden:

Option Explicit

'Callback for customUI onLoad
Sub OnLoadRibbon(ribbon As IRibbonUI)
End Sub

'Callback for btnUhrzeit onAction
Sub OnActionButton(control As IRibbonControl)
End Sub

'Callback for lblUhrzeit getLabel
Sub GetLabel(control As IRibbonControl, ByRef returnedVal)
End Sub

Bild vergrößernDie Prozedur-Rümpfe noch ohne Inhalt

Anders als bisher ist auch im <labelControl>-Element nicht einfach das label-Attribut mit einem statischen Text genannt, sondern stattdessen ein getLabel-Attribut mit der Angabe einer GetLabel-Prozedur. Beide Attribute in einem Element gleichzeitig sind nicht zulässig.

Das hat zur Folge, dass über den returnedVal-Parameter die Beschriftung immer aus der GetLabel-Prozedur geholt wird, auch schon direkt beim ersten Laden. Weil das noch nicht geklappt hat, ist die Beschriftung unterhalb der Schaltfläche mit dem Text "Laden" auch noch nicht zu sehen:

Bild vergrößernDas Bezeichnungsfeld ist noch unbeschriftet

Wenn Sie den Code für GetLabel wie folgt ergänzen, liefert die Prozedur jeweils die gewünschte Uhrzeit als Beschriftung:

Option Explicit

'Callback for customUI onLoad
Sub OnLoadRibbon(ribbon As IRibbonUI)
End Sub

'Callback for btnUhrzeit onAction
Sub OnActionButton(control As IRibbonControl)
End Sub

'Callback for lblUhrzeit getLabel
Sub GetLabel(control As IRibbonControl, ByRef returnedVal)
    Select Case LCase(control.ID)
    Case "lbluhrzeit": returnedVal = "Uhrzeit: " & Time()
    Case Else
    End Select
End Sub

Bild vergrößernDie GetLabel-Prozedur gibt eine Uhrzeit zurück

Das ist nach dem Schließen und erneuten Öffnen des Dokuments auch auf dem Ribbon zu sehen:

Bild vergrößernDie Uhrzeit wird angezeigt

Allerdings soll die Aktualisierung auch ohne erneutes Öffnen möglich sein, nämlich mit der Schaltfläche darüber. Diese Schaltfläche muss nun lediglich ein Invalidate für das Ribbon-Objekt auslösen. Leider existiert kein Ribbon-Objekt, Sie müssen es selbst verwalten.

Die einzige Chance, eine VBA-Referenz auf ein Ribbon anzulegen, besteht in der OnLoadRibbon-Prozedur, bei der Word als Parameter eine IRibbonUI-Variable übergibt. Nur hier und nur zu diesem Zeitpunkt können Sie einen Verweis anlegen.

Also deklarieren Sie eine Modul-öffentliche Variable m_ribAkademie und weisen dieser den übergebenen Parameter zu:

Option Explicit

Dim m_ribAkademie As IRibbonUI

'Callback for customUI onLoad
Sub OnLoadRibbon(ribbon As IRibbonUI)
    Set m_ribAkademie = ribbon
End Sub

'Callback for btnUhrzeit onAction
Sub OnActionButton(control As IRibbonControl)
    m_ribAkademie.InvalidateControl "lblUhrzeit"
End Sub

Bild vergrößernDie Modul-öffentliche Variable m_ribAkademie enthält den Verweis

Dann können Sie diese in onActionButton mit Invalidate als Ganzes oder wie hier mit InvalidateControl für das genannte Objekt dazu veranlassen, den entsprechenden Ribbon-Teil erneut einzulesen und damit zu aktualisieren.

Das funktioniert, wie Sie in Word prüfen können. Allerdings wird OnLoadRibbon nur beim Öffnen des Dokuments ausgeführt, sodass Sie es nochmals schließen und wieder öffnen müssen:

Bild vergrößernDie Uhrzeit lässt sich nun dynamisch aktualisieren.

IRibbonUI-Variable geht regelmäßig verloren

Sobald ein Laufzeit-Fehler auftritt und Sie die Ausführung stoppen müssen, werden alle Variablen zurückgesetzt. Das ist bei normaler VBA-Programmierung nicht weiter tragisch, denn alle Objekte werden von Word wieder aktualisiert.

Hier ist das anders, denn die OnRibbonLoad-Prozedur kann nur beim Öffnen der Datei ausgeführt werden, die Datei ist aber schon offen. Damit steht die m_ribAkademie-Variable auf Nothing. Es bleibt Ihnen nichts anderes übrig, als das Dokument zu schließen und wieder zu öffnen.

Wenn Sie ein Word-AddIn erstellen, ist das noch lästiger, denn Word hält das Dokument auch nach dem manuellen "Schließen" geöffnet. Da müssen Sie nach jedem Laufzeitfehler Word komplett beenden.


Beitrag bewerten

Ihre Wertung:

 

Eigene Ribbons RESET

Hallo zusammen,

ich habe in Excel für diesen Fall eine RESET Routine geschrieben,
welche mir das AddIn schließ und wieder öffnet.
Wobei dann alle eigenen Ribbons wieder da sind.

Das gleiche sollte auch in Word klappen. Dort dann das Makro in die Normal.dotm
schreiben und auf der Schnellstartleiste über "Weitere Befehle, Befehle auswählen, Makros, hinzufügen.

Hier mein Excel Makro. Dies müsste dann auf Word, die persönlichen Pfade und Dateinamen angepasste werden.

Sub BeispielAddIn_Rest()
On Error Resume Next
Application.ScreenUpdating = False
Workbooks("BeispielAddIn.xlam").Close SaveChanges:=False
Workbooks.Open "\\THOMM\Informationen\Produktion\BeispielAddIn.xlam"
AddIns("BeispielAddIn").Installed = True
Application.ScreenUpdating = True
End Sub

Dynamische Beschriftungen auf Ribbons

...jetzt weiß ich endlich, wie ich meine Ribbon-Beschriftungen zur Laufzeit sprachspezifisch ändern kann. Vielen Dank! mk

Mitglied werden, Vorteile nutzen!

  • Sie können alles lesen und herunterladen: Beiträge, PDF-Dateien und Zusatzdateien (Checklisten, Vorlagen, Musterbriefe, Excel-Rechner u.v.a.m.)
  • Unsere Autoren beantworten Ihre Fragen

Downloads zu diesem Beitrag

Newsletter abonnieren