Home > Artikel > Ausgabe 4/2015 > Navigieren über Formulartricks

Navigieren über Formulartricks

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

Die Voreinstellungen, die Access für ein neues Formular im Entwurf anbietet, sind für die üblichen Standardmasken in Anwendungen sicher sinnvoll. Durch Modifikation dieser Einstellungen bieten Formulare aber noch ganz andere Möglichkeiten – so etwa zu Navigationszwecken, wie in der hier vorgestellten Lösung.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1504_Formulartricks.accdb

Formulareinstellungen

Erzeugen Sie ein neues leeres Formular in Ihrer Datenbank, so versieht Access es mit Standardeinstellungen für das Layout und Format. Unter Access 2010 sind diese im Eigenschaftenblatt des Entwurfs zu finden (Bild 1). Da es einige Mühe macht, diese Einstellungen jeweils neu anzupassen, finden Sie sie so auch in vielen Datenbanken wieder. Nehmen wir aber einmal einige der wichtigsten Elemente genauer unter die Lupe.

Diese Einstellungen für das Layout spendiert Access 2010 einem neuen Formular

Bild 1: Diese Einstellungen für das Layout spendiert Access 2010 einem neuen Formular

Grundsätzlich ist die Standardansicht auf Einzelnes Formular gestellt. Das dürfte auch der am häufigsten gebrauchte Typ sein. Fraglich ist, ob die anderen Ansichtstypen wirklich zugelassen sein sollten. Wer braucht schon in einer Adressenverwaltung die Pivot-Ansichten? Erst recht gilt dies für die ab Access 2007 eingeführte Layoutansicht mit ihrer Mischung aus Entwurf und Formularansicht, die bis auf seltene Fälle eher der Entwicklungsphase vorbehalten sein dürfte. Die Endlosansicht jedoch wird immer wieder gebraucht.

Dass Automatisch zentrieren auf Nein steht, ist dem Standardverhalten von Fenstern in MDI-Anwendungen unter Windows geschuldet: Öffnen Sie mehrere Formulare gleichzeitig, so werden diese versetzt auf dem Arbeitsbereich positioniert, so dass auf alle zugegriffen werden kann. Selten sind Access-Formulare jedoch so klein, dass mehrere davon auf dem Bildschirm Platz hätten. Für größere Formulare stellen Sie die Zentrierung auf dem Bildschirm also auf Ja.

Datensatzmarkierer und Navigationsschaltflächen sind ebenfalls immer aktiviert. Während die Navigationsschaltflächen sicher nützlich sind, wenn das Formular nicht nur zur Eingabe oder Anzeige eines einzigen Datensatzes ausgelegt ist, so ist der Datensatzmarkierer in produktiven Anwendungen wieder fraglich. In der Formularansicht erkennen viele Anwender nicht, wofür er da ist, und eine Fehlbedienung durch versehentliches Betätigen der Entfernen-Taste bei markiertem Datensatz kommt immer wieder vor. In Formularen, wie dem Switchboard der Beispieldatenbank zum Beitrag, sind alle beide überflüssig.

Dass ein Formular eine Schließen-Schaltfläche aufweist, ist immer dann erforderlich, wenn Sie es nicht per VBA entladen möchten. MinMaxSchaltflächen hingegen braucht man in der Regel nicht. Formulare sind üblicherweise auf eine bestimmte Größe designet, so dass ein Maximieren keinen Vorteil bringt. Damit wären wir auch schon bei der Einstellung für die Rahmenart, die im Standard auf Veränderbar steht. Sie können es dann zur Laufzeit mit der Maus in der Größe ändern. In der Formularansicht ist auch das nicht notwendig. Eher verwenden Sie hier die Einstellungen Dialog oder Dünn, die zum gleichen Ergebnis führen: Die Titelleiste des Fensters ist sichtbar – und damit auch die Schließen-Schaltfläche –, die Abmessungen lassen sich aber nicht per Maus ändern. Schalten Sie den Modus Keine für die Rahmenart ein, so verschwindet die Titelleiste komplett. Das Formular kann dann nur per VBA geschlossen werden. Das Formular frmIntro der Beispieldatenbank, ein Splash-Screen, etwa macht davon Gebrauch. Erst ein Klick auf den Detailbereich des Formulars löst eine Ereignisprozedur aus, die das Formular über DoCmd.Close entlädt.

