{"id":55000580,"date":"2008-04-01T00:00:00","date_gmt":"2021-02-11T21:20:13","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=580"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Navigationsleiste_im_Eigenbau","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/","title":{"rendered":"Navigationsleiste im Eigenbau"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg04.met.vgwort.de\/na\/af442c5614644f4a80c67b6f089ac717\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Die Navigationsschaltfl&auml;che ist so zweckm&auml;&szlig;ig, dass sie von Access-Entwicklern vermutlich oft kaum noch wahrgenommen wird: Soll der Benutzer zwischen den Datens&auml;tzen bl&auml;ttern oder soll er nicht Dementsprechend schaltet man die Eigenschaft Navigationsschaltfl&auml;chen anzeigen entweder an oder aus. Manchmal passt die eingebaute Variante aber auch einfach nicht: Beispielsweise, wenn die Anordnung von Haupt- und Unterformular eine eher verwirrende Anzeige der Navigationsschaltfl&auml;chen bewirkt oder wenn die Navigationsleiste einfach einmal ganz anders aussehen soll. <\/b><\/p>\n<p>Dieser Beitrag liefert gleich zweierlei f&uuml;r die unterschiedlichen Anspr&uuml;che: Der erste Teil zeigt, wie Sie mit wenig Aufwand eine selbst gebaute Schaltfl&auml;che &#8211; nennen wir sie der Einfachheit halber <b>aiuNavigationsleiste <\/b>&#8211; in Ihrem Formular unterbringen, und im zweiten Teil lernen Sie, wie diese nachgebaute Variante der Navigationsleiste funktioniert.<\/p>\n<p><b>Einsatz der aiuNavigationsleiste<\/b><\/p>\n<p>Die Beispieldatenbank enth&auml;lt einige Tabellen, auf deren Basis Sie ein Formular erstellen k&ouml;nnen. F&uuml;r den Anfang verwenden Sie die Tabelle <b>tblPersonal<\/b>: Erstellen Sie ein neues Formular und weisen Sie der Eigenschaft <b>Datenherkunft <\/b>den Namen dieser Tabelle zu. F&uuml;gen Sie dann die gew&uuml;nschten Felder aus der Feldliste in den Detailbereich ein. Wenn Sie nun in die Formularansicht wechseln, haben Sie die &uuml;bliche Navigationsleiste vor sich &#8211; die k&ouml;nnen Sie auch zun&auml;chst einmal beibehalten, um das Verhalten der eingebauten mit der neu hinzugef&uuml;gten selbst gebauten Navigationsleiste zu vergleichen (siehe Bild 1).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic001_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Ein Formular mit der eingebauten Navigationsleiste<\/span><\/b><\/p>\n<p>Wenn Sie die Navigationsleiste in einer eigenen Datenbank einsetzen m&ouml;chten, brauchen Sie nur die beiden Elemente <b>sfmNavigationsleiste <\/b>und <b>mdlNavigationsleiste <\/b>aus der Beispieldatenbank in die Datenbank zu importieren &#8211; die &uuml;brigen Schritte sind nachfolgend beschrieben.<\/p>\n<p><b>Unterformular als Navigationsleiste<\/b><\/p>\n<p>Die selbst gebaute Navigationsleiste kommt in Form eines Unterformulars. Warum das Warum kann man die Steuerelemente nicht einfach so in das Formular integrieren Klar kann man: Wenn man sich die Arbeit jedesmal neu machen m&ouml;chte &#8230; Das Unterformular hat jedoch den gro&szlig;en Vorteil, dass Sie die Steuerelemente nur einmal arrangieren m&uuml;ssen und auch deren Steuerung per VBA nur von einer Stelle innerhalb der Datenbank erfolgt.<\/p>\n<p>Die Vorteile bei der Verwendung eines Unterformulars zeigen sich bereits beim Einbau: Sie brauchen einfach nur das Zielformular in der Entwurfsansicht zu &ouml;ffnen und das Formular <b>sfmNavigationsleiste <\/b>vom Datenbankfenster (oder, in Access 2007, vom Navigationsbereich) in den gew&uuml;nschten Bereich zu ziehen. Dabei k&ouml;nnen Sie sich tats&auml;chlich &#8211; und das ist der gr&ouml;&szlig;te Vorteil der selbst gebauten Navigationsleiste &#8211; aussuchen, wo Sie es unterbringen. Das kann irgendwo im Detailbereich sein, aber auch im Kopf- oder im Fu&szlig;bereich des Formulars (nicht jedoch im Seitenkopf oder Seitenfu&szlig;, denn diese Bereiche sind nat&uuml;rlich nur beim Drucken sichtbar).<\/p>\n<p>Wenn Sie das Formular <b>sfmNavigationsleiste <\/b>nun beispielsweise unten im Formularfu&szlig; einf&uuml;gen, sieht das wie in Bild 2 aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic002_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Ein Formular mit frisch eingef&uuml;gter Navigationsleiste<\/span><\/b><\/p>\n<p>Das Hinzuf&uuml;gen der Beschriftung (hier Navigationselement) l&auml;sst sich leider nicht vermeiden, also entfernen Sie dieses Bezeichnungsfeld einfach und positionieren das Unterformular noch, sodass dieses wie in Bild 3 aussieht &#8211; hier ist aus Gr&uuml;nden der Optik bereits der Datensatzmarkierer ausgeblendet.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic003_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Die eingebaute Navigationsleiste in der Formularansicht<\/span><\/b><\/p>\n<p>Au&szlig;erdem wurde die Eigenschaft <b>Rahmenart <\/b>des Unterformularsteuerelements auf <b>Transparent <\/b>eingestellt.<\/p>\n<p><b>Anpassungen<\/b><\/p>\n<p>Es funktioniert bereits alles wie gew&uuml;nscht &#8211; dies zeigt ein Vergleich der Steuerelemente der eingebauten mit denen der selbst hinzugef&uuml;gten Navigationsleiste. Letztere bietet aber noch mehr M&ouml;glichkeiten, die Sie sich mit wenigen Zeilen Code erschlie&szlig;en k&ouml;nnen. Dazu legen Sie zun&auml;chst im Klassenmodul des Hauptformulars eine Variable an, in der Sie einen Verweis auf das Unterformular mit der Navigationsleiste speichern. Um ein Klassenmodul anzulegen, wechseln Sie in die Entwurfsansicht des Hauptformulars und legen eine Ereignisprozedur an &#8211; eine, die Sie ohnehin gleich ben&ouml;tigen. Es handelt sich um das Ereignis <b>Beim Laden<\/b>, das direkt beim &Atilde;-ffnen des Formulars ausgel&ouml;st wird.<\/p>\n<p>Um ein solches Ereignis anzulegen, zeigen Sie das Eigenschaftsfenster des Hauptformulars an und wechseln dort zur Registerseite <b>Ereignis<\/b>. Dort klicken Sie doppelt in die Eigenschaft <b>Beim Laden <\/b>und dann auf die nun erscheinende Schaltfl&auml;che mit den drei Punkten.<\/p>\n<p>Es &ouml;ffnet sich der VBA-Editor und zeigt eine leere Ereignisprozedur namens <b>Form_Load <\/b>an:<\/p>\n<pre>Private Sub Form_Load()\r\n    End Sub<\/pre>\n<p>Oberhalb dieser Routine schreiben Sie nun die folgende Zeile hin (ohne Zeilenumbruch):<\/p>\n<pre>Private WithEvents objNavi As\r\nForm_sfmNavigationsleiste<\/pre>\n<p>Damit legen Sie eine Variable an, in der Sie einen Verweis auf das Klassenmodul des Unterformulars speichern. Das Schl&uuml;sselwort <b>WithEvents <\/b>besagt, dass es m&ouml;glich ist, auf das Ausl&ouml;sen von Ereignissen des Unterformulars zu reagieren. Und das ist eine interessante Geschichte: Sie k&ouml;nnen so im Hauptformular beispielsweise eine Ereignisprozedur f&uuml;r das Unterformular anlegen, die ausgel&ouml;st wird, wenn das gleiche Ereignis im Unterformular auftritt. Wie Sie davon profitieren k&ouml;nnen, erfahren Sie gleich &#8211; zun&auml;chst einmal m&uuml;ssen Sie die Objektvariable <b>objNavi<\/b> f&uuml;llen.<\/p>\n<p>Und dazu verwenden Sie genau die gerade angelegte Ereignisprozedur <b>Beim Laden<\/b>. Hier f&uuml;gen Sie dazu die folgende Zeile ein:<\/p>\n<pre>Private Sub Form_Load()\r\n    Set objNavi = Me!Navigationselement.Form\r\n    End Sub<\/pre>\n<p><b>Schaltfl&auml;chen anpassen<\/b><\/p>\n<p>Die erste M&ouml;glichkeit, die sich durch das Referenzieren des Unterformulars ergibt, ist das Anpassen der angezeigten Schaltfl&auml;chen. Die <b>aiuNavigationsleiste<\/b> liefert n&auml;mlich nicht nur die Standardschaltfl&auml;chen, sondern auch noch weitere. Welche das sind, erfahren Sie &uuml;ber die Konstanten, mit denen Sie die Schaltfl&auml;chen ausw&auml;hlen. Dazu geben Sie einige weitere Zeilen ein, zun&auml;chst jedoch die folgenden:<\/p>\n<pre>With objNavi\r\nEnd With<\/pre>\n<p>Zwischen diese Zeilen brauchen Sie nur noch einen Punkt zu setzen, damit IntelliSense automatisch die Eigenschaften und Methoden des Unterformulars anzeigt. In Bild 4 ist dies bereits geschehen, dort wurde die Eigenschaft <b>ButtonSet<\/b> ausgew&auml;hlt. Nach Eingabe des Gleichheitszeichens finden Sie alle m&ouml;glichen Konstanten f&uuml;r die einzelnen Schaltfl&auml;chen vor:<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic004_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Festlegen individueller Schaltfl&auml;chen f&uuml;r die Navigationsleiste<\/span><\/b><\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>eButtonFirst<\/b>: zum ersten Datensatz<\/li>\n<li class=\"aufz-hlung\"><b>eButtonLast<\/b>: zum letzten Datensatz<\/li>\n<li class=\"aufz-hlung\"><b>eButtonNext<\/b>: zum n&auml;chsten Datensatz<\/li>\n<li class=\"aufz-hlung\"><b>eButtonPrev<\/b>: zum vorherigen Datensatz<\/li>\n<li class=\"aufz-hlung\"><b>eButtonFastNext<\/b>: bl&auml;ttert mehrere Datens&auml;tze vor (Standard: zehn Datens&auml;tze)<\/li>\n<li class=\"aufz-hlung\"><b>eButtonFastPrev<\/b>: bl&auml;ttert mehrere Datens&auml;tze zur&uuml;ck (Standard: zehn Datens&auml;tze)<\/li>\n<li class=\"aufz-hlung\"><b>eButtonNew<\/b>: neuer Datensatz<\/li>\n<li class=\"aufz-hlung\"><b>eButtonDel<\/b>: Datensatz l&ouml;schen<\/li>\n<li class=\"aufz-hlung\"><b>eButtonCount<\/b>: Anzahl der Datens&auml;tze<\/li>\n<li class=\"aufz-hlung\"><b>eButtonNo<\/b>: aktuelle Datensatznummer (nicht zu verwechseln mit dem Prim&auml;rschl&uuml;sselwert)<\/li>\n<li class=\"aufz-hlung\"><b>eButtonStore<\/b>: Datensatz speichern<\/li>\n<li class=\"aufz-hlung\"><b>eButtonUndo<\/b>: R&uuml;ckg&auml;ngig<\/li>\n<\/ul>\n<p>Wenn Sie die Schaltfl&auml;chen individuell zusammenstellen m&ouml;chten, geben Sie die gew&uuml;nschten Konstanten durch den Operator <b>Or <\/b>getrennt an.<\/p>\n<p>Wenn Sie dort etwa die folgende Kombination eingeben, erhalten Sie die Navigationsleiste aus Bild 5:<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic005_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5: Navigationsleiste mit nur zwei Schaltfl&auml;chen<\/span><\/b><\/p>\n<pre>With objNavi\r\n.ButtonSet = eButtonPrev Or eButtonNext\r\nEnd With<\/pre>\n<p>Sie k&ouml;nnen auch auf fertige Sets von Navigationselementen zugreifen. Diese sind in Form weiterer Konstanten im Modul <b>mdlNavigationsleiste <\/b>zusammengefasst. Die Standardvariante sieht beispielsweise so aus (ohne Zeilenumbruch):<\/p>\n<pre>Public Const eButtonStd = eButtonFirst Or\r\neButtonLast Or eButtonNext Or eButtonPrev Or eButtonCount Or eButtonNo Or eButtonNew<\/pre>\n<p><b>Farbe anpassen<\/b><\/p>\n<p>M&ouml;glicherweise hat das Hauptformular eine andere Hintergrundfarbe als das Unterformular mit den Navigationsschaltfl&auml;chen. Auch f&uuml;r diesen Fall ist vorgesorgt: Sie k&ouml;nnen dann die Methode <b>AdjustColor <\/b>aufrufen. Diese liest die Farbe des passenden Bereichs des Hauptformulars ein und wendet diese Farbgebung auf das Unterformular an.<\/p>\n<p><b>Auf Aktionen reagieren<\/b><\/p>\n<p>Wie oben erw&auml;hnt, wurde die Variable <b>objNavi <\/b>als <b>WithEvents <\/b>deklariert, um auf Ereignisse des Unterformulars reagieren und f&uuml;r diese eigene Funktionen implementieren zu k&ouml;nnen.<\/p>\n<p>Das geht ganz leicht: Klicken Sie einfach einmal im Codefenster des VBA-Editors auf das Kombinationsfeld links oben und w&auml;hlen Sie dort den Eintrag <b>objNavi <\/b>aus. Der VBA-Editor legt automatisch die Ereignisprozedur <b>objNavi_NaviClick<\/b> an (siehe Bild 6). Diese hat zwei Parameter:<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic006_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6: Das Ereignis NaviClick wird jedesmal ausgel&ouml;st, wenn der Benutzer auf eine Schaltfl&auml;che der Navigationsleiste klickt.<\/span><\/b><\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>Button <\/b>liefert die Konstante f&uuml;r die Schaltfl&auml;che, die der Benutzer angeklickt hat, und<\/li>\n<li class=\"aufz-hlung\"><b>Cancel <\/b>erwartet den R&uuml;ckgabewert <b>True<\/b>, wenn der Vorgang abgebrochen werden soll.<\/li>\n<\/ul>\n<p>Wir demonstrieren die Funktionsweise an einem einfachen Beispiel. Angenommen, der Benutzer soll vor dem L&ouml;schen eines Datensatzes zun&auml;chst gefragt werden, ob er diesen auch tats&auml;chlich l&ouml;schen m&ouml;chte.<\/p>\n<p>Dann legen Sie die oben genannte Ereignisprozedur an und pr&uuml;fen darin, ob der Benutzer die <b>L&ouml;schen<\/b>-Schaltfl&auml;che gedr&uuml;ckt hat. Falls ja, soll Access ein Meldungsfenster anzeigen, das den Benutzer fragt, ob er den Datensatz tats&auml;chlich l&ouml;schen m&ouml;chte. Das sieht im Zusammenhang so wie in Listing 1 aus.<\/p>\n<p class=\"kastentabelleheader\">Listing 1: Abfrage beim L&ouml;schen eines Datensatzes<\/p>\n<pre>Private Sub objNavi_NaviClick(Button As eButtonSet, Cancel As Boolean)\r\n    Select Case Button\r\n    Case eButtonSet.eButtonDel\r\n    If MsgBox(&euro;&#156;M&ouml;chten Sie den Datensatz tats&auml;chlich l&ouml;schen&euro;, vbYesNo Or vbCritical, _\r\n    &euro;&#156;L&ouml;schbest&auml;tigung&euro;) = vbNo Then\r\n    Cancel = True\r\nEnd If\r\nEnd Select\r\nEnd Sub<\/pre>\n<p><b>Schaltfl&auml;chen aktivieren oder deaktivieren<\/b><\/p>\n<p>Genau so wie Sie nur eine bestimmte Menge angezeigter Schaltfl&auml;chen festlegen k&ouml;nnen, besteht auch die M&ouml;glichkeit, Schaltfl&auml;chen zu aktivieren oder zu deaktivieren.<\/p>\n<p>Dies kann zum Beispiel notwendig sein, wenn ein Benutzer keine Berechtigung hat, einen Datensatz anzulegen oder zu l&ouml;schen.<\/p>\n<p>In dem Fall verwenden Sie die Methode <b>EnableButton<\/b>, die als Parameter die Angabe einer oder mehrerer Schaltfl&auml;chen-Konstanten erwartet. Dieses Beispiel sorgt f&uuml;r das Ausblenden der Schaltfl&auml;chen wie in Bild 7.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic007_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 7: Deaktivierte Navigationsschaltfl&auml;chen<\/span><\/b><\/p>\n<pre>Private Sub Form_Load()\r\n    Set objNavi = Me!Navigationselement.Form\r\n    With objNavi\r\n    .EnableButton eButtonDel Or _\r\n    eButtonNew, False\r\n    End With\r\n    End Sub<\/pre>\n<p><!--30percent--><\/p>\n<p><b>Schnell vor- und zur&uuml;ckbl&auml;ttern<\/b><\/p>\n<p>Eine Erweiterung gegen&uuml;ber der herk&ouml;mmlichen Navigationsleiste sind die beiden Schaltfl&auml;chen zum schnellen Vor- und Zur&uuml;ckbl&auml;ttern zwischen den Datens&auml;tzen. Diese aktivieren Sie mit folgenden Zeilen:<\/p>\n<pre>With objNavi\r\n.ButtonSet = eButtonStd Or eButtonFastNext _\r\nOr eButtonFastPrev\r\n.WindFactor = 5\r\nEnd With<\/pre>\n<p>Die erste legt fest, dass neben den Standardschaltfl&auml;chen auch noch die beiden Schaltfl&auml;chen zum schnellen Vor- und Zur&uuml;ckbl&auml;ttern angezeigt werden, und die zweite stellt die Anzahl der jeweils &uuml;bersprungenen Datens&auml;tze ein. Im Formular erscheint die Navigationsschaltfl&auml;che nun so wie in Bild 8.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic008_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 8: Schnelles Vor- und Zur&uuml;ckbl&auml;ttern<\/span><\/b><\/p>\n<p><b>Programmierung der aiuNavigationsleiste<\/b><\/p>\n<p>Sie haben nun alles erfahren, was Sie zum Einsetzen der selbst gebauten Navigationsschaltfl&auml;che brauchen &#8211; nun geht es ans Eingemachte, n&auml;mlich an die dahintersteckenden Techniken.<\/p>\n<p>Das ben&ouml;tigte Unterformular sieht, hier der &Atilde;&#156;bersicht halber mit nebeneinander angeordneten Steuerelementen dargestellt, wie in Bild 9 aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic009_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 9: Das Unterformular mit den Elementen der Navigationsleiste in der Entwurfsansicht<\/span><\/b><\/p>\n<p><b>Hauptformular suchen<\/b><\/p>\n<p>Damit das Unterformular &uuml;berhaupt mit dem Hauptformular interagieren kann, muss es auf dieses zugreifen k&ouml;nnen. Dies geschieht in der Regel &uuml;ber einen Ausdruck wie <b>Me.Parent<\/b>.<\/p>\n<p>Da quasi jede Routine des Unterformulars <b>sfmNavigationsleiste<\/b> auf das Hauptformular zugreift, macht es Sinn, einen Verweis auf dieses in einer entsprechenden Objektvariablen zu speichern. Diese deklarieren Sie wie folgt:<\/p>\n<pre>Private WithEvents m_frm As Access.Form<\/pre>\n<p>Die Variable wird, wie schon bei der Objektvariablen zum Verweis auf das Unterformular im Hauptformular geschehen, mit dem Schl&uuml;sselwort <b>WithEvents<\/b> deklariert. Dies ist hier besonders wichtig: Immerhin zeigt das Unterformular Daten an, die es aus dem Hauptformular bezieht, und um auf dem aktuellsten Stand zu bleiben, muss es mitbekommen, wenn der Benutzer im Hauptformular den Datensatz wechselt, l&ouml;scht oder einen neuen Datensatz anlegt.<\/p>\n<p>Die Zuweisung eines Verweises auf das Hauptformular geschieht in der Prozedur, die durch das Ereignis <b>Beim Laden <\/b>ausgel&ouml;st wird. Dort passiert noch eine Menge mehr, dazu kommen wir jedoch erst sp&auml;ter.<\/p>\n<pre>Private Sub Form_Load()\r\n    ...\r\n    Set m_frm = Me.Parent\r\n    m_frm.OnCurrent = &euro;&#156;[Event Procedure]&euro;\r\n    ...\r\n    End Sub<\/pre>\n<p>Neben der Zuweisung des Formulars weist eine zweite Zeile der Eigenschaft <b>OnCurrent <\/b>des Hauptformulars den Wert <b>[Event Procedure] <\/b>zu.<\/p>\n<p>Was bedeutet das Nun: Wenn ein Objekt, das Ereignisse ausl&ouml;st, mit dem Schl&uuml;sselwort <b>WithEvents <\/b>deklariert wird, kann man sich, wie bereits oben beschrieben, in die Ereignisprozeduren dieses Objekts einklinken.<\/p>\n<p>Manchmal wei&szlig; man aber gar nicht, ob ein solches Ereignis &uuml;berhaupt eine Prozedur ausl&ouml;st. So ist es hier: Man kann durchaus einem Formular das Unterformular mit der Navigationsleise zuweisen, ohne dass dieses zwingend eine Routine <b>Form_Current <\/b>enth&auml;lt.<\/p>\n<p>Damit das Unterformular nun trotzdem darauf reagieren kann, legt es diese Ereignisprozedur einfach selbst an &#8211; und zwar in zwei Schritten: Der erste ist das Hinzuf&uuml;gen des Werts <b>[Event Procedure] <\/b>zu der gew&uuml;nschten Ereigniseigenschaft, der zweite das Anlegen einer Ereignisprozedur f&uuml;r dieses Ereignis. Der erste Schritt ist getan, der zweite folgt sogleich &#8211; n&auml;mlich die Implementierung der Ereignisprozedur, die durch das Ereignis <b>Beim Anzeigen <\/b>des Hauptformulars ausgel&ouml;st wird:<\/p>\n<pre>Private Sub m_frm_Current()\r\n    Me!btnStore.Enabled = False\r\n    Me!btnUndo.Enabled = False\r\n    If flagDelete Then Exit Sub\r\n    GetCounter\r\n    End Sub<\/pre>\n<p>Dieses deaktiviert die beiden Schaltfl&auml;chen zum Speichern des aktuellen Datensatzes und zum R&uuml;ckg&auml;ngigmachen von &Atilde;&#8220;nderungen und ruft die Routine <b>GetCounter <\/b>auf, welche die der aktuellen Position des Datensatzzeigers entsprechende Zahl ermittelt und in das Textfeld zur Anzeige dieser Zahl eintr&auml;gt.<\/p>\n<p><b>Nummer des aktuellen Datensatzes<\/b><\/p>\n<p>Diese Routine finden Sie in Listing 2. Sie pr&uuml;ft zun&auml;chst, ob das &uuml;bergeordnete Formular schon der Objektvariablen <b>objNavi <\/b>zugeordnet ist, und holt dies gegebenenfalls nach. Dann pr&uuml;ft sie die Eigenschaft <b>NewRecord <\/b>des Hauptformulars, die Aufschluss dar&uuml;ber gibt, ob der aktuell im Hauptformular angezeigte Datensatz soeben angelegt und noch nicht gespeichert wurde. In diesem Fall tr&auml;gt die Routine einfach ein Plus-Zeichen in das Textfeld <b>txtCounter <\/b>ein (siehe Bild 10).<\/p>\n<p class=\"kastentabelleheader\">Listing 2: Z&auml;hlen und Eintragen der aktuellen Datensatznummer<\/p>\n<pre>Private Sub GetCounter()\r\n    Dim n As Long\r\n    flagCounter = True\r\n    If m_frm Is Nothing Then Set m_frm = Me.Parent.Form\r\n    If m_frm.NewRecord Then\r\n        txtCounter = &euro;&#156;+&euro;\r\n        LblInfo.Caption = &euro;&#156;()&euro;\r\n    Else\r\n        DoEvents\r\n            n = m_frm.CurrentRecord\r\n            txtCounter = n\r\n            If (m_Buttons And eButtonSet.eButtonNo) &lt;&gt; 0 Then\r\n                Dim rs As DAO.Recordset\r\n                On Error Resume Next\r\n                Set rs = m_frm.RecordsetClone\r\n                rs.MoveLast\r\n                n = rs.RecordCount\r\n                If n &lt; 0 Then n = 0\r\n                If m_InfoPos = 1 Then\r\n                    LblInfo.Caption = &euro;&#156;(&euro;&#156; &amp; n &amp; &euro;&#156; Datens&auml;tze)&euro;\r\n                Else\r\n                    LblInfo.Caption = &euro;&#156;von &euro;&#156; &amp; n &amp; &euro;&#156; gesamt&euro;\r\n                End If\r\n                Set rs = Nothing\r\n            End If\r\n        End If\r\n        flagCounter = False\r\n        End Sub<\/pre>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic010_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 10: Beim Anlegen eines neuen Datensatzes zeigt das Formular statt einer Datensatznummer das Plus-Zeichen an.<\/span><\/b><\/p>\n<p>Falls der Datensatz nicht neu ist, geschieht Folgendes: Die Variable <b>n <\/b>erh&auml;lt den Wert der Eigenschaft <b>CurrentRecord <\/b>des Hauptformulars. Diese Eigenschaft ermittelt die Nummer des aktuellen Datensatzes, wobei die Datens&auml;tze entsprechend der Reihenfolge der Datenherkunft durchnummeriert sind. Der Wert landet dann im Textfeld <b>txtCounter<\/b>.<\/p>\n<p>Wie es weitergeht, h&auml;ngt davon ab, ob das Bezeichnungsfeld zur Anzeige der Gesamtzahl der Datens&auml;tze im Formular angezeigt werden soll. Dazu wird der Ausdruck <b>m_Buttons And eButtonSet.eButtonNo <\/b>untersucht.<\/p>\n<p><b>mButtons <\/b>ist der Wert, der die Zusammenstellung der anzuzeigenden Steuerelemente enth&auml;lt (beispielsweise <b>eButtonStd <\/b>oder wie in einem Beispiel oben angegeben <b>eButtonStd Or eButtonFastNext Or eButtonFastPrev<\/b>).<\/p>\n<p>Der Ausdruck verwendet die logische Konjunktion (<b>And<\/b>, mehr Informationen im Beitrag <b>Rund um Bin&auml;rzahlen<\/b>, Shortlink 556), um zu ermitteln, ob die Konstante <b>eButtonSet.eButtonNo <\/b>in <b>m_Buttons <\/b>enthalten ist. Falls ja, soll das Bezeichnungsfeld angezeigt werden, und dann f&uuml;llt die Routine <b>GetCounter <\/b>dieses auch. Sie erzeugt dazu ein neues Recordset auf Basis der Eigenschaft <b>RecordsetClone <\/b>des Hauptformulars, springt mit <b>MoveLast <\/b>zum letzten Datensatz und ermittelt dann mit <b>RecordCount <\/b>die Anzahl der enthaltenen Datens&auml;tze. F&uuml;r das Bezeichnungsfeld zur Ausgabe der Anzahl der Datens&auml;tze gibt es zwei m&ouml;gliche Positionen, wobei je nach Position ein spezieller Text angezeigt werden soll &#8211; dies erledigen die &uuml;brigen Zeilen der Routine.<\/p>\n<p><b>Parameter des <\/b><\/p>\n<pre>Unterformulars<\/pre>\n<p>Die Variablen <b>m_Buttons <\/b>und <b>m_InfoPos <\/b>aus der zuvor vorgestellten Routine sind zwei von mehreren Member-Variablen, die das Aussehen der Navigationsleiste einstellen. Diese Variablen werden wie folgt deklariert:<\/p>\n<pre>Private m_Buttons As Long\r\nPrivate m_InfoPos As Long\r\nPrivate m_Automatic As Boolean\r\nPrivate m_FastFactor As Long\r\nPrivate m_ShowBmps As Boolean\r\nPrivate m_Events As Boolean\r\nPrivate flagCounter As Boolean\r\nPrivate flagDelete As Boolean<\/pre>\n<p>Diese Variablen k&ouml;nnen Sie alle vom Hauptformular aus &uuml;ber entsprechende &ouml;ffentliche <b>Property<\/b>-Prozeduren einstellen, die Sie in Listing 3 finden. Eine dieser <b>Propery<\/b>-Prozeduren erledigt mehr, als nur die Member-Variable zu f&uuml;llen: Die Prozedur <b>Windfactor <\/b>weist nicht nur die Anzahl der Datens&auml;tze, die beim schnellen Vor- beziehungsweise Zur&uuml;ckbl&auml;ttern &uuml;bersprungen werden soll, zu, sondern aktualisiert auch noch den Text, der im Formular beim &Atilde;&#156;berfahren der entsprechenden Schaltfl&auml;chen angezeigt wird, auf die entsprechende Anzahl (siehe Bild 8).<\/p>\n<p class=\"kastentabelleheader\">Listing 3: Property-Prozeduren zum Einstellen der Membervariablen<\/p>\n<pre>Public Property Set PForm(AForm As Access.Form)\r\nIf m_frm Is Nothing Then Set m_frm = AForm\r\nEnd Property\r\nPublic Property Let ButtonSet(ASet As eButtonSet)\r\nm_Buttons = ASet\r\nRedraw\r\nEnd Property\r\nPublic Property Let InfoPosition(pos As eInfoPosition)\r\nm_InfoPos = pos\r\nRedraw\r\nEnd Property\r\nPublic Property Let AutoMode(OnOff As Boolean)\r\nm_Automatic = OnOff\r\nEnd Property\r\nPublic Property Let ShowBmps(OnOff As Boolean)\r\nm_ShowBmps = OnOff\r\nRedraw\r\nEnd Property\r\nPublic Property Let WindFactor(count As Long)\r\nm_FastFactor = count\r\nMe.btnForward.ControlTipText = m_FastFactor &amp; &euro;&#156; Datens&auml;tze&euro; _\r\n&amp; &euro;&#156; vorw&auml;rts&euro;\r\nMe.btnRewind.ControlTipText = m_FastFactor &amp; &euro;&#156; Datens&auml;tze&euro; _\r\n&amp; &euro;&#156; zur&uuml;ck&euro;\r\nEnd Property\r\nPublic Property Get FormWidth() As Long\r\nFormWidth = Me.Width\r\nEnd Property\r\nPublic Property Let Allowevents(OnOff As Boolean)\r\nm_Events = OnOff\r\nEnd Property<\/pre>\n<p>Die &ouml;ffentlichen Property-Prozeduren zeigen sich beim Einstellen der Eigenschaften vom Hauptformular aus dann wie in Bild 11.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2008_02\/Navigationsleiste-web-images\/pic011_opt.jpeg\" alt=\"missing image file\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 11: Auswirkung der &ouml;ffentlichen Property-Prozeduren<\/span><\/b><\/p>\n<p><b>Aktionen der einzelnen Schaltfl&auml;chen<\/b><\/p>\n<p>Das Formular enth&auml;lt f&uuml;r jede der Schaltfl&auml;chen eine Ereignisprozedur, die beim Klicken ausgel&ouml;st wird. Den Start macht die Schaltfl&auml;che, die einen Sprung auf den ersten Datensatz der Datenherkunft des Hauptformulars erlaubt:<\/p>\n<pre>Private Sub btnFirst_Click()\r\n    Dim b As Boolean\r\n    If m_Events Then RaiseEvent _\r\n    NaviClick(eButtonFirst, b)\r\n    On Error Resume Next\r\n    If m_Automatic Then If Not b Then m_frm.Recordset.MoveFirst\r\n    End Sub<\/pre>\n<p>Gleich die erste Anweisung dieser Routine stellt Einsteiger vor R&auml;tsel: Eine Funktion namens <b>RaiseEvent <\/b>findet sich im gesamten Quellcode nicht, also muss es eine VBA-Anweisung sein &#8211; doch wozu Vielleicht erinnern Sie sich: Weiter oben haben Sie vom Hauptformular aus Ereignisprozeduren des Unterformulars implementiert, in diesem speziellen Fall die Prozedur f&uuml;r das Ereignis <b>NaviClick<\/b>. Und genau die Anweisung <b>If m_Events Then RaiseEvent NaviClick(eButtonFirst, b) <\/b>l&ouml;st ein solches Ereignis aus. <\/p>\n<p>Dieses muss allerdings noch definiert werden und zwar durch die folgende Zeile:<\/p>\n<pre>Public Event NaviClick(Button As eButtonSet, _\r\nCancel As Boolean)<\/pre>\n<p>F&uuml;r den ersten Parameter &uuml;bergibt die Routine den Wert der Konstanten <b>eButtonFirst <\/b>(f&uuml;r die ausl&ouml;sende Schaltfl&auml;che <b>btnFirst<\/b>), f&uuml;r den zweiten die Variable <b>b<\/b>, die als R&uuml;ckgabewert entweder <b>True <\/b>oder <b>False <\/b>erwartet, je nachdem, ob die Aktion abgebrochen werden soll oder nicht.<\/p>\n<p>Danach folgt eine weitere Membervariable namens <b>m_Automatic<\/b>, deren Sinn noch nicht erl&auml;utert wurde: Mit ihr kann der Entwickler festlegen, ob die durch die Schaltfl&auml;chen der Navigationsleiste ausgel&ouml;sten Aktionen komplett selbst im Hauptformular implementieren m&ouml;chte oder die Implementierung im Unterformular verwenden will. &Atilde;&#156;blicherweise sollte Letzteres der Fall sein. Hat <b>m_Automatic <\/b>den Wert <b>True <\/b>und <b>b <\/b>auch, wird die <b>MoveFirst<\/b>-Methode des Recordset-Objekts im Hauptformular ausgef&uuml;hrt, was einen Sprung zum ersten Datensatz des Hauptformulars bewirkt.<\/p>\n<p>Die Methode zum Anspringen des letzten Datensatzes der Datenherkunft sieht &auml;hnlich aus. Der einzige Unterschied ist der Einsatz der Methode <b>MoveLast<\/b>:<\/p>\n<pre>Private Sub btnLast_Click()\r\n    ...\r\n    m_frm.Recordset.MoveLast\r\n    ...\r\n    End Sub<\/pre>\n<p>Der Weg zum n&auml;chsten Datensatz f&uuml;hrt &uuml;ber die Methode <b>MoveNext<\/b>. Die passende Routine pr&uuml;ft noch, ob m&ouml;glicherweise gerade ein neuer Datensatz angelegt wurde oder ob der Datensatzzeiger ohnehin auf dem letzten Datensatz steht.<\/p>\n<pre>Private Sub btnNext_Click()\r\n    ...\r\n    If m_frm.NewRecord Then Exit Sub\r\n    If m_frm.CurrentRecord &lt;&gt; _\r\n    m_frm.Recordset.RecordCount Then _\r\n    m_frm.Recordset.MoveNext\r\n    ...\r\n    End Sub<\/pre>\n<p>&Atilde;&#8220;hnlich sieht es beim Ausw&auml;hlen des vorherigen Datensatzes aus. Dort ist allerdings eine Pr&uuml;fung notwendig, ob sich der Datensatzzeiger gerade auf einem neuen Datensatz befindet; in dem Fall soll er zum letzten vorhandenen Datensatz springen. Ist das nicht der Fall, sorgt <b>MovePrevious <\/b>f&uuml;r einen Sprung auf den vorherigen Datensatz &#8211; vorausgesetzt, der Datensatzzeiger befindet sich gerade nicht ohnehin auf dem ersten Datensatz.<\/p>\n<pre>Private Sub btnPrev_Click()\r\n    ...\r\n    If m_frm.NewRecord Then\r\n        m_frm.Recordset.MoveLast\r\n    Else\r\n        If m_frm.CurrentRecord &gt; 1 Then _\r\n        m_frm.Recordset.MovePrevious\r\n    End If\r\n    ...\r\n    End Sub<\/pre>\n<p><b>Schnell vor- und zur&uuml;ckbl&auml;ttern<\/b><\/p>\n<p>Die beiden Schaltfl&auml;chen <b>btnForward <\/b>und <b>btnRewind <\/b>sollen daf&uuml;r sorgen, dass der Datensatzzeiger die f&uuml;r die Variable <b>m_Windfactor <\/b>angegebene Anzahl Datens&auml;tze nach vorne beziehungsweise nach hinten bl&auml;ttert. Die beiden Routinen verwenden die Eigenschaft der <b>DoCmd.GotoRecord<\/b>-Methode, mehrere Datens&auml;tze gleichzeitig &uuml;berspringen zu k&ouml;nnen. Dabei kann es vorkommen, dass der Datensatzzeiger einfach nicht mehr so weit wie gew&uuml;nscht verschoben werden kann, weil er sich schon zu nahe am ersten beziehungsweise letzten Datensatz befindet. In dem Fall l&ouml;st <b>DoCmd.GotoRecord <\/b>einen Fehler aus, der durch die vorherige <b>On Error Resume Next<\/b>-Anweisung zwar nicht angezeigt wird, sich aber durch einen Wert f&uuml;r <b>Err.Number <\/b>ungleich <b>0 <\/b>bemerkbar macht. Und dann wird der Datensatz einfach auf den ersten beziehungsweise letzten Datensatz verschoben.<\/p>\n<pre>Private Sub btnForward_Click()\r\n    ...\r\n    On Error Resume Next\r\n    ...\r\n    DoCmd.GoToRecord acDataForm, m_frm.Name, _\r\n    acNext, m_FastFactor\r\n    If Err.Number &lt;&gt; 0 Then _\r\n    m_frm.Recordset.MoveLast\r\n    Me.Parent.Refresh\r\n    m_frm.Recordset.Move 0\r\n    ...\r\n    End Sub\r\nPrivate Sub btnRewind_Click()\r\n    ...\r\n    On Error Resume Next\r\n    ...\r\n    DoCmd.GoToRecord acDataForm, _\r\n    m_frm.Name, acPrevious, m_FastFactor\r\n    If Err.Number &lt;&gt; 0 Then _\r\n    m_frm.Recordset.MoveFirst\r\n    Me.Parent.Refresh\r\n    m_frm.Recordset.Move 0\r\n    ...\r\n    End Sub<\/pre>\n<p><b>Neuen Datensatz anlegen<\/b><\/p>\n<p>Das Anlegen eines neuen Datensatzes erledigt die Schaltfl&auml;che <b>btnNew<\/b>. Diese setzt den Fokus auf das Hauptformular, speichert den aktuellen Datensatz und legt mit der <b>GotoRecord<\/b>-Methode des <b>DoCmd<\/b>-Objekts mit den entsprechenden Parametern einen neuen Datensatz an (hier k&ouml;nnte man auch die <b>AddNew<\/b>-Methode des <b>Recordset<\/b>-Objekts des Formulars einsetzen, dies f&uuml;hrt jedoch in Verbindung mit den <b>Attachment<\/b>-Feldern von Access 2007 oder OLE-Feldern fr&uuml;herer Versionen unter Umst&auml;nden zu Problemen).<\/p>\n<pre>Private Sub btnNew_Click()\r\n    ...\r\n    On Error Resume Next\r\n    ...\r\n    Forms(m_frm.Name).SetFocus\r\n    RunCommand acCmdSaveRecord\r\n    DoEvents\r\n        DoCmd.GoToRecord acDataForm, m_frm.Name, _\r\n        acNewRec\r\n        RaiseEvent DataChanged\r\n        ...\r\n        End Sub<\/pre>\n<p>Diese Routine l&ouml;st &uuml;brigens das Ereignis <b>DataChanged <\/b>aus, das wie folgt deklariert ist und gegebenenfalls vom Hauptformular aus abgefangen werden kann.<\/p>\n<pre>    Public Event DataChanged()<\/pre>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">L&ouml;schen des aktuellen Datensatzes<\/p>\n<p>Mit <b>btnDelete<\/b> bietet die Navigationsleiste auch die M&ouml;glichkeit zum L&ouml;schen des aktuellen Datensatzes. Die passende Ereignisprozedur finden Sie in Listing 4. Die Routine l&ouml;st zun&auml;chst das Ereignis <b>NaviClick<\/b> aus, um bei einer m&ouml;glicherweise im Hauptformular vorhandenen Implementierung dieses Ereignisses dem Benutzer die Gelegenheit zu geben, den <b>L&ouml;schen<\/b>-Vorgang abzubrechen (wie das im Hauptformular funktioniert, haben Sie bereits weiter vorne gelesen).<\/p>\n<p class=\"kastentabelleheader\">Listing 4: L&ouml;schen des aktuellen Datensatzes<\/p>\n<pre>Private Sub btnDelete_Click()\r\n    Dim b As Boolean, ctl As Access.Control\r\n    If m_Events Then RaiseEvent NaviClick(eButtonDel, b)\r\n    If m_Automatic Then\r\n        If m_frm.NewRecord Then Exit Sub\r\n        If Not b Then\r\n            On Error Resume Next\r\n            m_frm.Form.SetFocus\r\n            On Error Resume Next\r\n            For Each ctl In m_frm.Section(acDetail).Controls\r\n                If (ctl.ControlType = acTextBox) Then\r\n                    Err.Clear\r\n                    ctl.SetFocus\r\n                    If Err.Number = 0 Then Exit For\r\n                End If\r\n            Next ctl\r\n            On Error GoTo 0\r\n            flagDelete = True\r\n            DoCmd.RunCommand acCmdSelectRecord\r\n            DoCmd.RunCommand acCmdDeleteRecord\r\n            DoEvents\r\n                flagDelete = False\r\n                btnPrev_Click\r\n                RaiseEvent DataChanged\r\n            End If\r\n        End If\r\n        Set ctl = Nothing\r\n        End Sub<\/pre>\n<p>Ist der aktuelle Datensatz ein neuer Datensatz, bricht die Routine an dieser Stelle ab &#8211; ein neuer Datensatz ist noch nicht gespeichert, kann also auch nicht gel&ouml;scht werden.<\/p>\n<p>Hat <b>b<\/b>, der R&uuml;ckgabewert der Ereignisprozedur <b>NaviClick<\/b>, den Wert <b>False<\/b>, weil die Ereignisprozedur entweder gar nicht ausgel&ouml;st wurde oder der Benutzer diesen Wert zur&uuml;ckgeliefert hat, kann der L&ouml;schvorgang beginnen.<\/p>\n<p>Dazu setzt die Routine zun&auml;chst den Fokus auf das Hauptformular und durchl&auml;uft alle im Detailbereich enthaltenen Steuerelemente, bis sie ein Textfeld findet und den Fokus auf dieses setzt. Dies ist notwendig, weil die nachfolgende <b>L&ouml;schen<\/b>-Anweisung nur funktioniert, wenn der zu l&ouml;schende Datensatz mit dem Datensatzmarkierer markiert wurde (was nicht funktionieren kann, weil dieser ausgeblendet ist) oder dies automatisch geschieht, was aber nur funktioniert, wenn eines der Felder der Datenherkunft den Fokus besitzt (die Routine geht wohlwollend davon aus, dass sich nur gebundene Textfelder im Detailbereich befinden).<\/p>\n<p>Schlie&szlig;lich markiert die Routine den Datensatz mit <b>DoCmd.RunCommand acCmdSelectRecord <\/b>und l&ouml;scht ihn mit <b>DoCmd.RunCommand acCmdDeleteRecord<\/b>. Durch den Aufruf von <b>btnPrevious_Click <\/b>wird der Datensatzzeiger auf den vorherigen Datensatz gesetzt.<\/p>\n<p><b>Aktuellen Datensatz speichern<\/b><\/p>\n<p>Die Routine zum Speichern des aktuellen Datensatzes arbeitet &auml;hnlich wie die zum L&ouml;schen: Sie sucht sich zun&auml;chst eines der Textfelder im Detailbereich des Hauptformulars heraus und setzt den Fokus auf dieses, bevor es den Datensatz mit <b>DoCmd.RunCommand acCmdSaveRecord <\/b>speichert:<\/p>\n<pre>    Private Sub btnStore_Click()\r\n        Me.Parent.SetFocus\r\n        If Err.Number &lt;&gt; 0 Then\r\n            Dim ctl As Access.Control\r\n            For Each ctl In Me.Parent.Controls\r\n                Err.Clear\r\n                ctl.SetFocus\r\n                If Err.Number = 0 Then Exit For\r\n            Next ctl\r\n        End If\r\n        On Error GoTo 0\r\n        RunCommand acCmdSaveRecord\r\n        Me!btnNext.SetFocus\r\n        Me!btnStore.Enabled = False\r\n        Me!btnUndo.Enabled = False\r\n        End Sub<\/pre>\n<p><b>Datensatz &uuml;ber den Counter ausw&auml;hlen<\/b><\/p>\n<p>Der Benutzer kann nicht nur &uuml;ber diverse Schaltfl&auml;chen, sondern auch durch Eingabe der gew&uuml;nschten Position des Datensatzzeigers zu einem anderen Datensatz springen. Daf&uuml;r sorgt die folgende Ereignisprozedur:<\/p>\n<pre>    Private Sub txtCounter_AfterUpdate()\r\n        If flagCounter Then Exit Sub\r\n        On Error Resume Next\r\n        m_frm.Recordset.AbsolutePosition = _\r\n        CLng(txtCounter) - 1\r\n        End Sub<\/pre>\n<p><b>Speichern und R&uuml;ckg&auml;ngig-Funktionen <\/b><\/p>\n<pre>    aktivieren<\/pre>\n<p>Eine weitere implementierte Ereignisprozedur des Hauptformulars wird beim Bearbeiten eines Datensatzes ausgel&ouml;st. Sie sorgt daf&uuml;r, dass die Schaltfl&auml;chen zum Speichern und zum R&uuml;ckg&auml;ngigmachen von &Atilde;&#8220;nderungen aktiviert werden.<\/p>\n<pre>    Private Sub m_frm_Dirty(Cancel As Integer)\r\n        Me!btnStore.Enabled = True\r\n        Me!btnUndo.Enabled = True\r\n        End Sub<\/pre>\n<p><b>Sonstige Funktionen<\/b><\/p>\n<p>Die Navigationsleiste enth&auml;lt noch weitere interessante Funktionen, die wir aus Platzgr&uuml;nden leider nicht alle abdrucken k&ouml;nnen.<\/p>\n<p>Wichtig ist noch die Funktion <b>Redraw<\/b>, die f&uuml;r die Positionierung sowie f&uuml;r das Ein- und Ausblenden der Steuerelemente des Navigationsformulars verantwortlich ist und die vor allem beim Laden des Formulars aufgerufen wird.<\/p>\n<p>Die Funktion <b>AdjustColor<\/b> sorgt daf&uuml;r, dass die Hintergrundfarbe des Unterformulars mit der des Hauptformulars &uuml;bereinstimmt.<\/p>\n<p>Nicht nur f&uuml;r die Optik sind die Prozeduren, die durch die Ereigniseigenschaft <b>Bei Mausbewegung <\/b>aller Schaltfl&auml;chen der Navigationsleiste ausgel&ouml;st werden: Sie sorgen daf&uuml;r, dass die jeweils &uuml;berstrichene Schaltfl&auml;che den Fokus erh&auml;lt.<\/p>\n<p>Ohne dieses Feature w&auml;ren n&auml;mlich unter Umst&auml;nden zwei Klicks notwendig, wenn Sie sich in einem Feld des Hauptformulars befinden: Einer setzt den Fokus auf das Navigationsunterformular und erst danach l&ouml;st ein Klick auf eine Schaltfl&auml;che das <b>Click<\/b>-Ereignis aus.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Das <b>aiuNavigationsleiste<\/b>-Formular l&auml;sst sich leicht in eigene Anwendungen integrieren &#8211; einfach mitsamt dem dazugeh&ouml;renden Modul in die Datenbank kopieren und wie oben beschrieben konfigurieren.<\/p>\n<p>Die Vorteile stehen in einem guten Verh&auml;ltnis zum Aufwand: das individuelles Design der Schaltfl&auml;chen, das Positionieren der Navigationsleiste an beliebiger Stelle, das Abfangen von Ereignissen und die zus&auml;tzlichen Schaltfl&auml;chen sprechen f&uuml;r sich.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Navigationsleiste.zip<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/71682F1E-F3F6-4F5C-AC3D-4D7FD518F15F\/aiu_580.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die Navigationsschaltfl&auml;che ist so zweckm&auml;&szlig;ig, dass sie von Access-Entwicklern vermutlich oft kaum noch wahrgenommen wird: Soll der Benutzer zwischen den Datens&auml;tzen bl&auml;ttern oder soll er nicht Dementsprechend schaltet man die Eigenschaft Navigationsschaltfl&auml;chen anzeigen entweder an oder aus. Manchmal passt die eingebaute Variante aber auch einfach nicht: Beispielsweise, wenn die Anordnung von Haupt- und Unterformular eine eher verwirrende Anzeige der Navigationsschaltfl&auml;chen bewirkt oder wenn die Navigationsleiste einfach einmal ganz anders aussehen soll. <\/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":[66022008,662008,44000027,44000023],"tags":[],"class_list":["post-55000580","post","type-post","status-publish","format-standard","hentry","category-66022008","category-662008","category-Loesungen","category-Mit_Formularen_arbeiten"],"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>Navigationsleiste im Eigenbau - 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\/Navigationsleiste_im_Eigenbau\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Navigationsleiste im Eigenbau\" \/>\n<meta property=\"og:description\" content=\"Die Navigationsschaltfl&auml;che ist so zweckm&auml;&szlig;ig, dass sie von Access-Entwicklern vermutlich oft kaum noch wahrgenommen wird: Soll der Benutzer zwischen den Datens&auml;tzen bl&auml;ttern oder soll er nicht Dementsprechend schaltet man die Eigenschaft Navigationsschaltfl&auml;chen anzeigen entweder an oder aus. Manchmal passt die eingebaute Variante aber auch einfach nicht: Beispielsweise, wenn die Anordnung von Haupt- und Unterformular eine eher verwirrende Anzeige der Navigationsschaltfl&auml;chen bewirkt oder wenn die Navigationsleiste einfach einmal ganz anders aussehen soll.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2021-02-11T21:20:13+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg04.met.vgwort.de\/na\/af442c5614644f4a80c67b6f089ac717\" \/>\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=\"24\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Navigationsleiste im Eigenbau\",\"datePublished\":\"2021-02-11T21:20:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/\"},\"wordCount\":3900,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg04.met.vgwort.de\\\/na\\\/af442c5614644f4a80c67b6f089ac717\",\"articleSection\":[\"2\\\/2008\",\"2008\",\"L\u00f6sungen\",\"Mit Formularen arbeiten\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/\",\"name\":\"Navigationsleiste im Eigenbau - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg04.met.vgwort.de\\\/na\\\/af442c5614644f4a80c67b6f089ac717\",\"datePublished\":\"2021-02-11T21:20:13+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg04.met.vgwort.de\\\/na\\\/af442c5614644f4a80c67b6f089ac717\",\"contentUrl\":\"http:\\\/\\\/vg04.met.vgwort.de\\\/na\\\/af442c5614644f4a80c67b6f089ac717\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Navigationsleiste_im_Eigenbau\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Navigationsleiste im Eigenbau\"}]},{\"@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":"Navigationsleiste im Eigenbau - 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\/Navigationsleiste_im_Eigenbau\/","og_locale":"de_DE","og_type":"article","og_title":"Navigationsleiste im Eigenbau","og_description":"Die Navigationsschaltfl&auml;che ist so zweckm&auml;&szlig;ig, dass sie von Access-Entwicklern vermutlich oft kaum noch wahrgenommen wird: Soll der Benutzer zwischen den Datens&auml;tzen bl&auml;ttern oder soll er nicht Dementsprechend schaltet man die Eigenschaft Navigationsschaltfl&auml;chen anzeigen entweder an oder aus. Manchmal passt die eingebaute Variante aber auch einfach nicht: Beispielsweise, wenn die Anordnung von Haupt- und Unterformular eine eher verwirrende Anzeige der Navigationsschaltfl&auml;chen bewirkt oder wenn die Navigationsleiste einfach einmal ganz anders aussehen soll.","og_url":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/","og_site_name":"Access im Unternehmen","article_published_time":"2021-02-11T21:20:13+00:00","og_image":[{"url":"http:\/\/vg04.met.vgwort.de\/na\/af442c5614644f4a80c67b6f089ac717","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"24\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Navigationsleiste im Eigenbau","datePublished":"2021-02-11T21:20:13+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/"},"wordCount":3900,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/#primaryimage"},"thumbnailUrl":"http:\/\/vg04.met.vgwort.de\/na\/af442c5614644f4a80c67b6f089ac717","articleSection":["2\/2008","2008","L\u00f6sungen","Mit Formularen arbeiten"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/","url":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/","name":"Navigationsleiste im Eigenbau - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/#primaryimage"},"thumbnailUrl":"http:\/\/vg04.met.vgwort.de\/na\/af442c5614644f4a80c67b6f089ac717","datePublished":"2021-02-11T21:20:13+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/#primaryimage","url":"http:\/\/vg04.met.vgwort.de\/na\/af442c5614644f4a80c67b6f089ac717","contentUrl":"http:\/\/vg04.met.vgwort.de\/na\/af442c5614644f4a80c67b6f089ac717"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Navigationsleiste_im_Eigenbau\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Navigationsleiste im Eigenbau"}]},{"@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\/55000580","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=55000580"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000580\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000580"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000580"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000580"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}