Tipps und Tricks 1/2009

Es sind die kleinen Kniffe, die uns den Alltag beim Programmieren von Access-Anwendungen erleichtern. In dieser Ausgabe von Access im Unternehmen zeigen wir Ihnen zum Beispiel, wie Sie den Datensatzwechsel in Formularen steuern, bei Problemen mit DoCmd.OpenForms reagieren oder einen kompletten Datensatz im Endlosformular markieren.

Dateneingabe ohne Datensatzwechsel

Wenn Sie Detaildaten wie etwa einen Kunden, einen Artikel oder ähnliches eingeben, verwenden Sie in der Regel ein entsprechendes Formular, das nur zur Eingabe dieser Daten dient.

Beim Aufruf dieses Formulars geben Sie mit dem Parameter DataMode in der folgenden Anweisung direkt an, dass nun ein neuer Datensatz eingegeben werden soll:

DoCmd.OpenForm "Formularname", DataMode:=acFormAdd

Damit weiß das Formular, dass es direkt einen neuen, leeren Datensatz anzeigen und alle anderen Datensätze der Datenherkunft ausblenden soll.

Wenn Sie die Eigenschaften Trennlinie, Navigationsbereich und Datensatzmarkierer auf Nein einstellen, befreien Sie das Formular überdies von unnötigem Schnickschnack, den man beim Anlegen eines einfachen Datensatzes nicht braucht.

Der Benutzer kann hiermit keinen Unsinn mehr anstellen – es sei denn, er springt mit der Eingabe- oder Tabulator-Taste bis zum letzten Steuerelement in der Aktivierreihenfolge und darüber hinaus, dann gelangt er nämlich in einen neuen Datensatz.

Das können Sie allerdings leicht unterbinden: Stellen Sie dazu einfach die Eigenschaft Zyklus des Formulars auf den Wert Aktueller Datensatz ein. Der Fokus wechselt dann vom letzten Steuerelement der Aktivierreihenfolge zum ersten Steuerelement des Formulars.

DoCmd.OpenForm-Argumente funktionieren nicht

Während der Entwicklung von Formularen treten manchmal nicht nachvollziehbare Probleme auf.

So kann es zum Beispiel vorkommen, dass Sie ein Formular mit einer Anweisung wie der folgenden aufrufen, aber das mit dem Parameter OpenArgs übergebene Öffnungsargument einfach nicht beim Formular ankommt:

DoCmd.OpenForm "Formularname", OpenArgs:="Test"

Im Ereignis Beim Öffnen des Formulars möchten Sie das Öffnungsargument nun so auslesen:

Dim strOeffnungsargument As String
strOeffnungsargument = Me.OpenArgs

Es gibt jedoch die Fehlermeldung Laufzeitfehler 94: Unzulässige Verwendung von Null, OpenArgs ist also scheinbar leer.

Der durch das fehlende Öffnungsargument verursachte Fehler tritt immer dann auf, wenn das Formular bereits geöffnet ist – egal, ob sichtbar oder unsichtbar. Wenn Ihnen dies passiert, ist das Formular also beispielsweise hinter einem anderen Formular versteckt oder Sie haben es unsichtbar geschaltet.

Das geschieht gern, wenn Sie das Formular als modalen Dialog öffnen, um den aufrufenden Code anzuhalten, bis das Formular den Fokus verliert, um dann Elemente des Formulars auszulesen. Sie belegen dann etwa die OK-Schaltfläche des Formulars mit folgendem Code:

Me.Visible = False

Wenn Sie dann im aufrufenden Code vergessen, das Formular mit einer Anweisung wie der folgenden endgültig zu schließen, bleibt es im unsichtbaren Zustand geöffnet:

DoCmd.Close acForm, "frmTest"

Das Öffnungsargument ist allerdings nicht der einzige Parameter, der an bereits geöffnete Formulare nicht übergeben wird – auch die anderen Parameter wie WhereCondition, WindowMode, DataMode oder Filter funktionieren nicht.

Wenn Sie dieses Problem verhindern möchten, schließen Sie einfach immer alle geöffneten Formulare ordnungsgemäß – vor allem die unsichtbar geschalteten. Das Wichtigste ist jedoch, dass Sie das hier beschriebene Verhalten richtig einschätzen, was spätestens nach der Lektüre dieses Tipps kein Problem mehr sein sollte.

Kompletten Datensatz im Datenblatt markieren

Manchmal möchte man ein Datenblatt nicht zur Dateneingabe, sondern einfach nur zum Anzeigen und gegebenenfalls zum Auswählen von Daten verwenden. Damit der Benutzer keine Daten darin ändern kann, stellen Sie einfach die Eigenschaft Recordsettyp auf Snapshot ein – schon ist das Anfügen, ändern und Löschen der Daten nicht mehr möglich.

Das ist aber auch nur die technisch notwendige Seite der Medaille. Damit der Benutzer sich nicht verschaukelt fühlt, weil er zwar die Einfügemarke in die Felder setzen, aber keine Inhalte ändern kann, unterbinden Sie auch das.

Sie könnten dazu einfach die Eigenschaften Aktiviert und Gesperrt des Steuerelements auf Nein und Ja einstellen. Damit kann der Benutzer nicht mehr den Fokus auf die Steuerelemente setzen, aber leider kann er so auch den kompletten Datensatz nicht mehr einfach per Mausklick markieren.

Aktiviert und Gesperrt sind also die falschen Eigenschaften. Wir markieren den Datensatz einfach so, wie es auch durch einen Mausklick auf den Datensatzmarkierter am linken Rand geschehen würde – und dazu verwenden Sie die folgende Anweisung:

