Button vom Formular ins Ribbon

Formulare sind oft völlig überfrachtet mit Steuerelementen zur Anzeige und Auswahl von Daten und Schaltflächen. Das lässt sich zumindest teilweise ändern, indem Sie einige Elemente aus dem Formular in ein Ribbon auslagern, das dann beim Erscheinen des Formulars eingeblendet wird. Bei einfachen Schaltflächen ist das noch recht einfach, aber sobald die Steuer-elemente etwa abhängig von den angezeigten Daten ein- oder ausgeblendet werden sollen, wird es interessant. In diesem Beitrag schauen wir uns an, wie das gelingt.

Konkret nehmen wir uns das Beispiel aus dem Beitrag Datenblatt: Reihenfolge mehrerer Einträge ändern (www.access-im-unternehmen.de/1198) vor. Hier finden wir in einem Formular ein Unterformular in der Datenblattansicht vor (siehe Bild 1). Dieses enthält vier Schaltflächen, mit denen Sie die Reihenfolge der Einträge des Datenblatts über die Werte des Feldes ReihenfolgeID manipulieren können. Im Falle dieses Beispiels enthält das Datenblatt nicht so viele Felder, dass diese nicht auf das Formular passen würde.

Ausgangsformular

Bild 1: Ausgangsformular

Wenn dies allerdings der Fall wäre, würde man sich die Schaltflächen an einer anderen Position wünschen. Am Besten, damit diese gar nicht mehr im Weg sind, direkt im Ribbon. Und genau das ist Thema des vorliegenden Artikels: Wir wollen zeigen, wie Sie die Schaltflächen aus einem Formular in das Ribbon übertragen und dabei alle vorgegebenen Funktionen beibehalten.

In unserem Fall betrifft das vor allem das Aktivieren und Deaktivieren der Schaltflächen in Abhängigkeit der angezeigten Daten. Das heißt, dass die Schaltflächen zum Verschieben der Elemente nach oben nur aktiviert sein sollen, wenn die Elemente auch nach oben verschoben werden können. Das gleiche gilt für die Schaltflächen zum Verschieben nach unten – diese sollen nur aktiviert werden, wenn die Elemente auch nach unten verschoben werden können. Außerdem sollen die Schaltflächen natürlich die im Klassenmodul des Formulars gespeicherten Ereignisprozeduren aufrufen.

Eine weitere Anforderung ist, dass das Ribbon nur in Zusammenhang mit der Anzeige dieses Formulars angezeigt werden soll. Um dieses zu öffnen, fügen wir der Anwendung noch ein Start-Ribbon hinzu, das beim Start angezeigt wird und das Öffnen des Formulars frmMehrfachreihenfolgeDatenblatt erlaubt. Wir könnten theoretisch auch direkt das Unterformular in der Datenblattansicht öffnen, aber das würde bedeuten, dass wir den kompletten Code des Hauptformulars in das Klassenmodul des Unterformulars übertragen und anpassen müssten. Diesen Schritt wollen wir erst einmal nicht gehen. Daher maximieren wir einfach das Unterformular innerhalb des Hauptformulars und sorgen dafür, dass das Hauptformular mit dem Unterformular beim Anklicken des entsprechenden Ribbon-Eintrags angezeigt wird. Das Ribbon-Tab für das Formular frmMehrfachreihenfolgeDatenblatt soll dann rechts neben dem Startribbon erscheinen.

Start-Ribbon erstellen

Um das erste Ribbon zu erstellen, fügen wir zunächst eine neue Tabelle namens USysRibbons zur Datenbank hinzu. Dieser Tabelle fügen Sie die drei folgenden Felder hinzu (siehe Bild 2):

Entwurf der Tabelle USysRibbons

Bild 2: Entwurf der Tabelle USysRibbons

  • ID: Autowertfeld mit Primärschlüsselindex
  • RibbonName: Textfeld/Kurzer Text
  • RibbonXML: Memofeld/Langer Text

USysRibbons wieder einblenden

Wenn Sie nicht die Anzeige von Systemobjekten und ausblendeten Objekten deaktiviert haben, verschwindet die Tabelle allerdings direkt nach dem Speichern aus dem Navigationsbereich.

Um diese wieder sichtbar zu machen, klicken Sie mit der rechten Maustaste auf die Titelzeile des Navigationsbereichs und wählen aus dem Kontextmenü den Eintrag Navigationsoptionen… aus.

Im nun erscheinenden Dialog Navigationsoptionen aktivieren Sie die beiden Optionen Ausgeblendete Objekte anzeigen und System-Objekte anzeigen (siehe Bild 3). Danach erscheint die Tabelle USysRibbons wieder im Navigationsbereich.

Die Navigationsoptionen von Access

Bild 3: Die Navigationsoptionen von Access

Ribbon-Definition für das Start-Ribbon

Danach fügen wir dem Feld RibbonName der Tabelle den Wert Main und dem Feld RibbonXML den XML-Code aus Listing 1 hinzu.

<xml version="1.0">
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
   <ribbon>
     <tabs>
       <tab id="tabBeispiele" label="Beispiele">
         <group id="grpFormulare" label="Formulare">
           <button imageMso="AccessFormDatasheet" label="Mehrfachreihenfolge 
             Datenblatt" id="btnMehrfachreihenfolgeDatenblatt" onAction="onAction" 
             size="large"/>
         </group>
       </tab>
     </tabs>
   </ribbon>
</customUI>

Listing 1: XML-Code für das Start-Ribbon

Hier definieren wir die ineinander verschachtelten Elemente customUI, ribbon, tabs, tab, group und schließlich button. Das button-Element erhält schließlich über das Attribut imageMso den Namen eines eingebauten Icons, eine Beschriftung, eine ID, den Wert large für das Attribut size und den Wert onAction für das Attribut onAction. Das bedeutet, dass wir an irgendeiner Stelle – in diesem Fall in einem Standardmodul – eine Prozedur namens onAction bereitstellen müssen, die bestimmten syntaktischen Anforderungen genügt. Die Tabelle sieht danach wie in Bild 4 aus.

Ribbon-Definition für das Start-Ribbon

Bild 4: Ribbon-Definition für das Start-Ribbon

Code für die Schaltfläche zum Öffnen des Formulars

Die oben genannte Prozedur onAction erstellen wir schließlich so:

Sub onAction(control As IRibbonControl)
     DoCmd.OpenForm "frmMehrfachreihenfolgeDatenblatt"
End Sub

Die Prozedur öffnet also dann das gewünschte Formular.

Ribbonfehler anzeigen

Damit die Benutzeroberfläche Fehler beim Verwenden der benutzerdefinierten Ribbons anzeigt, müssen wir noch eine Access-Option aktivieren. Dazu öffnen Sie über den Eintrag Datei|Optionen zunächst den Optionen-Dialog von Access. Hier finden Sie im Bereich Client-ein-stel-lun-gen|Allgemein die Option Fehler von Be-nut-zer-ober-flächen-Add-Ins anzeigen. Diese aktivieren Sie und schließen den Dialog mit der Schaltfläche OK (siehe Bild 5).

Ribbon-Option zum Anzeigen von Ribbon-Fehlern

Bild 5: Ribbon-Option zum Anzeigen von Ribbon-Fehlern

Abschließende Schritte

Nun müssen wir nur noch drei Schritte erledigen:

  • Die Anwendung schließen und wieder öffnen.
  • Die Option Name des Menübands auf die durch das Schließen und Öffnen nun verfügbaren Eintrag Main einstellen (siehe Bild 6).
  • Start-Ribbon für die Anwendung einstellen

    Bild 6: Start-Ribbon für die Anwendung einstellen

  • Die Anwendung erneut schließen und wieder öffnen, um das Ribbon nun anzuzeigen.

Nun erscheint das Ribbon wie in Bild 7. Hier klicken Sie auf den Tab namens Beispiele und erhalten die Schaltfläche zum Öffnen des Formulars.

Das Start-Ribbon

Bild 7: Das Start-Ribbon

Schaltflächen ins Ribbon

Um die Funktionen der vier Schaltflächen nun über das Ribbon ausführen zu können, legen wir zunächst ein neues Ribbon mit einem eigenen Tab für das Formular frmMehrfachreihenfolgeDatenblatt an.

Der XML-Code für dieses Ribbon sieht zunächst wie in Listing 2 aus und bildet das Grundgerüst, das wir gleich noch ausbauen. Erstmal möchten wir überhaupt ein Ribbon mit dem Formular einblenden. Diesen XML-Code fügen Sie in einem zweiten Datensatz in die Tabelle USysRibbons ein, und zwar mit dem Eintrag Reihenfolge im Feld RibbonName.

<xml version="1.0">
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
   <ribbon>
     <tabs>
       <tab id="tabReihenfolge" label="Reihenfolge">
         <group id="grpReihenfolgeAendern" label="Reihenfolge ändern">
           <button imageMso="ShapeUpArrow" label="Ganz nach oben" id="btnTop" size="large"/>
           <button id="btnUp" imageMso="ShapeUpArrow" label="Nach oben" size="large"/>
           <button id="btnDown" imageMso="ShapeDownArrow" label="Nach unten" size="large"/>
           <button id="btnBottom" imageMso="ShapeDownArrow" label="Ganz nach unten" size="large"/>
         </group>
       </tab>
     </tabs>
   </ribbon>
</customUI>

Listing 2: XML-Code für das Ribbon zum Formular

Damit dies gelingt, stellen wir die Eigenschaft Name des Menü-bands des Hauptformulars auf den Namen des neu erstellten Ribbons ein – allerdings erst, nachdem wir nach dem Einfügen des neuen Eintrags zur Tabelle USysRibbons die Anwendung geschlossen und wieder geöffnet haben (siehe Bild 8). Nur dadurch werden neu hinzugefügte Ribbon-Namen auch in den Auswahlfeldern der jeweiligen Eigenschaften sichtbar.

Menüband festlegen

Bild 8: Menüband festlegen

Ribbon für das Unterformular

Wenn wir das Formular nun über den Ribbon-Befehl des Start-Ribbons öffnen, erscheint zwar das Formular, aber das Tab-Element aus dem zugeordneten Ribbon wird nicht angezeigt (siehe Bild 9). Warum das Ganz einfach: Die Schaltflächen sind zu Beginn deaktiviert, damit bleibt das Unterformular das einzige Steuer-element, das den Fokus erhalten kann. Und das Unterformular hat genau wie das Formular eine eigene Eigenschaft namens Name des Menübands. Wir haben nun zwei Möglichkeiten:

Kein neues Ribbon für das Formular

Bild 9: Kein neues Ribbon für das Formular

  • Wir stellen diese Eigenschaft einfach auf das gleiche Ribbon ein wie die für das Hauptformular.
  • Wir fügen eine Ereignisprozedur für das Hauptformular hinzu, dass dem Unterformular das Ribbon des Hauptformulars zuweist.

Wir entscheiden uns für die zweite Variante, da wir dann gegebenenfalls nur das Ribbon für das Hauptformular ändern müssen:

Private Sub Form_Load()
     Me!sfm.Form.RibbonName = Me.RibbonName
End Sub

Damit erhalten wir nun beim Öffnen des Formulars frmMehrfachreihenfolgeDatenblatt zwar das neue Ribbon-Tab, allerdings wird dieses nicht aktiviert (siehe Bild 10).

Das Reihenfolge-Ribbon wird nicht aktiviert.

Bild 10: Das Reihenfolge-Ribbon wird nicht aktiviert.

Dazu gibt es wiederum drei Möglichkeiten:

  • Wir aktivieren das Ribbon-Tab per VBA-Code.
  • Wir definieren das Ribbon-Tab als kontextsensitives Ribbon-Tab.
  • Wir stellen die Eigenschaft startFromScratch des ribbon-Elements auf true ein. Damit werden alle übrigen Elemente ausgeblendet.

Wir schauen uns alle drei Varianten an.

Ribbon-Tab per VBA-Code aktivieren

Für diesen Fall benötigen wir zunächst einen Verweis auf die Bibliothek Microsoft Office 14.0 Object Library, wobei wir diesen über den Verweise-Dialog hinzufügen.

Diesen öffnen Sie über den VBA-Editor mit dem Menübefehl Extras|Verweise. Dort fügen Sie dann den genannten Eintrag hinzu (siehe Bild 11).

Verweis auf die Office-Bibliothek

Bild 11: Verweis auf die Office-Bibliothek

Nun fügen wir dem Ribbon-Element customUI das Attribut onLoad hinzu:

<customUI     xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="onLoad_Reihenfolge">

Die hier angegebene Ereignisprozedur onLoad_Reihenfolge hinterlegen wir wieder im Modul mdlRibbons. Die Prozedur weist lediglich der Variablen objRibbon_Reihenfolge einen Verweis auf das per Parameter mitgelieferte Objekt IRibbonUI zu:

Sub onLoad_Reihenfolge(ribbon As IRibbonUI)
     Set objRibbon_Reihenfolge = ribbon
End Sub

Diese Variable müssen wir nun noch deklarieren, was wir im gleichen Modul erledigen:

Public objRibbon_Reihenfolge As IRibbonUI

Nun bietet dieses Objekt verschiedene Methoden an, darunter auch die ActivateTab-Methode, die den Namen des zu aktivierenden Tab-Elements entgegennimmt. Wann und wie aber wollen wir diese Methode aufrufen Eigentlich sollte dies gleich beim Öffnen des Formulars geschehen, also etwa in der Ereignisprozedur für eine der Ereigniseigenschaften Beim Öffnen oder Beim Laden.

Wenn wir aber etwa für die Ereignisprozedur Form_Load die folgende Anweisung anlegen, gelingt das nicht:

Private Sub Form_Load()
     objRibbon_Reihenfolge.ActivateTab "tabReihenfolge"
End Sub

Wir erhalten dann nämlich die Fehlermeldung aus Bild 12, der dadurch ausgelöst wird, dass die Objektvariable noch nicht mit dem Verweis auf das customUI-Objekte gefüllt wurde. Das versuchen wir zu umgehen, indem wir das Aktivieren des Tab-Elements ein wenig verzögern. Dazu stellen wir die Eigenschaft Zeitgeberintervall des Hauptformulars auf den Wert 500 ein (für 500 Millisekunden) und für die Ereigniseigenschaft Bei Zeitgeber hinterlegen wir die folgende Ereignisprozedur:

Fehler beim Versuch, die ActiveTab-Methode zu nutzen

Bild 12: Fehler beim Versuch, die ActiveTab-Methode zu nutzen

Private Sub Form_Timer()
     objRibbon_Reihenfolge.ActivateTab "tabReihenfolge"
     Me.TimerInterval = 0
End Sub

Allerdings erhalten wir hier den gleichen Fehler. Woran liegt das Wir könnten annehmen, dass die Prozedur onLoad_Reihenfolge erst ausgeführt wird, wenn das Ribbon-Tab aus dieser Ribbon-Definition angezeigt wird. Allerdings scheint auch dies nicht der Fall zu sein. Wir können ja zwischendurch immer prüfen, ob objRibbon_Reihenfolge einen Wert hat – und zwar mit der folgenden VBA-Anweisung, abgesetzt im Direktbereich des VBA-Editors:

  objRibbon_Reihenfolge Is Nothing

Dies liefert aber aktuell immer den Wert True, objRibbon_Reihenfolge ist also leer. Die Lösung für dieses Problem war: Wir haben das Formular mehrfach aufgerufen und bereits zuvor dafür gesorgt, dass On_Load aufgerufen wurde. Damit war objRibbon_Reihenfolge gefüllt. Allerdings haben wir anschließend vermutlich durch einen Laufzeitfehler dafür gesorgt, dass die Variable wieder geleert wurde. Da On_Load aber bereits ausgeführt war, wurde sie nicht erneut gefüllt … Es gilt also zu beachten: Entweder Sie verhindern Laufzeitfehler durch entsprechend stabile Programmierung mit Fehlerbehandlungen, oder Sie müssen zwischendurch die Anwendung einmal neu laden, damit alle Ribbons et cetera wieder korrekt geladen werden können.

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

Schreibe einen Kommentar