Home > Artikel > Ausgabe 2/2018 > Daten im Ribbon anzeigen

Daten im Ribbon anzeigen

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Im Artikel Ribbon für die Handyverwaltung haben wir ein Ribbon für eine bestehende Anwendung angelegt. Dort gibt es einige Übersichtsformulare, die man per Ribbon aufrufen kann. Aber warum erst die Übersicht anzeigen, wenn man auch direkt über das Ribbon auf die Details eines Datensatzes zugreifen kann? Zum Beispiel, indem man die Elemente per Kombinationsfeld oder auf andere Art und Weise darstellt? Dieser Artikel stellt die Möglichkeiten des Ribbons zur Anzeige von Daten aus den Tabellen der Datenbank vor.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1802_DatenImRibbon.accdb.

Listenelemente

Das Ribbon bietet fünf verschiedene Elemente, mit denen Sie Listen anzeigen können:

  • comboBox: Entspricht etwa einem Kombinationsfeld unter Access, allerdings ohne die Möglichkeit der Eingabe von Daten.
  • dropDown: wie comboBox, allerdings mit mehr Möglichkeiten
  • dynamicMenu: eine weitere Alternative, deren Besonderheit darin besteht, seinen Inhalt im XML-Format entgegenzunehmen
  • gallery: Kann Elemente in mehreren Spalten und Zeilen anzeigen und außerdem Abbildungen darstellen.
  • menu: Nimmt normale Menüeintrage wir früher unter Access 2003 und älter auf, bietet aber zusätzlich die Möglichkeit zur Angabe einer Beschreibung.

Das comboBox-Element

Das comboBox-Element können Sie statisch per XML-Code füllen oder auch dynamisch über entsprechende Callback-Funktionen. Ein Beispiel für ein statisches comboBox-Element definieren wir wie folgt:

Das Ergebnis finden Sie in Bild 1. Damit die Bilder angezeigt werden, benötigen Sie weiteren Code, den wir im Artikel Ribbon für die Handyverwaltung beschreiben.

Beispiel einer comboBox

Bild 1: Beispiel einer comboBox

comboBox dynamisch füllen

Das können wir auch dynamisch hinbekommen. Dazu fügen wir einem neuen comboBox-Element namens cboProviderDynamisch einfach vier weitere Attribute hinzu, nämlich getItemCount, getItemLabel und getItemID. Die Definition des Elements sieht danach wie folgt aus:

id="cboProviderDynamisch"

getItemCount="getItemCount"

getItemLabel="getItemLabel"

getItemID="getItemID"/>

Für die drei Callback-Attribute hinterlegen wir entsprechende Prozeduren. Dabei ist eine kleine Vorbemerkung nötig. Die Callback-Prozeduren werden nämlich nach einem bestimmten Schema aufgerufen. Die Callback-Prozedur für das Attribut getItemCount wird einmal zu Beginn aufgerufen. Diese erwartet als Rückgabewert vor allem einen Wert für den Parameter count, der die Anzahl der anzuzeigenden Einträge enthalten sollte. Die anderen beiden Callbacks für die Attribute getItemID und getItemLabel werden entsprechend der Anzahl der mit count ermittelten Einträge aufgerufen. Dabei übergibt der zweite Parameter jeweils den Wert für den Index des aktuellen Durchlaufs an. Das heißt, das wir optimalerweise in der Prozedur getItemCount ein Array anlegen, das wir mit den beim Zählen und dabei Durchlaufen der Datensätze mit den relevanten Daten, also dem Index und der Beschriftung füllen. Damit wir dieses zweidimensionale Array in der ersten Prozedur füllen und anschließend in den beiden Prozeduren getItemID und getLabelID auslesen können, deklarieren wir es im Kopf unseres Moduls namens mdlRibbon, in dem sich auch die übrigen Ribbon-spezifischen Prozeduren befinden:

Dim strProvider() As String

Diese nutzen wir dann in der Prozedur getItemCount, die wir wie in Listing 1 aufbauen. Sie ermittelt die anzuzeigenden Daten aus der Tabelle tblProvider über ein Recordset, das sie anschließend in einer Do While-Schleife durchläuft. Dabei erweitert sie zunächst die Anzahl der Einträge im Array mit der Redim-Anweisung, wobei wir die Anzahl der ersten Dimension auf 2 und die der zweiten Dimension auf die aktuelle Anzahl der Datensätze plus eins einstellen und die bereits eingetragenen Elemente durch das Preserve-Schlüsselwort beibehalten. Dann schreibt die Prozedur innerhalb der Schleife den Wert des Feldes ProviderID in die erste Spalte des Arrays und den des Feldes Bezeichnung in die zweite Spalte. Außerdem erhöht sie die Zählervariable i um eins.

Sub getItemCount(control As IRibbonControl, ByRef count)

     Dim db As DAO.Database

     Dim rst As DAO.Recordset

     Dim i As Integer

     Set db = CurrentDb

     Set rst = db.OpenRecordset("SELECT * FROM tblProvider", dbOpenDynaset)

     Do While Not rst.EOF

         ReDim Preserve strProvider(2, i + 1) As String

         strProvider(0, i) = rst!ProviderID

         strProvider(1, i) = rst!Bezeichnung

         i = i + 1

         rst.MoveNext

     Loop

     count = i

     rst.Close

     Set rst = Nothing

     Set db = Nothing

End Sub

Listing 1: Ermitteln der Anzahl der einzulesenden Datensätze und Speichern der Datensätze in einem Array

Danach trägt sie den Wert von i für den Rückgabeparameter count ein.

Nun haben wir beispielsweise den Wert 3 zurückgegeben. Das bedeutet, dass die beiden Prozeduren getItemID und getItemLabel jeweils drei Mal aufgerufen werden. Die Prozedur getItemID sieht dabei beispielsweise wie folgt aus:

Sub getItemID(control As IRibbonControl, _

index As Integer, ByRef id)

id = strProvider(0, index)

End Sub

Die Prozedur erhält mit control einen Verweis auf das aufrufende Ribbon-Element und mit index die Nummer des aktuell auszulesenden Elements. Außerdem hat sie einen Rückgabeparameter namens id. Die einzige Zeile dieser Prozedur trägt den Wert des Array für die erste Spalte und die mit index übergebene Spalte in die Variable id für den Rückgabewert ein.

Die Prozedur getItemLabel arbeitet auf identische Weise. Der Unterschied ist, dass der Rückgabeparameter label heißt und das wir diesem den Wert aus der zweiten Spalte und den angegebenen Index aus dem Array zuweisen:

Sub getItemLabel(control As IRibbonControl, _

index As Integer, ByRef label)

label = strProvider(1, index)

End Sub

Das Ergebnis sieht wie in Bild 2 aus, also prinzipiell genauso wie beim ersten Beispiel. Die Beispielbilder haben wir weggelassen, da es ja auch keine in der Tabelle tblProvider gespeicherten Bilder für diese Einträge gibt.

Dynamisch gefülltes comboBox-Element

Bild 2: Dynamisch gefülltes comboBox-Element

Beim Auswählen eines Eintrags

Wenn der Benutzer nun einen der Einträge auswählt, wollen wir diese Auswahl natürlich auch auswerten können. Dazu nutzen wir im Falle des comboBox-Elements das Attribut onChange, das wir wie folgt zum Element hinzufügen:

id="cboProviderDynamisch"

onChange="onChange"

getItemCount="getItemCount"

getItemLabel="getItemLabel"

getItemID="getItemID"/>

Wenn der Benutzer nun einen der Einträge auswählt, soll ein Meldungsfenster die Bezeichnung des gewählten Eintrags ausgeben, was wie in Bild 3 aussieht.

Auswertung des gewählten Eintrags

Bild 3: Auswertung des gewählten Eintrags

Dazu legen wir die folgende Prozedur an:

Sub onChange(control As IRibbonControl, text As String)

MsgBox "Sie haben den Eintrag '" _

& text & "' ausgewählt."

End Sub

Das ist ja sehr praktisch, dass der Parameter text direkt die Bezeichnung des gewählten Elements liefert. Wenn man allerdings nicht wie im Beispiel einfach nur die Bezeichnung ausgeben, sondern etwas mit dem zugrunde liegenden Datensatz erledigen möchte, wird es kompliziert – man müsste dann per DLookup erst den Primärschlüsselwert zu diesem Eintrag ermitteln und könnte erst dann weiterarbeiten. Allerdings gibt es auch keinen Ausweg – es sei denn, Sie setzen auf das zweite in diesem Artikel vorgestellte Steuer­element, das dropDown-Element!

Das dropDown-Element

Wenn man wie wir ein dropDown-Element genauso ausstattet wie das eingangs beschriebene comboBox-Element und beide genau gleich aussehen, fragt man sich natürlich, wozu Microsoft überhaupt zwei solcher Steuer­elemente vorgesehen hat (siehe Bild 4). Hier sehen Sie den Code, der für das bis auf die Bilder, die wir schlicht eingespart haben, identische dropDown-Element nötig ist:

Eineiiger Zwilling des comboBox-Elements – aber nur optisch: das dropDown-Element

Bild 4: Eineiiger Zwilling des comboBox-Elements – aber nur optisch: das dropDown-Element

Die Unterschiede werden erst dann offensichtlich, wenn wir uns die Attribute und hier speziell die Callback-Attribute ansehen.

Ein voll ausgestattes dropDown-Element sieht beispielsweise wie folgt aus:

id="drpProviderDynamisch"

onAction="onActionDropDown"

getItemCount="getItemCount"

getItemLabel="getItemLabel"

getItemID="getItemID"

getSelectedItemID="getSelectedItemID"/>

Hier sehen Sie schon, dass es kein onChange-Attribut gibt, das beim Auswählen eines Eintrags ausgewählt wird, sondern stattdessen ein onAction-Attribut. Außerdem finden wir hier zusätzlich ein Attribut namens getSelectedItemID.

Wir können die für das comboBox-Element verwendeten Prozeduren getItemCount, getItemLabel und getItemID beibehalten beziehungsweise mitnutzen. Neu hinzugefügt haben wir die Callback-Prozedur getSelectedItemID, die wie folgt aussieht:

Sub getSelectedItemID(control As IRibbonControl, _

ByRef index)

index = strProvider(0, 1)

End Sub

Diese Prozedur weist als Rückgabeparameter den Parameter index auf, mit dem Sie den Wert des ausgewählten Eintrags festlegen können. Wir stellen diesen hier auf den Wert der ersten Spalte des ersten Eintrags des Arrays strProvider ein. Dies sorgt dafür, dass der entsprechende Eintrag direkt beim Anzeigen des dropDown-Elements vorausgewählt wird (siehe Bild 5).

Voreinstellung eines Eintrags im dropDown-Element

Bild 5: Voreinstellung eines Eintrags im dropDown-Element

Es gibt noch eine zweites, ähnliches Callback-Attribut namens getSelectedItemIndex. Damit können Sie den auszuwählenden Index zurückgeben.

Ausgewählten Eintrag synchronisieren

Interessant wird es natürlich, wenn Sie über das dropDown-Element einen Eintrag auswählen, dessen Detailseite angezeigt werden soll. Wenn der Benutzer dann einen anderen Eintrag in der Detailseite anzeigt, soll auch der aktuell im dropDown-Element ausgewählte Eintrag aktualisiert werden. Dies erreichen wir allerdings nur, wenn wir ein paar weitere Elemente zum Ribbon und zum Code hinzufügen. Das erste ist das Callback-Attribut onLoad, welches Sie wie in Listing 2 mit dem Wert onLoad_Main versehen. Für dieses legen wir die folgende Callback-Prozedur fest:

   

     

       ...

       

         

           ...

           

             getItemLabel="getItemLabel" getItemID="getItemID" getSelectedItemID="getSelectedItemID"/>

         

       

     

   

Listing 2: Ribbon-Definition mit onLoad-Methode

Sub onLoad_Main(ribbon As IRibbonUI)

Set objRibbon_Main = ribbon

End Sub

Diese Prozedur hat nur eine Aufgabe: Sie erhält über den Parameter ribbon einen Verweis auf die auslösende Ribbon-Definition und speichert diesen in der Variablen objRibbon_Main. Diese deklarieren wir im allgemeinen Teil des Moduls mdlRibbon wie folgt mit dem Datentyp IRibbonUI:

Public objRibbon_Main As IRibbonUI

Dies sorgt dafür, dass gleich nach dem Anzeigen der Elemente der Ribbon-Definition (dies kann ja auch nur eine einzige Schaltfläche sein, die Sie einer bestehenden Ribbon-Gruppe hinzugefügt haben) ein Verweis darauf in der Variablen objRibbon_Main landet.

Was haben wir nun davon? Dieses Objekt bietet uns nun die zum Beispiel Möglichkeit, eine der beiden Methoden Invalidate oder InvalidateControl aufzurufen. Die erste sorgt dafür, dass alle Elemente, welche Ihre Werte über Callback-Attribute erhalten, beim nächsten Erscheinen neu mit den entsprechenden Eigenschaftswerten gefüllt werden. Die zweite erwartet den Namen des betroffenen Ribbon-Elements als Parameter und aktualisiert nur die Callback-Attribut dieses einen Elements.

Wir machen nun folgendes: Den Wert des Primärschlüsselfeldes des Eintrags der Tabelle tblProvider, welchen das dropDown-Element drpProviderDynamisch anzeigen soll, speichern wir in einer Variablen, die wir wie folgt deklarieren:

Dim lngAktuellerProviderID As Long

Den Wert dieser Variablen übergeben wir nun in der Callback-Prozedur, die durch das Callback-Attribut getSelectedItemID ausgelöst wird. Sollte lngAktuellerProviderID zu diesem Zeitpunkt noch den Wert 0 aufweisen, lesen wir per DLookup den ersten Wert der Tabelle tblProvider in diese Variable ein:

Sub getSelectedItemID(control As IRibbonControl, _

ByRef index)

If lngAktuellerProviderID = 0 Then

lngAktuellerProviderID = DLookup("ProviderID", _

"tblProvider")

End If

index = lngAktuellerProviderID

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!