Interessant, aber wenig beachtet, ist die Eigenschaft Verschiebbar eines Formulars. Normalerweise können Sie es zur Laufzeit mit der Maus über die Titelleiste an die gewünschte Position ziehen. Ist Verschiebbar deaktiviert, so ist dies jedoch in keiner Ansichts- oder Rahmenart mehr möglich. Das Formular bleibt fest im Arbeitsbereich angepinnt. Dennoch können Sie es über VBA und die Methode Move bewegen, doch dazu später mehr.

Die Bildlaufleisten sind im Standard zwar eingeschaltet, aber in der Formularansicht bis auf Ausnahmefälle unnötig. Das wären Formulare, deren Inhalt so umfangreich ist, dass er nicht auf den Bildschirm passt und nur über Scrollen erreicht werden kann. Im Interesse von guter Ergonomie ist ein solches Verhalten weniger.

Ein Teil der Formulareinstellungen schließlich ist gar nicht im jeweiligen Eigenschaftenblatt zu finden, sondern in den Optionen der Datenbank. Klicken Sie im Ribbon auf Datei | Optionen und wählen die Abteilung Aktuelle Datenbank aus. Ein Ausschnitt der Einstellungen ist hier in Bild 2 zu sehen. Überlappende Fenster ist der übliche MDI-Modus, wie Sie ihn aus anderen Mehrfensteranwendungen kennen. Das Registerkartenformat jedoch führt zu einer Anordnung der Fenster mit Tabs. Die Einstellung Automatisch zentrieren eines Formulars etwa wird damit ignoriert, denn es bleibt immer oben am Arbeitsbereich angeheftet. Ebenso lässt sich hier auch die Layoutansicht deaktivieren, was der entsprechenden Eigenschaft Layoutansicht zulassen eines Formulars übergeordnet ist.

Formulareinstellungen in den Optionen der Datenbank

Bild 2: Formulareinstellungen in den Optionen der Datenbank

Nicht verschiebbare Fenster

Ist die Eigenschaft Verschiebbar eines Formulars auf Nein gesetzt, so bleibt es zur Laufzeit, wie erwähnt, an einer festen Position angenagelt. Selbst mit einer Titelleiste ausgestattet reagiert es nicht auf ein Ziehen mit der Maus. Das eröffnet die Möglichkeit, mehrere Formulare nach Belieben auf dem Arbeitsbereich zu positionieren, ohne dass sie sich überlappen oder der Anwender die Anordnung beeinflussen kann.

Wie aber bringt man ein Formular an die gewünschte Stelle? Dazu sieht VBA die recht einfache Methode Move vor, die übrigens nicht nur die Formularklassen, sondern auch alle Steuerelemente aufweisen:

Form1.Move Links, Oben, Breite, Höhe

Der Clou der Anweisung besteht darin, dass sämtliche Parameter optional sind. Um ein Fenster etwa 100 Pixel vom linken Rand des Arbeitsbereichs unterzubringen, setzten Sie einfach dies ab:

Form1.Move 100*15

Der Faktor 15 übersetzt hier die Pixelmaße in die Twips-Einheiten, welche Access immer erwartet. Soll das Formular oben bündig abschließen, so genügt ein

Form1.Move 100*15, 0

Und sollen Breite und Höhe zusätzlich vorgegeben werden, käme diese Anweisung infrage:

Form1.Move 1500, 0, 400*15, 300*15

Diese Methode können Sie etwa im Beim Laden-Ereignis (Form_Load) absetzen, aber auch an jeder anderen Stelle des Formular-Codes.

Versuchen wir mit diesem Wissen ein Switchboard zu realisieren, das dem Navigationsbereich von Access ähnelt.

Navigationsmenü per Formular