Application.RunCommand acCmdSelectRecord

Aber wann Der Datensatz soll schließlich bei einem Mausklick irgendwo in der Zeile markiert werden, was normalerweise das Anlegen entsprechender Beim Klicken-Ereignisprozeduren für alle angezeigten Steuerelemente beziehungsweise Felder erforderlich machen würde.

Das macht bei Formularen mit vielen Feldern aber keinen Spaß und deshalb lösen wir diese Anweisung einfach beim Ereignis Beim Anzeigen aus, das bei jedem Wechseln des Datensatzes angestoßen wird.

Wählen Sie dazu im Eigenschaftsfenster das Element Formular aus, tragen Sie für die Eigenschaft Beim Anzeigen den Wert [Ereignisprozedur] ein und klicken Sie auf die nun erscheinende Schaltfläche neben der Eigenschaft. Die dann im VBA-Editor angelegte Routine ergänzen Sie wie folgt:

Private Sub Form_Current()
    Application.RunCommand acCmdSelectRecord
    End Sub

Damit markiert das Formular direkt beim Anzeigen den ersten Datensatz und erledigt dies auch beim Wechseln des Datensatzes durch einen Mausklick auf einen anderen Datensatz.

Wenn Sie dieses Formular nun als Unterformular in einem anderen Formular einsetzen, was bei der Verwendung von Formularen in der Datenblattansicht üblich ist, wird der erste Datensatz beim Öffnen des Formulars nicht mehr komplett markiert – dies funktioniert nur noch beim Wechseln des Datensatzes.

Die Ereignisprozedur Form_Current des Unterformulars wird zwar beim Öffnen ausgelöst, aber offensichtlich sorgt der zwischenzeitliche Wechsel zum Hauptformular dafür, dass dieses den Fokus verliert und auch der erste Datensatz nicht mehr markiert ist.

Uns ist nur eine Möglichkeit bekannt, auch beim Öffnen des Formulars direkt den ersten Datensatz des Unterformulars komplett zu markieren – und zwar durch das Setzen des Timers des Hauptformulars auf ein kurzes Zeitintervall wie 1 und Hinzufügen der folgenden Routine, die durch die Ereigniseigenschaft Bei Zeitgeber ausgelöst wird:

Private Sub Form_Timer()
    Me!sfm.SetFocus
    Me!sfm.Form.Vorname.SetFocus
    Application.RunCommand acCmdSelectRecord
    Me.TimerInterval = 0
    End Sub

Durch das Einstellen der Eigenschaft TimerInterval auf den Wert 0 sorgen Sie dafür, dass Access die Routine nicht erneut auslöst.

Eine Optimierung gibt es noch. Dabei verwenden Sie statt der SetFocus– und RunCommand-Methode die folgende Variante, die den Zugriff stark vereinfacht:

With Me
.SelTop = Me.Recordset.AbsolutePosition + 1
.SelLeft = 1
.SelWidth = 3
.SelHeight = 1
End With

Einen kleinen Haken hat diese Routine noch: Wenn das Unterformular keine Datensätze enthält, löst das Setzen des Fokus auf ein Feld des Datensatzes (hier Vorname) einen Fehler aus. Daher fügen Sie noch die folgende Abfrage hinzu:

Private Sub Form_Timer()
    Me!sfm.SetFocus
    If Me!sfm.Form.Recordset.RecordCount > 0 Then
        Me!sfm.Form.Vorname.SetFocus
        Application.RunCommand acCmdSelectRecord
    End If
    Me.TimerInterval = 0
    End Sub

Migration nach Access 2007

Wer professionelle Datenbanken entwickelt, verwendet auch eine oder mehrere benutzerdefinierte Menüleisten darin.

Wenn man eine solche Datenbank nach Access 2007 migriert, zeigt Access diese Menüleiste im Ribbon in einem eigenen Tab namens Add-Ins an (siehe Bild 1).

pic007.tif

Bild 1: Menüleisten-Überbleibsel einer MDB in Access 2007

Spätestens wenn Sie die Elemente der Menü- und gegebenenfalls auch der Symbolleisten als Ribbon nachgebaut haben, werden Sie die Menü- und Symbolleisten aus der Datenbank werfen.

Das geht am einfachsten, indem Sie zunächst einmal prüfen, welches die Kandidaten für den Rauswurf sind, und diese mit der folgenden Routine im Direktfenster ausgeben lassen:

Public Sub CommandbarsLoeschen()
Dim cbr As CommandBar
For Each cbr In CommandBars
 If Not cbr.BuiltIn Then
    Debug.Print cbr.Name
End If
Next cbr
End Sub

Danach können Sie die nicht mehr benötigten Elemente mit der folgenden Anweisung löschen:

CommandBars("<Menüleiste>").Delete

Warum so zimperlich und nicht alle nicht eingebauten Menü- und Symbolleisten direkt löschen

Nun: Es kann ja sein, dass die CommandBars-Auflistung nicht nur die Elemente der aktuellen Datenbank, sondern auch solche aus Bibliotheksdatenbanken oder aus Add-In-Datenbanken enthält, und die würden Sie dann mitlöschen.

Wenn Sie die Anwendung das nächste Mal starten, erscheint dann allerdings eine Fehlermeldung wie die aus Bild 2.

pic001.tif

Bild 2: Dieser Fehler erscheint, wenn eine noch referenzierte Symbolleiste nicht mehr vorhanden ist.

Die Ursache ist klar: Irgendwo muss noch ein Verweis auf die Menüleiste sein – vermutlich in den Access-Optionen für die aktuelle Datenbank.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar