Objekte im Ribbon verfügbar machen

Manchmal wird die Liste der Tabellen, Abfragen, Formulare und Co. im Navigationsbereich etwas unübersichtlich. Da wünscht sich der eine oder andere, dass die wichtigsten Elemente einer Datenbank schnell zur Verfügung stehen. Eine Möglichkeit, das zu erledigen, ist das Ribbon. Wie Sie die dort anzuzeigenden Elemente auswählen und diese dort hinzufügen, zeigt der vorliegende Beitrag.

Zwar verstummen allmählich die Stimmen, die eine Rückkehr des Datenbankfensters fordern, aber dass der Navigationsbereich nicht gerade die übersichtlichste Variante ist, um Datenbankobjekte anzuzeigen, ist offensichtlich (siehe Bild 1). Auf vielfachen Leserwunsch schauen wir uns daher einmal an, welche Möglichkeiten es gibt, Elemente wie Tabellen, Abfragen, Formulare, Berichte, Makros und Module über das Ribbon zugänglich zu machen.

Navigationsbereich

Bild 1: Navigationsbereich

Als Erstes benötigen wir eine Tabelle, in die wir die Elemente des Navigationsbereichs einlesen und der wir ein Feld hinzufügen, mit dem wir angeben, ob das jeweilige Element zusätzlich zur Anzeige im Navigationsbereich noch im Ribbon erscheinen soll. Dann stellen wir ein Formular zusammen, mit dem wir die Elemente anzeigen und die Möglichkeit bieten, diese für die Anzeige im Ribbon auszuwählen. Schließlich gibt es verschiedene Varianten, um Daten wie die beschriebenen Objekte im Ribbon anzuzeigen. Wir schauen uns die verschiedenen Varianten an und prüfen die Machbarkeit und Vor- und Nachteile.

Objekte in Tabelle

Zum Speichern der Objekte wollen wir die Tabelle tblObjekte-In-Ribbon verwenden, die im Entwurf wie in Bild 2 aussieht.

Tabelle zum Speichern der Objekte

Bild 2: Tabelle zum Speichern der Objekte

Die Tabelle verwendet neben dem Primärschlüsselfeld ID das Feld Objektname, in das wir den Namen der Tabelle, Abfrage et cetera eintragen. Für das Feld Objektname legen wir über die Eigenschaft Indiziert mit dem Wert Ja (Ohne Duplikate) einen eindeutigen Index fest. Damit stellen wir sicher, dass jedes Objekt nur einmal zur Tabelle hinzugefügt wird.

Das Feld ObjekttypID ist verknüpft mit der Tabelle tblObjekttypen, in der wir die sechs Objekttypen aufführen (siehe Bild 3). Das letzte Feld heißt InRibbon und hat den Datentyp Ja/Nein. Mit diesem Feld legen wir fest, ob das Objekt im Ribbon angezeigt werden soll oder nicht.

Die verschiedenen Objekttypen in der Tabelle tblObjekttypen

Bild 3: Die verschiedenen Objekttypen in der Tabelle tblObjekttypen

Achtung: Die Tabelle muss die Daten genau mit den Primärschlüsselwerten enthalten, wie sie hier abgebildet sind. Später verwenden wir im Code die Werte von 1 bis 6, um Elemente zu referenzieren, die zu einer der Objektkategorien gehören.

Prozedur zum Erfassen aller Objekte in der Tabelle

Schließlich benötigen wir eine Prozedur, mit der wir die Objekte der Datenbank durchlaufen und diese zur Tabelle tblObjekteInRibbon hinzufügen.

Diese sieht wie in Listing 1 aus. Die Prozedur deklariert die Variable db, die Sie mit einem Verweis auf das Database-Objekt der aktuellen Datenbank füllt. tdf und qdf haben die Typen TableDef und QueryDef und dienen zum Durchlauen der Tabellen und Abfragen.

Public Sub ObjekteInTabelleSchreiben()
     Dim db As DAO.Database
     Dim tdf As DAO.TableDef
     Dim qdf As DAO.QueryDef
     Dim objAccess As AccessObject
     Set db = CurrentDb
     On Error Resume Next
     For Each tdf In db.TableDefs
         db.Execute "INSERT INTO tblObjekteInRibbon(Objektname, ObjekttypID) VALUES('" & tdf.Name & "', 1)", dbFailOnError
     Next tdf
     For Each qdf In db.QueryDefs
         db.Execute "INSERT INTO tblObjekteInRibbon(Objektname, ObjekttypID) VALUES('" & qdf.Name & "', 2)", dbFailOnError
     Next qdf
     For Each objAccess In CurrentProject.AllForms
         db.Execute "INSERT INTO tblObjekteInRibbon(Objektname, ObjekttypID) VALUES('" & objAccess.Name _
             & "', 3)", dbFailOnError
     Next objAccess
     For Each objAccess In CurrentProject.AllReports
         db.Execute "INSERT INTO tblObjekteInRibbon(Objektname, ObjekttypID) VALUES('" & objAccess.Name _
             & "', 4)", dbFailOnError
     Next objAccess
     For Each objAccess In CurrentProject.AllMacros
         db.Execute "INSERT INTO tblObjekteInRibbon(Objektname, ObjekttypID) VALUES('" & objAccess.Name _
             & "', 5)", dbFailOnError
     Next objAccess
     For Each objAccess In CurrentProject.AllModules
         db.Execute "INSERT INTO tblObjekteInRibbon(Objektname, ObjekttypID) VALUES('" & objAccess.Name _
             & "', 6)", dbFailOnError
     Next objAccess
End Sub

Listing 1: Prozedur zum Einlesen aller Access-Objekte in die Tabelle tblObjekteInRibbon

objAccess hat den Typ Access-Object und erlaubt das Durchlaufen der Auflistungen AllForms, AllReports, AllMacros und AllModules der CurrentProject-Klasse.

Die Fehlerbehandlung deaktivieren wir mit On Error Resume Next. Der Hintergrund ist, dass beim erneuten Einlesen der Objekte gegebenenfalls vorhandene Elemente gleichen Namens zu Fehlern führen können, da der eindeutige Index für das Feld Objektname verletzt wird. Dies wollen wir einfach ignorieren und Objekte, deren Namen bereits vorhanden sind, einfach nicht nochmals hinzufügen.

In der ersten For Each-Schleife durchläuft die Prozedur alle Elemente der TableDefs-Auflistung des Database-Objekts und trägt für jedes Element einen neuen Datensatz in die Tabelle tblObjekteInRibbon ein.

Dabei wird als Objektname der Wert der Eigenschaft Name des TableDef-Objekts und als ObjekttypID der Wert 1 eingetragen.

Die zweite For Each-Schleife erledigt das Gleiche für die Elemente der Auflistung QueryDefs. Hier fügt sie der Tabelle jedoch für das Feld ObjekttypID den Wert 2 hinzu.

Die dritte bis sechste For Each-Schleife der Prozedur verwendet die Auflistungen AllForms, AllReports, AllMacros und AllModules des CurrentProject-Objekts, um die Formulare, Berichte, Makros und Module der Datenbank zu ermitteln. Dabei nutzen wir jeweils die Name-Eigenschaft des AccessObject-Elements als Wert für das Feld Objektname. Für das Feld ObjekttypID tragen wir je nach Objekttyp die Werte 3, 4, 5 oder 6 ein. Das Ergebnis sieht wie in Bild 4 aus.

Die Tabelle tblObjekteInRibbon mit den Objekten der Datenbank

Bild 4: Die Tabelle tblObjekteInRibbon mit den Objekten der Datenbank

Formular zur Auswahl der anzuzeigenden Elemente

Nun benötigen wir ein Formular, dass die Elemente der Datenbank in alphabetischer Reihenfolge und nach Objekttyp aufgeteilt anzeigt und das Markieren der im Ribbon anzuzeigenden Objekte erlaubt. Dazu erstellen wir ein neues Formular namens frmObjekteInRibbon. Das Formular soll seine Daten in einem Register-Steuerelement mit sechs Registerseiten anzeigen, die jeweils ein Unterformular enthalten. Das Unterformular soll die Elemente des jeweiligen Objekttyps anzeigen. Da das Unterformular jeder Registerseite die Daten aus der gleichen Tabelle anzeigen soll, die nur unterschiedlich gefiltert werden, benötigen wir nur ein Formular, das dann in den sechs Unterformular-Steuerelementen angezeigt wird.

Wir legen als Erstes das Formular frmObjekteInRibbon an und fügen das Register-Steuerelement hinzu. Dann wählen wir aus dem Kontextmenü dieses Steuerelements so oft den Eintrag Seite einfügen aus, bis das Register-Steuerelement sechs Registerseiten enthält (siehe Bild 5). Die sechs Registerseiten beschriften wir über die Eigenschaft Beschriftung mit Tabellen, Abfragen, Formulare, Berichte, Makros und Module. Die Seiten erhalten die Namen pgeTabellen, pgeAbfragen, pgeFormulare, pgeBerichte, pgeMakros und pgeModule.

Hinzufügen von Registerseiten zum Register-Steuerelement

Bild 5: Hinzufügen von Registerseiten zum Register-Steuerelement

Das Unterformular sfmObjekteInRibbon statten wir mit einer Abfrage namens qryObjekteInRibbonNachObjektname als Datensatzquelle aus, welche alle Felder der Tabelle tblObjekteInRibbon enthält und diese nach dem Feld Objektname sortiert (siehe Bild 6).

Datensatzquelle des Formulars sfmObjekteInTabelle

Bild 6: Datensatzquelle des Formulars sfmObjekteInTabelle

Wir fügen dem Formular die beiden Felder InRibbon und Objektname der Datensatzquelle hinzu. Außerdem stellen wir die Eigenschaft Standardansicht auf Datenblatt ein.

Danach speichern und schließen Sie das Unterformular sfm-ObjekteInRibbon. Für das Formular frmObjekteInRibbon stellen wir noch die Eigenschaften Datensatzmarkierer, Navigationsschaltflächen und Bildlaufleisten auf Nein ein und die Eigenschaft Automatisch zentrieren auf Ja.

Dann folgt ein wenig Kleinarbeit: das Einfügen des Unterformulars in das Register-Steuerelement. Hier gibt es zwei Möglichkeiten:

  • Entweder wir fügen auf jeder Registerseite ein neues Unterformular-Steuerelement ein, das wir dann jeweils nach dem Wert für das Feld ObjekttypID filtern, der die Objekte passend zur Beschriftung der Registerseite liefert.
  • Oder wir platzieren ein Unterformular-Steuerelement in z-Reihenfolge vor dem Register-Steuerelement und ändern den Filter jeweils bei Änderung der ausgewählten Registerseite.

Wer schon einmal auf mehreren Registerseiten ein Steuer-element so eingefügt hat, dass es sich beim Blättern im Register immer an der gleichen Position befindet, weiß, dass das eine langweilige Arbeit ist. Also entscheiden wir uns für die zweite Variante mit nur einem Unterformular, das wir einfach vor dem Register-Steuerelement platzieren. Dazu fügen wir dieses zuerst unter oder neben dem Register-Steuerelement ein, entfernen das Beschriftungsfeld und schieben es dann über das Register-Steuerelement (siehe Bild 7).

Unterformular-Steuerelement über Register-Steuerelement

Bild 7: Unterformular-Steuerelement über Register-Steuerelement

Damit sich beide beim Ändern der Formulargröße der Größe anpassen, stellen wir die Eigenschaften Horizontaler Anker und Vertikaler Anker jeweils auf Beide ein.

Nun müssen wir nur noch dafür sorgen, dass das Unterformular nur noch die Elemente anzeigt, die dem im Register-Steuerelement ausgewählten Objekttyp entsprechen. Dazu hinterlegen wir für die Ereigniseigenschaft Bei Änderung des Register-Steuerelements, das wir zuvor noch mit regObjekte benennen, die folgende Ereignisprozedur:

Private Sub regObjekte_Change()
     With Me!sfmObjekteInRibbon.Form
         .Filter = "ObjekttypID = " & Me!regObjekte.Value + 1
         .FilterOn = True
     End With
End Sub

Diese stellt die Eigenschaft Filter des Unterformulars auf einen Ausdruck ein, der den Wert der jeweils ausgewählten Registerseite ermittelt, eins hinzuaddiert und diesen mit dem Wert des Feldes ObjekttypID gleichsetzt. Dabei kommt dann etwa für die erste Registerseite das folgende Kriterium heraus:

ObjekttypID = 1

Wenn wir das Formular nun öffnen, erscheinen allerdings zunächst alle Elemente in der Liste (siehe Bild 8).

Das Unterformular zeigt noch alle Einträge an.

Bild 8: Das Unterformular zeigt noch alle Einträge an.

Wenn wir allerdings die Ereignisprozedur regObjekte_Change einmal beim Laden des Formulars aufrufen, erhalten wir auch direkt nach dem Öffnen die korrekt gefilterten Elemente (siehe Bild 9).

Objekte gefiltert nach Objekttyp, hier alle Tabellen

Bild 9: Objekte gefiltert nach Objekttyp, hier alle Tabellen

Die Ereignisprozedur, die durch das Ereignis Beim Laden ausgelöst wird, sieht dann so aus:

Private Sub Form_Load()
     regObjekte_Change
End Sub

Verwalten der Objekte

Wir wollen noch ein paar weitere Elemente hinzufügen, damit der Benutzer die Objekte im Formular einfacher verwalten kann. Die dazu angelegten Schaltflächen sehen Sie in Bild 10. Damit die Schaltflächen nicht unter den anderen Steuerelementen verschwinden, wenn der Benutzer das Formular nach unten vergrößert, stellen wir die Eigenschaft Vertikaler Anker auf Unten ein.

Objekte verwalten mit zusätzlichen Schaltflächen

Bild 10: Objekte verwalten mit zusätzlichen Schaltflächen

Alle Objekte löschen

Die Schaltfläche mit der Beschriftung Alle löschen heißt cmdAlleLoeschen und soll alle Datensätze aus der Tabelle tblObjekteInRibbon löschen. Auf diese Weise kann der Benutzer die Objekte nach umfangreicheren Änderungen anschließend wieder neu einlesen. Die Schaltfläche löst beim Anklicken die Ereignisprozedur aus Listing 2 aus. Diese zeigt zunächst noch eine Meldung an, die den Benutzer darauf hinweist, dass alle Datensätze gelöscht werden. Der Benutzer kann dies durch Betätigen der Nein-Schaltfläche abwenden. Ansonsten sorgt eine DELETE-Abfrage für das Löschen aller Datensätze der Tabelle tblObjekteInRibbon. Die folgende Anweisung aktualisiert die Anzeige der Daten im Unterformular.

Private Sub cmdAlleLoeschen_Click()
     Dim db As DAO.Database
     Set db = CurrentDb
     If MsgBox("Dies löscht alle Elemente. Diese müssen danach neu eingelesen werden.", vbYesNo) = vbYes Then
         db.Execute "DELETE FROM tblObjekteInRibbon", dbFailOnError
         Me!sfmObjekteInRibbon.Form.Requery
     End If
End Sub

Listing 2: Beim Klicken-Prozedur der Schaltfläche cmdAlleLoeschen

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