Das Formular frmNavi der Beispieldatenbank sieht zur Laufzeit aus, wie in Bild 3. Für das Format ist im Eigenschaftenblatt die Rahmenart Keine angegeben, Datensatzmarkierer und Navigationsschaltflächen wurden auf Nein gesetzt, und der Modus Verschiebbar ist deaktiviert. Damit das Formular links oben angeheftet bleibt, wird im Ereignis Beim Laden diese Code-Zeile ausgeführt:

Das Navigationsmenü der Beispieldatenbank

Bild 3: Das Navigationsmenü der Beispieldatenbank

Me.Move 0, 0, 1500

Das bewirkt, dass die Positionen für Links und Oben auf 0 eingestellt und die Breite auf 100 Pixel festgelegt werden. Die Höhe bleibt von der Anweisung unberührt, weil der vierte Parameter fehlt.

Die beschrifteten Schaltflächen sollen nicht fest im Formular angelegt sein, sondern sich aus den Daten einer Tabelle tblNavi (siehe Bild 4) speisen, damit sich das Menü über diese steuern lässt. Leider lässt Access das Anlegen von Steuerelementen zur Laufzeit nicht zu. Deshalb ist für die Standardansicht des Formulars nicht die Formularansicht ausgewählt, sondern die Endlosansicht.

Die Tabelle tblNavi mit den Werten zur Steuerung des Menüformulars

Bild 4: Die Tabelle tblNavi mit den Werten zur Steuerung des Menüformulars

Kommen wir zur Bedeutung der einzelnen Felder der Tabelle. Unter Caption wird angegeben, welche Beschriftung eine Schaltfläche des Menüs haben soll. Function ist eine Parameterangabe, die dem VBA-Code später mitteilt, welches Objekt beim Klick auf eine Schaltfläche geöffnet wird. Die vertikale Reihenfolge der Schaltflächen wird über den Zahlenwert unter Sort festgelegt, nach der über eine Abfrage die Datensätze sortiert werden. Type gibt an, welche Aufgabe ein Klick auf den Button ausführt. Dabei steht die 1 für Formular öffnen, die 2 für Bericht öffnen und 3 für das Auslösen einer selbst angelegten VBA-Prozedur. In Function findet sich dabei der Name des Formulars, Berichts oder der Funktion. Im Bool-Feld Ribbon aktiviert ein Häkchen, dass nach dem Klick der Ribbon von Access eingeblendet wird. Beim Starten der Anwendung wird dieser nämlich zunächst ausgeblendet. Schließlich können Sie dem Feld BackColor jeweils noch einen RGB-Wert spendieren, der die Hintergrundfarbe des Buttons nach dem Klick bestimmt. Den hier benötigten Long-Wert erhalten Sie etwa über das VBA-Direktfenster und die Anweisung

RGB( Rotanteil, Grün, Blau)

Diese Tabelle dient als Datenherkunft des Endlosformulars, wobei sie allerdings über eine Abfrage sortiert wird:

SELECT * FROM tblNavi ORDER BY Sort;

Der Formularentwurf

Nun kann eine Schaltfläche in Access nicht direkt an ein Datenfeld gebunden werden. Zwar könnten Sie per VBA im Ereignis Beim Anzeigen, die in einem Endlosformular für jeden Datensatz automatisch ausgelöst wird, die Caption-Eigenschaft der Schaltfläche aus der Datenherkunft setzen, doch dann würden alle Buttons hintereinander dieselbe Beschriftung erhalten, nämlich die des letzten Datensatzes – denn die einzelnen Instanzen des Buttons leiten sich alle von einem Objekt ab. Also scheidet dieses Verfahren aus. Greifen wir deshalb zu einem Trick, der vielleicht in der Entwurfsansicht in Bild 5 deutlich wird. Ganz oben ist der Formularkopf eingeblendet, der ein Bezeichnungsfeld enthält, das schlicht mit Navigation beschriftet ist. Rechts daneben befindet sich ebenfalls ein Bezeichnungsfeld LblTitle mit der gleichen Beschriftung, das aber zur Laufzeit unsichtbar ist. Auf dessen Bedeutung kommen wir noch zu sprechen.

Das Formular frmNavi in der Entwurfsansicht

Bild 5: Das Formular frmNavi in der Entwurfsansicht

Der Detailbereich, welcher sich in einem Endlosformular für jeden Datensatz wiederholt, ist mit einer Schaltfläche bestückt, deren Hintergrund scheinbar hellblau daherkommt. Tatsächlich aber – und das ist der Trick! – sieht man hier den Hintergrund eines Textfeldes, welches direkt hinter der Schaltfläche cmdFunction liegt und die gleichen Abmessungen aufweist. Die Hintergrundart der Schaltfläche selbst hingegen ist auf Transparent gestellt. Und dennoch reagiert sie auf einen Klick in den Hintergrund des Textfeldes.

Über das Textfeld ist die Möglichkeit der Datenbindung an das Feld Caption gegeben, so dass das Ganze zur Laufzeit so wirkt, als hätte man lediglich eine blaue Schaltfläche vor sich. Damit das Textfeld dann nicht etwa den Mauszeiger als Textcursor entgegennimmt, ist seine Eigenschaft Aktiviert auf Nein eingestellt.

Bedingte Formatierung

Bevor die Programmierung des Formulars erläutert wird, gehen wir noch auf ein Spezialverhalten der Schaltfläche ein. Beim Klick auf sie nimmt sie die Farbe an, die in der Tabelle für BackColor hinterlegt ist. Dabei kommt diese Funktionalität fast ohne VBA-Code aus, indem das Textfeld hinter der Schaltfläche mit einer Bedingten Formatierung ausgestattet wird. Markieren Sie dazu das Textfeld txtFunction und wechseln im Ribbon auf den Bereich Format | Steuerelementformatierung. Dort ist der Button Bedingte Formatierung aktiv. Klicken Sie ihn an, um den Dialog für die Festlegung der Bedingungen zu öffnen. In Bild 6 ist die entsprechende Bedingungszeile bereits hinterlegt. Entstanden ist Sie über das Hinzufügen einer Bedingung über die Schaltfläche Neue Regel, welche den Dialog in Bild 7 lädt. Die Berechnungsregel lautet hier im Prinzip so:

Dialog zur Bedingten Formatierung des Textfelds txtFunction

Bild 6: Dialog zur Bedingten Formatierung des Textfelds txtFunction

Eingabe der Berechnungsregel für die Bedingte Formatierung

Bild 7: Eingabe der Berechnungsregel für die Bedingte Formatierung

Feldwert = [LblTitle].Beschriftung

Das bedeutet im Klartext, dass die unter der Zeile eingestellte Formatierung, nämlich gelber Hintergrund, immer dann zur Geltung kommt, wenn der Wert des Datenfeldes Caption, das dem Textfeld ja zugrunde liegt, genau dem Wert für die Eigenschaft Beschriftung des Label-Steuerelements LblTitle entspricht. Und dieses befindet sich unsichtbar im Formularkopf.

Das mag ihnen spanisch vorkommen, denn das Label hat ja die feste Beschriftung Navigation. Und da es in der Tabelle keinen einzigen Eintrag gibt, der unter Caption diese Bezeichnung führt, dürfte die Bedingung ja nie zutreffen, was die gelbe Formatierung nie auslösen würde. Tatsächlich braucht es hier doch noch etwas VBA-Code, um der Sache auf die Sprünge zu helfen.

In Listing 1 steht die Prozedur für das Ereignis Beim Anzeigen des Formulars. Sie wird dann aufgerufen, wenn ein Datensatz des Formulars aktiviert wird, was etwa beim Klicken auf eine Schaltfläche des Detailbereichs passiert. In der ersten Zeile wird dann der Wert des Datenfeldes Caption dem versteckten Label LblTitle im Formularkopf zugewiesen. Und schon trifft die Regel für die Bedingte Formatierung zu! Und zwar nur für diese eine Schaltfläche beziehungsweise deren unterlegtes Textfeld. Denn alle anderen Textfelder des Endlosformulars haben ja einen anderen Wert für Caption eingetragen. Die Bedingte Formatierung tritt indessen nicht sofort in Kraft, sondern wird in der letzten Zeile über eine Requery des Textfelds aktiv.

Private Sub Form_Current()

     Me!LblTitle.Caption = Me!Caption.Value

     Me!txtFunction.FormatConditions(0).BackColor = Me!BackColor.Value

     Me!txtFunction.Requery

End Sub

Listing 1: Ereignisprozedur Beim Anzeigen des Formulars

Nun erschiene die Schaltfläche in leuchtendem Gelb. Da wir ihr jedoch die in der Tabelle durch BackColor angegebene Hintergrundfarbe verabreichen wollten, muss zuvor noch in der zweiten Zeile die Bedingte Formatierung per VBA geändert werden. Über FormatConditions(0) gelangen wir an die einzige Regel des Textfelds txtFunction. Ihre Eigenschaft BackColor wird mit dem gleichnamigen Wert aus der Tabelle versehen. Und damit wird das Gelb durch diese neue Farbe ersetzt, ohne dass die Regel selbst sich ändert.

Das Zusammenwirken von Bedingter Formatierung mit VBA ist hier sicher nicht so leicht nachzuvollziehen, zeigt aber anschaulich, was sich mit den Bordmitteln von Access ohne großen Programmieraufwand erreichen lässt.

Das Menü in Aktion – die Programmierung

Wie die Anwendung nach einem Klick auf die Schaltfläche Kundenbericht aussieht, zeigt Bild 8. Der Button ist hellgelb hinterlegt, was auch dem Wert in der Tabelle tblNavi für diesen Datensatz entspricht. Geöffnet hat sich ein Beispielbericht rptKunden, der genau den restlichen Raum des Arbeitsbereichs von Access einnimmt. Gehen wir Schritt für Schritt durch, was hier im Code des Navigationsformulars abläuft.

Beispiel für die Navigation

Bild 8: Beispiel für die Navigation

Beim Laden wird die Routine aus Listing 2 durchlaufen. Zunächst wird über die ShowToolbar-Methode der Ribbon von Access ausgeblendet. Wir wollen ihn schließlich durch unser Menü ersetzen. Im Folgenden wird per Move das rahmenlose Formular in die linke obere Ecke des Arbeitsbereichs verfrachtet und seine Breite auf 100 Pixel eingestellt. Weiter geht es mit einem Aufruf der Timer-Prozedur Form_Timer (Bei Zeitgeber) des Formulars, die in Listing 3 zu finden ist. Außerdem wird das Intervall des Timers auf 200 ms festgelegt. Am Ende wird auf die erste Menüschaltfläche cmdFunction noch der Fokus gesetzt. Übergangen haben wird bisher noch die Zuweisung der formularweit gültigen Variablen hwndMDI mit dem Resultat der Function GetMDIWindow, welche sich im Modul mdlFormulare der Datenbank aufhält. Sie ermittelt das Windows Fenster-Handle des MDI-Arbeitsbereichs von Access über eine Reihe von API-Funktionen, auf die hier nicht weiter eingegangen wird. Diese Handle wird in der Timer-Routine noch benötigt.

Private Sub Form_Timer()

     Dim frm As Access.Form

     Dim rpt As Access.Report

     If hwndMDI <> 0 Then

         GetWindowDims hwndMDI, HeightMDI, WidthMDI

         HeightMDI = HeightMDI - 60

         Me.Move 0, 0, 3300, HeightMDI

         For Each frm In Forms

             If frm.Name <> "frmNavi" Then

                 If (frm.WindowLeft <> 3330) Or _

                    (frm.WindowHeight <> HeightMDI) Then

                       frm.Move 3330, 0, WidthMDI - 3390, HeightMDI

                 End If

             End If

         Next frm

         For Each rpt In Reports

             If (rpt.WindowLeft <> 3330) Or _

                (rpt.WindowHeight <> HeightMDI) Then

                   rpt.Move 3330, 0, WidthMDI - 3390, HeightMDI

             End If

         Next rpt

     End If

     

     If Forms.Count = 1 And Reports.Count = 0 Then

         If CommandBars("Ribbon").Visible Then _

             DoCmd.ShowToolbar "Ribbon", acToolbarNo

         If Me!LblTitle.Caption <> " " Then

             Me!LblTitle.Caption = " "

             Me!txtFunction.Requery

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

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