Wer das Ribbon ausgiebig nutzt, hat schnell einige Tabs zusammen, die wiederum mehrere Gruppen mit den jeweiligen Steuerelementen enthalten. Diese Tabs sind in der Regel so ausgelegt, dass das zuerst angezeigte Tab aktiviert wird, wenn der Benutzer die Anwendung startet. Wenn der Benutzer aber regelmäßig eher mit den Aufgaben einsteigt, die sich in einem anderen Tab befinden, muss er jedes Mal erst noch zu diesem Tab wechseln. Um dies zu vereinfachen, stellen wir in diesem Beitrag eine Lösung vor, mit der sich die Anwendung das zuletzt verwendete Tab-Element merken kann und dieses beim nächsten Start wiederherstellt.
Umfangreiche Anwendungen enthalten manchmal ebenso reichhaltige Ribbon-Definitionen mit vielen Tab, Groups und Steuerelementen. Benutzer wählen ein Tab aus, um Funktionen mit den darin enthaltenen Steuerelementen aufzurufen.
Gegebenenfalls ist es für den Benutzer hilfreich, wenn er öfter Befehle eines speziellen tab-Elements nutzt, dass dieses Tab beim Schließen und erneuten Starten einer Anwendung direkt wieder angezeigt wird.
Die damit verbundenen Techniken wollen wir in diesem Beitrag einmal vorstellen. Dazu haben wir eine kleine Beispielanpassung des Ribbons vorbereitet, die zunächst einmal nur drei Tabs mit den jeweiligen Gruppen und je einem Steuerelement anzeigt.
Dieses definieren wir wie in Listing 1.
<?xml version="1.0"?> <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui"> <ribbon> <tabs> <tab id="tab1" label="Tab 1"> <group id="grp11" label="Gruppe 1-1"> <button idMso="Copy" size="large"/> <button idMso="Cut" size="large"/> <button idMso="Paste" size="large"/> </group> </tab> <tab id="tab2" label="Tab 2"> <group id="grp21" label="Gruppe 2-1"> <button idMso="FindDialog" size="large"/> </group> </tab> <tab id="tab3" label="Tab 3"> <group id="grp31" label="Gruppe 3-1"> <button idMso="CreateTable" size="large"/> <button idMso="CreateTableInDesignView" size="large"/> </group> </tab> </tabs> </ribbon> </customUI>
Listing 1: Ausgangsposition für das Speichern des zuletzt verwendeten Tab-Elements
Wir sehen das customUI-Element mit dem ribbon– und dem tabs-Element, dem wiederum drei tab-Element untergeordnet sind.
Diese enthalten jeweils eine Gruppe mit ein paar Schaltflächen auf Basis eingebauter Steuerelemente. Damit dieses Ribbon in der Beispielanwendung wie in Bild 1 erscheint, sind folgende Schritte zu erledigen:
Bild 1: Beispielribbon, dessen Tabs wir uns merken wollen
- Anlegen einer Tabelle namens USysRibbons wie in Bild 2, der wir die Daten wie abgebildet hinzufügen.
- Komprimieren und Reparieren der Datenbank (schnellste Version, um eine Datenbankdatei zu schließen und wieder zu öffnen)
- Öffnen der Access-Optionen und dort unter Aktuelle Datenbank im Bereich Menüband- und Symbolleistenoptionen die Option Name des Menübands auf Main einstellen (siehe Bild 3).
- Erneutes Komprimieren und Reparieren.
Bild 2: Tabelle USysRibbons mit unserer Ribbondefition
Bild 3: Einstellen der Ribbondefinition als Anwendungsribbon
Danach sollte das Ribbon wie in der Abbildung erscheinen. Wenn Sie nur die benutzerdefinierten Ribbon-Einträge hinzufügen wollen, ändern Sie die Zeile mit dem Ribbon-Element wie folgt:
<ribbon startFromScratch="true">
Danach noch einmal Komprimieren und Reparieren und das Ribbon erscheint wie in Bild 4.
Bild 4: Ribbon ohne eingebaute Elemente
Letztes Ribbontab speichern
Wie aber bekommen wir es nun hin, dass sich die Anwendung das beim Schließen geöffnete Ribbontab merkt? Dazu sind grob die folgenden Schritte nötig:
- Beim Schließen der Anwendung das aktuell geöffnete tab-Element ermitteln.
- Eine Information über dieses tab-Element an einer beliebigen Stelle speichern.
- Beim Öffnen der Anwendung das gespeicherte Tab wiederherstellen.
Den letzten Punkt können wir abdecken, wenn wir wissen, dass es eine ActivateTab-Methode gibt, der wir den Namen des zu aktivierenden tab-Elements übergeben.
Der zweite Punkt ist reine Fleißarbeit. Wir können uns überlegen, ob diese Information in einer Tabelle der Datenbank, einer Textdatei, der Registry oder auch einer Datenbankeigenschaft gespeichert wird. Da die Information je Benutzer gespeichert werden soll, ist es sinnvoll, diese in der Registry im Bereich für das aktuelle Benutzerkonto zu hinterlegen.
Der erste Punkt ist etwas schwieriger. Zunächst einmal gibt es keine Möglichkeit, zu irgendeinem Zeitpunkt auszulesen, welches tab-Element gerade markiert ist. Es gibt keine Auflistung der Tabs im Objektmodell von Access oder Office, und es gibt auch keine Eigenschaft, die das aktuell aktivierte tab-Element referenziert.
Wir müssen also all unser Ribbon-Know-how nutzen, um diese Anforderung zu lösen.
Wir wissen: Es gibt keine Methode, mit der explizit wir auf das Wechseln des tab-Elements reagieren können. Aber es gibt einige Methoden, die beim Anzeigen von Steuerelementen wie beispielsweise bei button-Elementen ausgelöst werden.
Das button-Element liefert beispielsweise einige get…-Callback-Funktionen, die immer ausgelöst werden, wenn ein Element erstmals sichtbar gemacht wird – also beispielsweise, wenn sich das button-Element auf dem ersten Tab befindet und dieses beim Starten der Anwendung angezeigt wird. Wenn sich ein button-Element auf einem anderen, zunächst nicht aktivierten tab-Element befindet, werden seine get…-Callbacks erst einmal nicht aufgerufen. Dies geschieht erst, wenn das zweite Tab dann eingeblendet wird.
Wir können also auf jedem Tab ein button-Element unterbringen, das jeweils beim Aktivieren des tab-Elements die get…-Callbackfunktion aufruft.
Das button-Element muss noch nicht einmal sichtbar sein. Genau genommen soll es das auch gar nicht – wir wollen ein button-Element nur für diesen einen Zweck hinzufügen.
Und wenn es ohnehin nicht sichtbar sein soll, können wir auch gleich sein getVisible-Attribut nutzen und damit die getVisible-Callbackfunktion aufrufen, wenn das tab-Element aktiviert wird. In dieser Funktion können wir dann einfach speichern, welches tab-Element gerade aktiviert wurde.
Wir fügen also jedem tab-Element in einem group-Element ein neues button-Element hinzu, welches das Attribut getVisible enthält und beispielsweise wie folgt aussieht:
<tab id="tab1" label="Tab 1"> <group id="grp11" label="Gruppe 1-1"> <button label="Button 1-1-1" getVisible="getVisible" id="btn111" tag="tab1"/> ... </group> </tab>
Wir sehen hier allerdings nicht nur das Attribut getVisible, sondern auch noch das Attribut tag. Mit diesem legen wir fest, in welchem tab-Element sich das button-Element befindet – in diesem Fall tab1.
Die Callbackfunktion, die durch das Auslösen von getVisible ausgeführt wird, sieht zunächst wie folgt aus:
Sub getVisible(control As IRibbonControl, ByRef visible) Debug.Print "LastUsedTab gespeichert: " & control.Tag End Sub
Diese Prozedur fügen wir einem Standardmodul hinzu, in diesem Fall namens mdlRibbons.
Wir wollen hier zunächst nur ausgeben, welches tab-Element gerade aktiviert wurde.
Wenn wir für alle drei Tabs jeweils ein solches button-Element hinterlegen, die alle drei die gleiche Callback-Funktion getVisible aufrufen, erhalten wir nach dem Starten und dem aufeinanderfolgenden Anklicken der drei Ribbon-Tabs die Ausgabe aus Bild 5 im Direktbereich des VBA-Editors.
Bild 5: Ausgabe nach dem Aktivieren der drei Ribbon-Tabs
Erneutes Auslösen der get…-Funktionen aktivieren
Allerdings gelingt dies auch nur beim jeweils ersten Aufruf. Klicken wir danach nochmal auf eines der anderen tab-Elemente, erfolgt keine weitere Ausgabe im Direktbereich. Woran liegt das? Nun: Wenn ein tab-Element mit seinen Unterelementen einmal angezeigt wurde, dann ausgeblendet wird und wieder aktiviert wird, geht Access davon aus, dass sich zwischenzeitlich nichts geändert hat und liefert lediglich die bereits zuvor festgelegte Ansicht. Dadurch werden auch die get…-Funktionen nicht erneut aufgerufen.
Damit dies erneut geschieht, müssen wir die Ribbondefinition ungültig machen, was durch den Aufruf der Methode Invalidate (für das ganze Ribbon) oder InvalidateControl (für einzelne Steuerelemente) geschieht.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo