{"id":55001415,"date":"2023-02-01T00:00:00","date_gmt":"2023-06-17T09:32:39","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1415"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Datensatznavigation_per_Ribbon","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/","title":{"rendered":"Datensatznavigation per Ribbon"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg08.met.vgwort.de\/na\/232ccab92853462386eed7c903af7c1b\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2023_01\/pic_1415_001.png\" alt=\"Daten in der Datenblattansicht\" width=\"599,559\" height=\"381,386\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Daten in der Datenblattansicht<\/span><\/b><\/p>\n<p><b>Die Navigationszeile am unteren Rand von Formularen oder Unterformularen in der Datenblattansicht ist recht fummelig und f&auml;llt nicht auf den ersten Blick auf, wenn man nicht gewohnt ist, damit zu arbeiten. Es gibt eine Menge L&ouml;sungen, bei denen diese Steuerelemente in Form von Formular-Schaltfl&auml;chen bereitgestellt werden. Uns ist aber noch keine L&ouml;sung &uuml;ber den Weg gelaufen, bei der die Navigationssteuerelemente im Ribbon abgebildet wurden. Zwar gibt es einen eigenen Bereich, der Werkzeuge f&uuml;r den Umgang mit der Datenblattansicht bereitstellt, aber dieser bietet keine Steuerelemente zum Navigieren in den Datens&auml;tzen. Aber kein Problem: Wir liefern das nach!<\/b><\/p>\n<p>Wenn wir eine Tabelle in einem Formular in der Datenblattansicht anzeigen wie in Bild 1, sehen wir am unteren Rand des Formulars die Navigationssteuerelemente &#8211; also Schaltfl&auml;chen und ein Textfeld mit den folgenden Funktionen:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2023_01\/pic_1415_001.png\" alt=\"Daten in der Datenblattansicht\" width=\"599,559\" height=\"381,386\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Daten in der Datenblattansicht<\/span><\/b><\/p>\n<ul>\n<li>Ersten Datensatz anzeigen\/markieren<\/li>\n<li>Vorherigen Datensatz anzeigen\/markieren<\/li>\n<li>Ausgabe des aktuellen Datensatzes und der gesamten Anzahl samt Eingabe des Datensatzindex, zu dem navigiert werden soll<\/li>\n<li>N&auml;chsten Datensatz anzeigen\/markieren<\/li>\n<li>Letzten Datensatz anzeigen\/markieren<\/li>\n<li>Neuen Datensatz anzeigen\/markieren<\/li>\n<\/ul>\n<p>Es w&auml;re doch praktisch, wenn diese wichtigen Steuerelemente nicht klein und ganz unten angezeigt w&uuml;rden, sondern oben prominent im Ribbon &#8211; sodass der Benutzer diese nicht &uuml;bersehen kann!<\/p>\n<p>Also schauen wir uns in diesem Beitrag an, wie wir dies realisieren k&ouml;nnen.<\/p>\n<h2>Verhalten der Navigationssteuerelemente untersuchen<\/h2>\n<p>Da wir das Verhalten der oben genannten Steuerelemente m&ouml;glichst genau abbilden wollen, m&uuml;ssen wir es zun&auml;chst studieren. In der Regel &ouml;ffnet man ein Formular mit Daten und erh&auml;lt den ersten Datensatz der Datensatzquelle. In diesem Zustand sind alle Steuerelemente mit Ausnahme der Schaltfl&auml;che zum Anzeigen des vorherigen Datensatzes aktiviert. Das ergibt Sinn, denn man kann nicht zu einem fr&uuml;heren Datensatz springen, wenn schon der erste Datensatz angezeigt wird. Aber kann man zum ersten Datensatz springen, wenn schon der erste angezeigt wird? Man k&ouml;nnte sich streiten, ob die Schaltfl&auml;che zum Ansteuern des ersten Datensatzes aktiviert sein muss, wenn der erste Datensatz angezeigt wird, aber Tatsache ist: Unter Access ist es so.<\/p>\n<p>Die n&auml;chste zu untersuchende Situation ist die, wenn sich der Datensatzzeiger irgendwo zwischen dem ersten und dem letzten Datensatz befindet. Hier sind immer alle Schaltfl&auml;chen aktiviert.<\/p>\n<p>Das ist auch bei der Anzeige des letzten Datensatzes der Fall! Warum aber ist hier die Schaltfl&auml;che zum Anzeigen des n&auml;chsten Datensatzes aktiviert, obwohl wir ja eigentlich nicht mehr zu einem weiteren Datensatz springen k&ouml;nnen?<\/p>\n<p>Ganz einfach: Unter Access k&ouml;nnen wir in dieser Situation noch zu einem neuen, leeren Datensatz springen, wenn wir diese Schaltfl&auml;che anklicken.<\/p>\n<h2>Sonderfall nicht aktualisierbare Datensatzquelle<\/h2>\n<p>Eine Situation f&uuml;hrt &uuml;brigens dazu, dass auch die Schaltfl&auml;che zum Anzeigen eines neuen Datensatzes einmal deaktiviert ist: dann n&auml;mlich, wenn das Formular Daten anzeigt, die nicht aktualisierbar sind.<\/p>\n<p>Und dann wird auch die Schaltfl&auml;che zum Anzeigen des n&auml;chsten Datensatzes deaktiviert, wenn sich der Datensatzzeiger auf dem letzten Datensatz befindet.<\/p>\n<p>Dieses Verhalten k&ouml;nnen wir f&uuml;r ein Formular &uuml;brigens relativ einfach abbilden &#8211; wir m&uuml;ssen dazu nur die Eigenschaft <b>Recordsettyp <\/b>auf <b>Snapshot <\/b>einstellen oder eine nicht aktualisierbare Abfrage zusammenstellen.<\/p>\n<p>Die hier definierten Regeln wollen wir beim Programmieren der Ribbonanpassung zum Steuern der Datensatzanzeige ber&uuml;cksichtigen.<\/p>\n<h2>Aussehen des Ribbons definieren<\/h2>\n<p>Das geplante Ribbon soll wie in Bild 2 aussehen. Es enth&auml;lt also f&uuml;nf Schaltfl&auml;chen sowie ein <b>EditBox<\/b>-Element, das die aktuelle Position des Datensatzzeigers anzeigt und auch die Eingabe einer neuen Position erlaubt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2023_01\/pic_1415_002.png\" alt=\"So soll das Ribbon zur Datensatznavigation aussehen.\" width=\"649,559\" height=\"305,0805\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: So soll das Ribbon zur Datensatznavigation aussehen.<\/span><\/b><\/p>\n<p>Was wir hier nicht beschreiben, aber dennoch ben&ouml;tigt wird und in der Beispieldatenbank enthalten ist:<\/p>\n<ul>\n<li>das Modul <b>mdlRibbonImages<\/b>, das Funktionen enth&auml;lt, mit denen wir die Bilder aus der Tabelle <b>MSysResources <\/b>auslesen und in geeigneter Form f&uuml;r die Anzeige im Ribbon bereitstellen<\/li>\n<li>die Funktion <b>LoadImages <\/b>im Modul <b>mdlRibbons<\/b>, welches wir f&uuml;r das Attribut <b>loadImages <\/b>des <b>customUI<\/b>-Elements des Ribbons hinterlegen und die daf&uuml;r sorgt, dass f&uuml;r jedes Element, welches das <b>image<\/b>-Attribut enth&auml;lt, das entsprechende Bild aus der Tabelle <b>MSysResources <\/b>geladen wird.<\/li>\n<\/ul>\n<p>Davon ab nutzen wir eine Tabelle namens <b>USysRibbons<\/b>, in der wir die Ribbondefinition im XML-Format speichern.<\/p>\n<p>Diese enth&auml;lt drei Felder, n&auml;mlich <b>RibbonID <\/b>(Prim&auml;rschl&uuml;sselfeld mit Autowert), <b>RibbonName <\/b>(Datentyp <b>Kurzer Text<\/b>) und <b>RibbonXML <\/b>(Datentyp <b>Langer Text<\/b>). Darin speichern wir die n&ouml;tigen Informationen wie in Bild 3.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2023_01\/pic_1415_003.png\" alt=\"Tabelle zum Speichern der Ribbondefinition\" width=\"649,559\" height=\"276,4886\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Tabelle zum Speichern der Ribbondefinition<\/span><\/b><\/p>\n<p>Nun schauen wir uns die darin enthaltene Ribbondefinition an. Diese haben wir in Listing 1 abgebildet. Das Element <b>customUI <\/b>enth&auml;lt die beiden Attribute <b>onLoad <\/b>und <b>loadImage<\/b>, welche die beim Laden des Ribbons und f&uuml;r die Anzeige von Bildern ben&ouml;tigten VBA-Prozeduren angeben. Die f&uuml;r <b>onLoad <\/b>hinterlegte Prozedur <b>OnLoad_Navigation <\/b>wird direkt beim Laden ausgel&ouml;st, die f&uuml;r <b>loadImage <\/b>hinterlegte f&uuml;r jedes Element, welches das Attribut <b>image <\/b>aufweist und somit ein Bild anzeigen soll.<\/p>\n<pre>&lt;?xml version=\"1.0\"?&gt;\r\n&lt;customUI xmlns=\"http:\/\/schemas.microsoft.com\/office\/2009\/07\/customui\" onLoad=\"OnLoad_Navigation\" loadImage=\"loadImage\"&gt;\r\n     &lt;ribbon&gt;\r\n         &lt;tabs&gt;\r\n             &lt;tab id=\"tabNavigation\" getLabel=\"getLabel\"&gt;\r\n                 &lt;group id=\"grpNavigation\" label=\"Datensatznavigation\"&gt;\r\n                     &lt;button image=\"navigate_beginning\" getEnabled=\"getEnabled\" label=\"Erster Datensatz\" \r\n                         id=\"btnErster\" onAction=\"onAction\" size=\"large\"\/&gt;\r\n                     &lt;button image=\"navigate_left\" getEnabled=\"getEnabled\" label=\"Vorheriger Datensatz\" \r\n                         id=\"btnVorheriger\" onAction=\"onAction\" size=\"large\"\/&gt;\r\n                     &lt;editBox label=\"Aktueller Datensatz\" id=\"txtAktuellerDatensatz\" getText=\"getText\" \r\n                         onChange=\"onChange\" sizeString=\"100 von 100\" getEnabled=\"getEnabled\"\/&gt;\r\n                     &lt;button image=\"navigate_right\" getEnabled=\"getEnabled\" label=\"N&auml;chster Datensatz\" \r\n                         id=\"btnNaechster\" onAction=\"onAction\" size=\"large\"\/&gt;\r\n                     &lt;button image=\"navigate_end\" getEnabled=\"getEnabled\" label=\"Letzter Datensatz\" \r\n                         id=\"btnLetzter\" onAction=\"onAction\" size=\"large\"\/&gt;\r\n                     &lt;button image=\"add\" getEnabled=\"getEnabled\" label=\"Neuer Datensatz\" id=\"btnNeu\" \r\n                         onAction=\"onAction\" size=\"large\"\/&gt;\r\n                 &lt;\/group&gt;\r\n             &lt;\/tab&gt;\r\n         &lt;\/tabs&gt;\r\n     &lt;\/ribbon&gt;\r\n&lt;\/customUI&gt;<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Definition des Ribbons f&uuml;r die Datensatznavigation<\/span><\/b><\/p>\n<h2>Vorbereitung zum Aktualisieren der Ribbonelemente<\/h2>\n<p>Wenn wir zur Laufzeit die Eigenschaften von Ribbonelementen aktualisieren wollen, was hier absehbar ist, weil Schaltfl&auml;chen aktiviert und deaktiviert werden sollen und auch das <b>editBox<\/b>-Element die jeweilige Position des Datensatzzeigers anzeigen soll, m&uuml;ssen wir eine Variable des Typs <b>IRibbonUI <\/b>deklarieren. Dieses bietet die Methode <b>Invalidate <\/b>an, mit der wir daf&uuml;r sorgen k&ouml;nnen, dass die Attribute wie <b>getEnabled<\/b>, <b>getText <\/b>et cetera ihre Werte per Callbackprozedur erneut abrufen. Diese Variable deklarieren wir wie folgt:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>objRibbon_Navigation<span style=\"color:blue;\"> As <\/span>IRibbonUI<\/pre>\n<p>Au&szlig;erdem implementieren wir die f&uuml;r das Attribut <b>onLoad<\/b> hinterlegte Prozedur wie folgt, damit diese mit der Variablen <b>objRibbon_Navigation <\/b>gleich beim Laden einen Verweis auf die angewendete Ribbondefinition hinterlegt:<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>onLoad_Navigation(ribbon<span style=\"color:blue;\"> As <\/span>IRibbonUI)\r\n     <span style=\"color:blue;\">Set<\/span> objRibbon_Navigation = ribbon\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Unterhalb des <b>customUI<\/b>-Elements befinden sich die obligatorischen <b>ribbon<\/b>-, <b>tabs<\/b>&#8211; und <b>tab<\/b>-Elemente. Das <b>tab<\/b>-Element mit der Bezeichnung <b>tabNavigation <\/b>enth&auml;lt das Callback-Attribut <b>getLabel<\/b>, welches die Beschriftung des <b>tab<\/b>-Elements ermitteln soll. Diese Beschriftung soll entweder den Wert der Eigenschaft <b>Beschriftung <\/b>des Formulars enthalten oder, wenn diese nicht angegeben wurde, den Namen des Formulars als <b>tab<\/b>-Beschriftung anzeigen.<\/p>\n<h2>tab-Beschriftung ermitteln<\/h2>\n<p>Die f&uuml;r das Attribut <b>getLabel <\/b>hinterlegte Prozedur wird direkt beim Anzeigen des Ribbons aufgerufen und sieht wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>getLabel(control<span style=\"color:blue;\"> As <\/span>IRibbonControl, ByRef label)\r\n     <span style=\"color:blue;\">Dim <\/span>frm<span style=\"color:blue;\"> As <\/span>Form\r\n     Select Case control.ID\r\n         <span style=\"color:blue;\">Case <\/span>\"tabNavigation\"\r\n             <span style=\"color:blue;\">Set<\/span> frm = Screen.ActiveForm\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(frm.Caption) = 0<span style=\"color:blue;\"> Then<\/span>\r\n                 label = frm.Name\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 label = frm.Caption\r\n             <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Sie pr&uuml;ft per <b>Select Case<\/b>, ob sie f&uuml;r das Element <b>tabNavigation <\/b>aufgerufen wurde und referenziert dann das aktuelle Formular. Wenn wir, wie geplant, diese Ribbondefinition als Ribbon f&uuml;r ein Formular angeben, ist auf jeden Fall ein Formular ge&ouml;ffnet, wenn das Ribbon erscheint. F&uuml;r dieses pr&uuml;fen wir dann, ob die Eigenschaft <b>Caption <\/b>leer ist. Ist das der Fall, gibt die Prozedur den Namen des Formulars zur&uuml;ck, anderenfalls die Beschriftung aus der Eigenschaft <b>Caption<\/b>.<\/p>\n<h2>Gruppe mit Steuerelementen<\/h2>\n<p>Unter dem <b>tab<\/b>-Element folgt das <b>group<\/b>-Element, das die eigentlichen Steuerelemente enth&auml;lt. Die <b>button<\/b>-Elemente erhalten jeweils den Namen des anzuzeigenden Icons f&uuml;r das <b>image<\/b>-Attribut, zum Beispiel <b>navigate_beginning<\/b>. Au&szlig;erdem zeigen sie eine Beschriftung an, die wir f&uuml;r das Attribut <b>label <\/b>angeben und ein eindeutiger Bezeichner, der im Attribut <b>id <\/b>landet, darf auch nicht fehlen.<\/p>\n<p>Schlie&szlig;lich enth&auml;lt jedes <b>button<\/b>-Element noch zwei Attribute, f&uuml;r die wir VBA-Prozeduren hinterlegen:<\/p>\n<ul>\n<li>F&uuml;r das Attribut <b>onAction <\/b>hinterlegen wir die Prozedur, die beim Anklicken ausgel&ouml;st werden soll. Diese hei&szlig;t <b>OnAction<\/b>.<\/li>\n<li>F&uuml;r das Attribut <b>getEnabled <\/b>hinterlegen wir eine Prozedur, die anhand der aktuellen Position des Datensatzzeigers und weiterer Parameter pr&uuml;fen soll, ob die Schaltfl&auml;che derzeit aktiviert sein darf.<\/li>\n<\/ul>\n<h2>Anzeige der Datensatzzeigerposition<\/h2>\n<p>In einem Textfeld wollen wir einen Wert wie <b>1\/100 <\/b>anzeigen und somit die Position des Datensatzzeigers sowie die Anzahl der Datens&auml;tze darstellen. Das erledigen wir mit einem <b>editBox<\/b>-Element. F&uuml;r dieses hinterlegen wir auch drei Callback-Attribute:<\/p>\n<ul>\n<li>F&uuml;r <b>getText <\/b>hinterlegen wir die Prozedur, welche die aktuelle Position des Datensatzzeigers und die Anzahl der Datens&auml;tze liefert.<\/li>\n<li>F&uuml;r <b>onChange <\/b>geben wir die Prozedur an, die ausgel&ouml;st wird, wenn der Benutzer einen Zahlenwert eingibt, um den Datensatzzeiger zu der angegebenen Position zu bewegen.<\/li>\n<li>F&uuml;r <b>getEnabled <\/b>hinterlegen wir eine Prozedur, die ermittelt, ob das <b>editBox<\/b>-Element aktiviert sein soll. Das ist eigentlich nur nicht der Fall, wenn das Recordset leer ist und nicht bearbeitet werden kann.<\/li>\n<\/ul>\n<h2>Bilder bereitstellen<\/h2>\n<p>Die f&uuml;nf Bilddateien, welche die Schaltfl&auml;chen als Icon anzeigen sollen, speichern wir in der Tabelle <b>MSysResources<\/b>. Um diese dort zu hinterlegen, gibt es einen einfachen Trick: Wir zeigen ein Formular in der Entwurfsansicht an, klicken auf den Ribbonbefehl zum Hinzuf&uuml;gen eines Bild-Steuerelements, w&auml;hlen das Bild mit dem dann erscheinenden Dateiauswahl-Dialog aus und brechen dann das Hinzuf&uuml;gen des Bild-Steuerelements ab.<\/p>\n<p>Damit legen wir zwar kein Bild-Steuerelement an, aber das soeben ausgew&auml;hlte Bild wird in der Tabelle <b>MSysResources <\/b>gespeichert. Diesen Schritt wiederholen wir einfach f&uuml;r alle anzuzeigenden Bilder, bis die Tabelle <b>MSysResources <\/b>wie in Bild 4 aussieht. Diese Tabelle wird im Navigationsbereich &uuml;brigens nur erscheinen, wenn die Anzeige von Systemobjekten und ausgeblendeten Objekten aktiviert ist. Man kann sie aber auch mit dem folgenden Befehl &ouml;ffnen (das gilt auch f&uuml;r die Tabelle <b>USysRibbons<\/b>):<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2023_01\/pic_1415_004.png\" alt=\"Tabelle zum Speichern der Bilder, die als Icons der Schaltfl&auml;chen im Ribbon erscheinen sollen\" width=\"424,5589\" height=\"213,1789\" \/><\/p>\n<p>[<\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Tabelle zum Speichern der Bilder, die als Icons der Schaltfl&auml;chen im Ribbon erscheinen sollen<\/span><\/b><\/p>\n<pre>DoCmd.OpenTable \"MSysResources\"<\/pre>\n<p>F&uuml;r die Tabelle <b>USysRibbons <\/b>analog:<\/p>\n<pre>DoCmd.OpenTable \"USysRibbons\"<\/pre>\n<p>Das die Bilder letztlich angezeigt werden, erreichen wir durch die Kombination der Angabe des Wertes aus dem Feld <b>Name <\/b>f&uuml;r das Attribut <b>image <\/b>der <b>button<\/b>-Elemente sowie der Verwendung der f&uuml;r das Attribut <b>loadImage <\/b>des <b>customUI<\/b>-Elements hinterlegten Callbackprozedur.<\/p>\n<h2>Text f&uuml;r die Anzeige der Position des Datensatzzeigers anzeigen<\/h2>\n<p>Damit das <b>editBox<\/b>-Element einen Text wie <b>1\/100 <\/b>anzeigt und diese Anzeige zu gegebenen Zeitpunkten aktualisiert, m&uuml;ssen wir eine entsprechende Callbackprozedur hinterlegen. Diese sieht wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>getText(control<span style=\"color:blue;\"> As <\/span>IRibbonControl, ByRef text)\r\n     <span style=\"color:blue;\">Dim <\/span>frm<span style=\"color:blue;\"> As <\/span>Form\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> frm = Screen.ActiveForm\r\n     <span style=\"color:blue;\">Set<\/span> rst = frm.Recordset\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rst.Updatable And rst.RecordCount = 0<span style=\"color:blue;\"> Then<\/span>\r\n         text = \"\"\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> frm.NewRecord<span style=\"color:blue;\"> Then<\/span>\r\n             text = rst.AbsolutePosition + 1 & \"\/\" _\r\n                 & rst.RecordCount\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             text = rst.RecordCount + 1 & \"\/\" _\r\n                 & rst.RecordCount + 1\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Prozedur referenziert das aktuell im Fokus befindliche Formular mit der Variablen <b>frm <\/b>und das darin enthaltene Recordset mit <b>rst<\/b>. Dann pr&uuml;ft die Prozedur, ob das Recordset nicht aktualisierbar ist und keinen Datensatz enth&auml;lt. In diesem Fall soll das <b>editBox<\/b>-Element keinen Wert anzeigen.<\/p>\n<p>Anderenfalls folgt die Unterscheidung, ob das Formular gerade keinen neuen Datensatz anzeigt oder einen neuen. Im ersteren Fall ermittelt die Prozedur mit <b>rst.AbsolutePosition + 1 <\/b>die aktuelle Position des Datensatzzeigers und mit <b>rst.RecordCount <\/b>die Anzahl der Datens&auml;tze. Diese beiden Werte f&uuml;gt sie, durch einen Schr&auml;gstrich voneinander getrennt, zusammen und gibt sie mit dem Parameter <b>text <\/b>an das aufrufende Steuerelement zur&uuml;ck. Falls das Formular gerade einen neuen, leeren Datensatz anzeigt, stellen wir den Inhalt des Textfeldes auf den Ausdruck <b>rst.RecordCount + 1 &#038; &#8222;\/&#8220; &#038; rst.RecordCount + 1<\/b> ein &#8211; also wenn es 100 Recordsets enth&auml;lt, auf <b>101\/101<\/b>. Wie und wann wir die Anzeige aktualisieren, zeigen wir in wenigen Abschnitten.<\/p>\n<h2>Aktivieren und Deaktivieren der Schaltfl&auml;chen<\/h2>\n<p>F&uuml;r jede der f&uuml;nf Schaltfl&auml;chen haben wir mit dem Attribut <b>getEnabled <\/b>den Namen der Callbackprozedur hinterlegt, mit der wir den <b>Enabled<\/b>-Zustand der jeweiligen Schaltfl&auml;che ermitteln wollen. Diese Prozedur sieht wie in Listing 2 aus. Sie nimmt mit dem Parameter <b>control <\/b>einen Verweis auf das ausl&ouml;sende Steuerelement entgegen und erwartet f&uuml;r den Parameter <b>enabled <\/b>die Angabe des Wertes <b>True <\/b>oder <b>False<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>getEnabled(control<span style=\"color:blue;\"> As <\/span>IRibbonControl, ByRef enabled)\r\n     <span style=\"color:blue;\">Dim <\/span>frm<span style=\"color:blue;\"> As <\/span>Form\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> frm = Screen.ActiveForm\r\n     <span style=\"color:blue;\">Set<\/span> rst = frm.Recordset\r\n     Select Case control.ID\r\n         <span style=\"color:blue;\">Case <\/span>\"btnErster\", \"btnLetzter\", \"txtAktuellerDatensatz\"\r\n             <span style=\"color:blue;\">If <\/span>rst.RecordCount = 0 And rst.Updatable = <span style=\"color:blue;\">False<\/span><span style=\"color:blue;\"> Then<\/span>\r\n                 enabled = <span style=\"color:blue;\">False<\/span>\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 enabled = <span style=\"color:blue;\">True<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Case <\/span>\"btnVorheriger\"\r\n             <span style=\"color:blue;\">If <\/span>rst.AbsolutePosition = 0 Or rst.AbsolutePosition = -1<span style=\"color:blue;\"> Then<\/span>\r\n                 enabled = <span style=\"color:blue;\">False<\/span>\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 enabled = <span style=\"color:blue;\">True<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Case <\/span>\"btnNaechster\"\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> frm.NewRecord<span style=\"color:blue;\"> Then<\/span>\r\n                 <span style=\"color:blue;\">If <\/span>rst.AbsolutePosition = rst.RecordCount - 1<span style=\"color:blue;\"> Then<\/span>\r\n                     <span style=\"color:blue;\">If <\/span>rst.Updatable<span style=\"color:blue;\"> Then<\/span>\r\n                         enabled = <span style=\"color:blue;\">True<\/span>\r\n                     <span style=\"color:blue;\">Else<\/span>\r\n                         enabled = <span style=\"color:blue;\">False<\/span>\r\n                     <span style=\"color:blue;\">End If<\/span>\r\n                 <span style=\"color:blue;\">Else<\/span>\r\n                     enabled = <span style=\"color:blue;\">True<\/span>\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 enabled = <span style=\"color:blue;\">False<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Case <\/span>\"btnNeu\"\r\n             <span style=\"color:blue;\">If <\/span>rst.Updatable<span style=\"color:blue;\"> Then<\/span>\r\n                 <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> frm.NewRecord<span style=\"color:blue;\"> Then<\/span>\r\n                     enabled = <span style=\"color:blue;\">True<\/span>\r\n                 <span style=\"color:blue;\">Else<\/span>\r\n                     enabled = <span style=\"color:blue;\">False<\/span>\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 enabled = <span style=\"color:blue;\">False<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Die Prozedur getEnabled zum Ermitteln des enabled-Zustands der Schaltfl&auml;chen<\/span><\/b><\/p>\n<p>Die Prozedur referenziert mit der Variablen <b>frm <\/b>das aktuell angezeigte und mit <b>Screen.ActiveForm <\/b>ermittelte Formular sowie mit <b>rst <\/b>das darin enthaltene Recordset. Das setzt voraus, das aktuell ein Formular angezeigt wird &#8211; was erf&uuml;llt ist, da das Ribbon nur in Zusammenhang mit einem Formular ge&ouml;ffnet wird. Ein Recordset sollte auch vorliegen, sonst macht die Zuweisung dieses Ribbons keinen Sinn.<\/p>\n<p>Danach pr&uuml;ft die Prozedur mit dem Wert der Eigenschaft <b>ID <\/b>des mit <b>control <\/b>gelieferten <b>IRibbonControl<\/b>-Elements, f&uuml;r welches Steuerelement die Prozedur aufgerufen wurde.<\/p>\n<h2>Aktivieren der Schaltfl&auml;chen f&uuml;r die Anzeige des ersten oder letzten Datensatzes<\/h2>\n<p>F&uuml;r die Schaltfl&auml;che <b>btnErster <\/b>ist der Fall klar: Sie soll eigentlich immer aktiviert sein, also k&ouml;nnten wir mit dem Parameter <b>enabled <\/b>den Wert <b>True <\/b>zur&uuml;ckgeben. Das Gleiche gilt f&uuml;r die Schaltfl&auml;che <b>btnLetzter<\/b>.<\/p>\n<p>Aber es gibt einen Sonderfall: Wenn wir n&auml;mlich auf ein Formular sto&szlig;en, dessen Recordset leer ist und wenn gleichzeitig die Bearbeitung der Daten deaktiviert ist, dann sind die original Navigationsschaltfl&auml;chen ebenfalls deaktiviert. Also fragen wir ab, ob <b>rst.RecordCount <\/b>gleich <b>0 <\/b>ist und <b>rst.Updatable <\/b>gleich <b>False<\/b>. Ist beides wahr, sollen die Schaltfl&auml;chen <b>btnErster <\/b>und <b>btnLetzter <\/b>deaktiviert werden.<\/p>\n<h2>Aktivieren der Schaltfl&auml;che f&uuml;r die Anzeige des vorherigen Datensatzes<\/h2>\n<p>F&uuml;r die Aktivierung der Schaltfl&auml;che <b>btnVorheriger <\/b>pr&uuml;fen wir, ob der Datensatzzeiger sich auf der ersten Position befindet &#8211; und zwar mit <b>rst.AbsolutePosition = 0<\/b>. Ist dies wahr, gibt es keinen vorherigen Datensatz mehr &#8211; also soll diese Schaltfl&auml;che deaktiviert werden. In allen anderen F&auml;llen ist sie aktiviert.<\/p>\n<h2>Aktivieren der Schaltfl&auml;che f&uuml;r die Anzeige des n&auml;chsten Datensatzes<\/h2>\n<p>Bei der Schaltfl&auml;che <b>btnNaechster <\/b>gelten etwas andere Regeln, denn auch wenn wir uns bereits auf dem letzten Datensatz befinden, soll diese Schaltfl&auml;che es erm&ouml;glichen, zu einem neuen, leeren Datensatz zu springen. Au&szlig;er nat&uuml;rlich, die Datensatzgruppe kann nicht aktualisiert werden &#8211; dann soll <b>btnNaechster <\/b>bei Anzeige des letzten Datensatzes nicht aktiviert sein. Und wenn sich der Datensatzzeiger auf einem neuen, noch nicht gespeicherten Datensatz befindet, soll die Schaltfl&auml;chen <b>btnNaechster<\/b> auch deaktiviert werden.<\/p>\n<p>Wir pr&uuml;fen also als Erstes mit <b>Not frm.NewRecord<\/b>, ob kein neuer, leerer Datensatz angezeigt wird. Dann pr&uuml;fen wir, ob wir uns auf dem letzten Datensatz befinden.<\/p>\n<p>Ist das der Fall und das Recordset ist aktualisierbar, aktivieren wir die Schaltfl&auml;che. Falls wir auf dem letzten Datensatz sind und das Recordset ist nicht aktualisierbar, deaktivieren wir <b>btnNaechster<\/b>.<\/p>\n<p>Befinden wir uns nicht auf dem letzten Datensatz, aktivieren wir <b>btnNaechster<\/b>. Und wenn wir uns auf einem neuen Datensatz befinden (<b>Else<\/b>-Teil von <b>If Not frm.NewRecord<\/b>), dann wird <b>btnNaechster <\/b>auch deaktiviert.<\/p>\n<h2>Aktivieren der Schaltfl&auml;che zum Anlegen eines neuen, leeren Datensatzes<\/h2>\n<p>Diese Schaltfl&auml;che wird definitiv deaktiviert, wenn das Recordset nicht aktualisierbar ist. Anderenfalls pr&uuml;fen wir, ob wir uns bereits auf einem neuen, leeren Datensatz befinden. Falls ja, wird die Schaltfl&auml;che ebenfalls deaktiviert, sonst wird sie aktiviert.<\/p>\n<p>Damit haben wir alle Zust&auml;nde bez&uuml;glich der Aktivierung der Schaltfl&auml;chen gekl&auml;rt.<\/p>\n<p>Fehlt noch das <b>editBox<\/b>-Element <b>txtAktuellerDatensatz<\/b>: Dieses soll auch nur deaktiviert werden, wenn keine Datens&auml;tze vorhanden sind und die Datensatzgruppe nicht aktualisierbar ist. Deshalb f&uuml;gen wir dieses Element zu dem <b>Case<\/b>-Zweig hinzu, der bereits die Schaltfl&auml;chen <b>cmdErster <\/b>und <b>cmdLetzter <\/b>behandelt.<\/p>\n<h2>Anklicken der Schaltfl&auml;chen<\/h2>\n<p>Beim Anklicken einer jeden der f&uuml;nf Schaltfl&auml;chen wird die Prozedur <b>onAction <\/b>aufgerufen (siehe Listing 3). Diese nimmt mit dem Parameter <b>control <\/b>einen Verweis auf das aufrufende Steuerelement entgegen.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>onAction(control<span style=\"color:blue;\"> As <\/span>IRibbonControl)\r\n     <span style=\"color:blue;\">Dim <\/span>frm<span style=\"color:blue;\"> As <\/span>Form\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> frm = Screen.ActiveForm\r\n     <span style=\"color:blue;\">Set<\/span> rst = frm.Recordset\r\n     Select Case control.ID\r\n         <span style=\"color:blue;\">Case <\/span>\"btnErster\"\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rst.BOF<span style=\"color:blue;\"> Then<\/span>\r\n                 rst.MoveFirst\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             objRibbon_Navigation.Invalidate\r\n         <span style=\"color:blue;\">Case <\/span>\"btnVorheriger\"\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> frm.NewRecord<span style=\"color:blue;\"> Then<\/span>\r\n                 rst.MovePrevious\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 rst.MoveLast\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             objRibbon_Navigation.Invalidate\r\n         <span style=\"color:blue;\">Case <\/span>\"btnNaechster\"\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rst.AbsolutePosition = rst.RecordCount - 1<span style=\"color:blue;\"> Then<\/span>\r\n                 rst.Move<span style=\"color:blue;\">Next<\/span>\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 DoCmd.GoToRecord record:=acNewRec\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             objRibbon_Navigation.Invalidate\r\n         <span style=\"color:blue;\">Case <\/span>\"btnLetzter\"\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rst.EOF<span style=\"color:blue;\"> Then<\/span>\r\n                 rst.MoveLast\r\n             <span style=\"color:blue;\">End If<\/span>\r\n            objRibbon_Navigation.Invalidate\r\n         <span style=\"color:blue;\">Case <\/span>\"btnNeu\"\r\n             DoCmd.GoToRecord record:=acNewRec\r\n             objRibbon_Navigation.Invalidate\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Die Prozedur onAction zum Durchf&uuml;hren von Aktionen beim Anklicken der Schaltfl&auml;chen<\/span><\/b><\/p>\n<p>Sie referenziert das aktive Formular mit der Variablen <b>frm <\/b>und das darin enthaltene Recordset mit <b>rst<\/b>. Dann unterscheidet sie in einer <b>Select Case<\/b>-Bedingung nach dem Wert der Eigenschaft <b>ID <\/b>des <b>control<\/b>-Elements.<\/p>\n<h2>Zum ersten Datensatz<\/h2>\n<p>Die Schaltfl&auml;che <b>btnErster <\/b>soll den Datensatzzeiger auf den ersten Datensatz des Recordsets verschieben. Dazu ruft die Prozedur die Methode <b>MoveFirst <\/b>des Recordsets auf <b>rst <\/b>auf. Das f&uuml;hrt aber zu einem Fehler, wenn die Datensatzgruppe leer ist. Also pr&uuml;fen wir vorab per <b>rst.BOF<\/b>, ob sich der Datensatzzeiger bereits vor dem ersten Datensatz befindet.<\/p>\n<p>Danach folgt noch ein wichtiger Schritt: Der Aufruf der Methode <b>Invalidate <\/b>der Objektvariablen <b>objRibbon_Navigation<\/b>. Dies f&uuml;hrt dazu, dass alle Callbackprozeduren f&uuml;r die Elemente dieser Ribbondefinition erneut aufgerufen werden. Damit rufen nun beispielsweise alle Steuerelemente erneut die <b>getEnabled<\/b>-Prozedur auf, um ihren Aktiviert-Zustand neu einzustellen.<\/p>\n<h2>Zum vorherigen Datensatz<\/h2>\n<p>Bei der Schaltfl&auml;che <b>btnVorheriger <\/b>sollte man meinen, wir k&ouml;nnten hier einfach den Befehl <b>rst.MovePrevious <\/b>anwenden. Das ist allerdings nicht immer der Fall: Wenn das Formular n&auml;mlich einen neuen, leeren Datensatz anzeigt, ist als Position des Datensatzzeigers dennoch der letzte Datensatz gespeichert. Das w&uuml;rde bedeuten, dass wir bei 100 Datens&auml;tzen von einem neuen Datensatz auf den neunundneunzigsten Datensatz springen w&uuml;rden statt auf den hundertsten.<\/p>\n<p>Also pr&uuml;fen wir in diesem <b>Case<\/b>-Zweig mit <b>frm.NewRecord<\/b>, ob das Formular gerade einen neuen, leeren Datensatz anzeigt. Falls nicht, bewegen wir den Datensatzzeiger mit <b>rst.MovePrevious <\/b>zum vorherigen Datensatz, sonst mit <b>rst.MoveLast <\/b>zum letzten Datensatz. Auch hier rufen wir wieder <b>objRibbon_Navigation.Invalidate <\/b>auf, um den Status der Steuerelemente zu aktualisieren.<\/p>\n<h2>Zum n&auml;chsten Datensatz<\/h2>\n<p>Hat der Benutzer die Schaltfl&auml;che <b>btnNaechster <\/b>angeklickt, m&uuml;ssen wir pr&uuml;fen, ob sich der Datensatzzeiger gerade auf dem letzten Datensatz befindet. Ist das nicht der Fall, zeigen wir mit <b>rst.MoveNext <\/b>den n&auml;chsten Datensatz an.<\/p>\n<p>Befinden wir uns hingegen schon auf dem letzten Datensatz, hat diese Schaltfl&auml;che die gleiche Funktion wie die Schaltfl&auml;che <b>btnNeu<\/b>. Wir springen dann also mit <b>DoCmd.GotoRecord Record:=acNewRec <\/b>zu einem neuen Datensatz.<\/p>\n<h2>Zum letzten Datensatz <\/h2>\n<p>Die Schaltfl&auml;che <b>btnLetzter <\/b>hat einen klaren Auftrag: Sie soll einfach zum letzten Datensatz springen. Dazu verwenden wir die Methode <b>rst.MoveLast<\/b>. Allerdings kann auch hier ein Fehler auftreten, wenn das Recordset leer ist. Deshalb pr&uuml;fen wir vorab mit <b>rst.EOF<\/b>, ob sich das Recordset bereits hinter dem letzten Datensatz befindet &#8211; ist das der Fall, wird <b>rst.MoveLast <\/b>nicht ausgef&uuml;hrt.<\/p>\n<h2>Zu einem neuen, leeren Datensatz<\/h2>\n<p>Wie wir zu einem neuen, leeren Datensatz kommen, haben wir oben schon gesehen, und die Schaltfl&auml;che btnNeu macht nichts anderes: <b>DoCmd.GotoRecord Record:=acNewRec<\/b>.<\/p>\n<h2>Eingabe der anzuzeigenden Datensatzposition per Textfeld<\/h2>\n<p>Damit wir auf die Eingabe des Benutzers in das <b>editBox<\/b>-Element <b>txtAktuellerDatensatz <\/b>reagieren k&ouml;nnen, haben wir das Attribut <b>onChange <\/b>mit dem Namen der gleichnamigen Prozedur gef&uuml;llt. Diese enth&auml;lt den vom Benutzer eingegeben Wert mit dem Parameter <b>text <\/b>und pr&uuml;ft, ob der Benutzer einen numerischen Wert eingegeben hat.<\/p>\n<p>Falls ja, weist sie der Variablen <b>rst <\/b>das Recordset des aktuell aktiven Formulars zu. Enth&auml;lt der Parameter einen Zahlenwert, der kleiner ist als die enthaltene Anzahl Datens&auml;tze, wird die Position des Datensatzzeigers &uuml;ber die Eigenschaft <b>AbsolutePosition<\/b> des Recordsets auf die gew&uuml;nschte Position eingestellt. Dabei wird der eingegebene Wert noch um <b>1 <\/b>nach unten korrigiert, da <b>AbsolutePosition <\/b>den Index mit <b>0 <\/b>beginnend erwartet.<\/p>\n<p>Die Prozedur sorgt schlie&szlig;lich noch durch den Aufruf der <b>Invalidate<\/b>-Methode f&uuml;r die Aktualisierung der &uuml;brigen Steuerelemente:<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>onChange(control<span style=\"color:blue;\"> As <\/span>IRibbonControl, text<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">If <\/span>IsNumeric(text)<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> rst = Screen.ActiveForm.Recordset\r\n         <span style=\"color:blue;\">If <\/span>text &lt;= rst.RecordCount<span style=\"color:blue;\"> Then<\/span>\r\n             rst.AbsolutePosition = text - 1\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     objRibbon_Navigation.Invalidate\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Ribbon direkt anzeigen<\/h2>\n<p>Eine Frage, die wir noch bearbeiten m&uuml;ssen, ist die nach der Anzeige der Ribbonanpassung. Bisher wird das dort definierte <b>tab<\/b>-Element neben all den anderen Elementen angezeigt. Wir wollen dieses aber direkt sehen k&ouml;nnen. Die einfachste M&ouml;glichkeit dazu ist, f&uuml;r das <b>ribbon<\/b>-Element das Attribut <b>startFromScratch <\/b>auf <b>true <\/b>einzustellen:<\/p>\n<pre>&lt;ribbon startFromScratch=\"true\"&gt;<\/pre>\n<p>Das sorgt daf&uuml;r, dass wie in Bild 5 alle &uuml;brigen eingebauten Elemente ausgeblendet werden und unsere Anpassung direkt sichtbar ist.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2023_01\/pic_1415_005.png\" alt=\"Die Ribbonanpassung blendet alle anderen Elemente aus.\" width=\"524,559\" height=\"306,3638\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Die Ribbonanpassung blendet alle anderen Elemente aus.<\/span><\/b><\/p>\n<h2>Eingebaute Navigationsschaltfl&auml;chen ausblenden<\/h2>\n<p>Da wir nun eigene Navigationsschaltfl&auml;chen anzeigen, k&ouml;nnen wir die eingebauten Elemente ausblenden. Dazu stellen wir die Eigenschaft <b>Navigationsschaltfl&auml;chen <\/b>des Formulars einfach auf <b>Nein <\/b>ein.<\/p>\n<h2>Problem Synchronisation<\/h2>\n<p>Das Problem ist: Solange der Benutzer ausschlie&szlig;lich mit den Navigationsschaltfl&auml;chen im Ribbon navigiert, sind die dortigen Schaltfl&auml;chen entsprechend der Position des Datensatzzeigers im Formular aktiviert oder deaktiviert.<\/p>\n<p>Wenn der Benutzer jedoch beispielsweise in der Datenblattansicht mit der <b>Nach unten<\/b>-Taste zu den folgenden Datens&auml;tzen navigiert, synchronisiert sich das Ribbon nicht automatisch. Wir m&uuml;ssen dem Formular also noch ein paar Ereignisprozeduren verpassen, damit das Ribbon regelm&auml;&szlig;ig aktualisiert wird.<\/p>\n<p>Das offensichtlichste Ereignis, das wir ber&uuml;cksichtigen m&uuml;ssen, ist das Ereignis <b>Beim Anzeigen<\/b>. Dieses wird beim Anzeigen eines jeden Datensatzes ausgel&ouml;st, also nicht nur beim Anzeigen des ersten Datensatzes nach dem &Ouml;ffnen des Formulars, sondern auch bei jedem Datensatzwechsel.<\/p>\n<p>F&uuml;r diese Ereigniseigenschaft hinterlegen wir daher die folgende Ereignisprozedur:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Current()\r\n     objRibbon_Navigation.Invalidate\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Damit k&ouml;nnen wir mit den <b>Nach oben<\/b>&#8211; und <b>Nach unten<\/b>-Tasten durch die Datens&auml;tze navigieren und das Navigationsribbon wird immer auf dem aktuellen Stand gehalten.<\/p>\n<h2>Anlegen und Speichern eines neuen Datensatzes<\/h2>\n<p>Ein Sonderfall tritt ein, wenn wir einen neuen Datensatz anlegen und diesen beispielsweise mit <b>Strg + S <\/b>speichern (oder durch einen Klick auf den Datensatzmarkierer).<\/p>\n<p>Dann wird der neue Datensatz zum letzten Datensatz und darunter wird der n&auml;chste neue, leere Datensatz angezeigt. Allerdings l&ouml;sen wir so nicht das Ereignis <b>Beim Anzeigen <\/b>aus und somit wird das Navigationsribbon nicht aktualisiert.<\/p>\n<p>In diesem Fall behelfen wir uns mit der Ereignisprozedur <b>Nach Aktualisierung<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_AfterUpdate()\r\n     objRibbon_Navigation.Invalidate\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>L&ouml;schen eines Datensatzes<\/h2>\n<p>Wenn wir den aktuellen Datensatz l&ouml;schen, erhalten wir einen Fehler in der Prozedur <b>getEnabled<\/b> f&uuml;r die Schaltfl&auml;che <b>btnVorheriger<\/b>, weil wir <b>rst.AbsolutePosition <\/b>kurzzeitig nicht ermitteln k&ouml;nnen.<\/p>\n<p>Setzt man die Ausf&uuml;hrung des Codes nach der Fehlermeldung fort, l&auml;uft dieser ohne Probleme weiter. <b>rst.AbsolutePosition <\/b>enth&auml;lt dann allerdings den Wert <b>-1 <\/b>und die Schaltfl&auml;che <b>btnVorheriger <\/b>wird f&auml;lschlicherweise deaktiviert, wenn wir uns nicht auf dem ersten Datensatz befinden. Au&szlig;erdem zeigt das Textfeld den Text <b>0\/100 <\/b>an, wobei der Wert <b>0 <\/b>falsch ist.<\/p>\n<p>Um dies zu beheben, haben wir folgende Anpassung vorgenommen. Als Erstes ben&ouml;tigen wir eine Variable, um den Wert von <b>AbsolutePosition <\/b>vor dem L&ouml;schen zu speichern:<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>lngPos<span style=\"color:blue;\"> As Long<\/span><\/pre>\n<p>Dann verwenden wir die f&uuml;r das Ereignis <b>Beim L&ouml;schen <\/b>wie folgt hinterlegte Prozedur, um uns in <b>lngPos <\/b>die Datensatzzeigerposition zu merken:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Delete(Cancel<span style=\"color:blue;\"> As Integer<\/span>)\r\n     lngPos = Me.Recordset.AbsolutePosition\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Schlie&szlig;lich erweitern wir die Prozedur f&uuml;r das Ereignis <b>Beim Anzeigen <\/b>so, dass es die Datensatzzeigerposition auf den Wert aus <b>lngPos <\/b>einstellt, wenn dieser Wert <b>-1 <\/b>lautet, was beim L&ouml;schen oft der Fall ist &#8211; das Ganze bei deaktivierter Fehlerbehandlung:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Current()\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">If <\/span>Me.Recordset.AbsolutePosition = -1<span style=\"color:blue;\"> Then<\/span>\r\n         Me.Recordset.AbsolutePosition = lngPos\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     objRibbon_Navigation.Invalidate\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Somit klappt nun auch das Aktualisieren der Steuerelemente und insbesondere des Textfeldes <b>txtAktuellerDatensatz <\/b>nach dem L&ouml;schen von Datens&auml;tzen.<\/p>\n<h2>Performance des Ribbons<\/h2>\n<p>Wenn man schnell durch die Datens&auml;tze klickt und speziell, wenn man bei gedr&uuml;ckter <b>Nach oben<\/b>&#8211; oder <b>Nach unten<\/b>-Taste schnell durch die Datens&auml;tze scrollt, aktualisiert sich das Ribbon nicht so schnell, wie das bei den Navigationssteuerelementen im Formular passiert. Wenn Sie dies feststellen sollten, liegt es also nicht an Ihrer Anwendung.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Dieser Beitrag stellt eine L&ouml;sung vor, um die Funktionen der Navigationsleiste eines Formulars, die recht klein am unteren Rand abgebildet wird, im Ribbon darzustellen und dabei die urspr&uuml;nglichen Funktionen m&ouml;glichst 1:1 zu &uuml;bernehmen.<\/p>\n<p>Dazu sind ein paar Programmierschritte n&ouml;tig und leider auch eine Anpassung des Formulars. Diese Anpassungen k&ouml;nnte man allerdings auch in eine Klasse auslagern, sodass man nicht jedem Formular, das dieses Navigationsribbon anzeigen soll, den notwendigen VBA-Code zuweisen muss. Das Formular in der Datenblattansicht muss dann lediglich ein Klassenmodul enthalten.<\/p>\n<p>Wie das gelingt, zeigen wir in einem weiteren Beitrag namens <b>Datensatznavigation per Ribbon mit Klasse <\/b>(<b>www.access-im-unternehmen.de\/1415<\/b>).<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>NavigationImRibbon.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/CA90D3F2-248E-4A27-B8D0-D6995C213DBB\/aiu_1415.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die Navigationszeile am unteren Rand von Formularen oder Unterformularen in der Datenblattansicht ist recht fummelig und f&auml;llt nicht auf den ersten Blick auf, wenn man nicht gewohnt ist, damit zu arbeiten. Es gibt eine Menge L&ouml;sungen, bei denen diese Steuerelemente in Form von Formular-Schaltfl&auml;chen bereitgestellt werden. Uns ist aber noch keine L&ouml;sung &uuml;ber den Weg gelaufen, bei der die Navigationssteuerelemente im Ribbon abgebildet wurden. Zwar gibt es einen eigenen Bereich, der Werkzeuge f&uuml;r den Umgang mit der Datenblattansicht bereitstellt, aber dieser bietet keine Steuerelemente zum Navigieren in den Datens&auml;tzen. Aber kein Problem: Wir liefern das nach!<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66012023,662023,44000028],"tags":[],"class_list":["post-55001415","post","type-post","status-publish","format-standard","hentry","category-66012023","category-662023","category-Ergonomie_und_Benutzeroberflaeche"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Datensatznavigation per Ribbon - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Datensatznavigation per Ribbon\" \/>\n<meta property=\"og:description\" content=\"Die Navigationszeile am unteren Rand von Formularen oder Unterformularen in der Datenblattansicht ist recht fummelig und f&auml;llt nicht auf den ersten Blick auf, wenn man nicht gewohnt ist, damit zu arbeiten. Es gibt eine Menge L&ouml;sungen, bei denen diese Steuerelemente in Form von Formular-Schaltfl&auml;chen bereitgestellt werden. Uns ist aber noch keine L&ouml;sung &uuml;ber den Weg gelaufen, bei der die Navigationssteuerelemente im Ribbon abgebildet wurden. Zwar gibt es einen eigenen Bereich, der Werkzeuge f&uuml;r den Umgang mit der Datenblattansicht bereitstellt, aber dieser bietet keine Steuerelemente zum Navigieren in den Datens&auml;tzen. Aber kein Problem: Wir liefern das nach!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2023-06-17T09:32:39+00:00\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"23\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Datensatznavigation per Ribbon\",\"datePublished\":\"2023-06-17T09:32:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/\"},\"wordCount\":3945,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg08.met.vgwort.de\\\/na\\\/232ccab92853462386eed7c903af7c1b\",\"articleSection\":[\"1\\\/2023\",\"2023\",\"Ergonomie und Benutzeroberfl\u00e4che\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/\",\"name\":\"Datensatznavigation per Ribbon - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg08.met.vgwort.de\\\/na\\\/232ccab92853462386eed7c903af7c1b\",\"datePublished\":\"2023-06-17T09:32:39+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg08.met.vgwort.de\\\/na\\\/232ccab92853462386eed7c903af7c1b\",\"contentUrl\":\"http:\\\/\\\/vg08.met.vgwort.de\\\/na\\\/232ccab92853462386eed7c903af7c1b\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datensatznavigation_per_Ribbon\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Datensatznavigation per Ribbon\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Datensatznavigation per Ribbon - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/","og_locale":"de_DE","og_type":"article","og_title":"Datensatznavigation per Ribbon","og_description":"Die Navigationszeile am unteren Rand von Formularen oder Unterformularen in der Datenblattansicht ist recht fummelig und f&auml;llt nicht auf den ersten Blick auf, wenn man nicht gewohnt ist, damit zu arbeiten. Es gibt eine Menge L&ouml;sungen, bei denen diese Steuerelemente in Form von Formular-Schaltfl&auml;chen bereitgestellt werden. Uns ist aber noch keine L&ouml;sung &uuml;ber den Weg gelaufen, bei der die Navigationssteuerelemente im Ribbon abgebildet wurden. Zwar gibt es einen eigenen Bereich, der Werkzeuge f&uuml;r den Umgang mit der Datenblattansicht bereitstellt, aber dieser bietet keine Steuerelemente zum Navigieren in den Datens&auml;tzen. Aber kein Problem: Wir liefern das nach!","og_url":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/","og_site_name":"Access im Unternehmen","article_published_time":"2023-06-17T09:32:39+00:00","author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"23\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Datensatznavigation per Ribbon","datePublished":"2023-06-17T09:32:39+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/"},"wordCount":3945,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/#primaryimage"},"thumbnailUrl":"http:\/\/vg08.met.vgwort.de\/na\/232ccab92853462386eed7c903af7c1b","articleSection":["1\/2023","2023","Ergonomie und Benutzeroberfl\u00e4che"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/","url":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/","name":"Datensatznavigation per Ribbon - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/#primaryimage"},"thumbnailUrl":"http:\/\/vg08.met.vgwort.de\/na\/232ccab92853462386eed7c903af7c1b","datePublished":"2023-06-17T09:32:39+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/#primaryimage","url":"http:\/\/vg08.met.vgwort.de\/na\/232ccab92853462386eed7c903af7c1b","contentUrl":"http:\/\/vg08.met.vgwort.de\/na\/232ccab92853462386eed7c903af7c1b"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Datensatznavigation_per_Ribbon\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Datensatznavigation per Ribbon"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001415","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001415"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001415\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001415"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001415"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001415"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}