Formulare per VBA erstellen

Warum sollte man Formulare per VBA erstellen, wenn Microsoft Access doch die gute alte, etwas in die Jahre gekommene Entwurfsansicht dafür bereitstellt Ganz einfach: Weil es für den effizient arbeitenden Access-Entwickler immer wieder Aufgaben gibt, die er einfach nicht von Hand erledigen möchte. Oder weil der Access-Entwickler immer wiederkehrende Aufgaben in ein Access-Add-In oder ein COM-Add-In auslagern möchte. Und dort gibt es nun einmal keine Entwurfsansicht – dort ist VBA-Code gefragt, um neue Formulare zu erstellen und die gewünschten Steuerelemente auf das Formular zu bringen. Dieser Beitrag liefert alle Techniken, die zum Erstellen von Formularen und zum Ausstatten mit Steuerelementen notwendig sind.

Neues, leeres Formular erstellen

Mit einer ersten Funktion wollen wir ein neues, leeres Formular mit einem vorher festgelegten Namen erstellen. Das erledigt die Funktion CreateNewForm. Diese erwartet als Parameter den Namen, den das Formular nach dem Erstellen erhalten soll:

Public Sub CreateNewForm(strName As String) 
     Dim frm As Form
     Dim strNameTemp As String
     Set frm = CreateForm()
     strNameTemp = frm.Name
     DoCmd.Close acForm, frm.Name, acSaveYes
     DoCmd.Rename strName, acForm, strNameTemp
End Sub

Die Prozedur deklariert Variablen für das neue Form-Element (frm) und für den temporären von Access beim Erstellen vergebenen Namen (strNameTemp). Dann erstellt es mit der CreateForm-Funktion ein neues Formular. CreateForm liefert einen Verweis auf das neu erstellte Form-Objekt zurück, welches wir mit der Variablen frm referenzieren. Wir würden nun gern den Namen des Formulars einstellen, aber das ist nicht ohne weiteres möglich: Die Eigenschaft Name des Form-Objekts ist nämlich schreibgeschützt. Wie also dem Formular den gewünschten Namen geben Klar: Wir könnten es einfach nach dem Speichern und Schließen umbenennen, dafür gibt es die DoCmd.Rename-Methode. Allerdings erwartet die auch den vorherigen Namen des Formulars, und den kennen wir nicht. Allerdings können wir diesen zuvor mit frm.Name auslesen und speichern ihn in der Variablen strNameTemp. Danach schließen wir dann das Formular mit der Methode DoCmd.Close und den Parametern acForm für den Objekttyp, frm.Name für den Namen des zu schließenden Objekts und acSaveYes, damit die Änderungen an dem neu erstellten Formular ohne Rückfrage gespeichert werden.

Nach dem Schließen rufen wir dann DoCmd.Rename auf und übergeben mit dem ersten Parameter den neuen Namen, mit dem zweiten den Objekttyp (acForm) und mit dem dritten den vorherigen Objektnamen.

Rufen wir diese Prozedur nun wie folgt auf, legt dies ein neues, leeres Formular unter dem angegebenen Namen an, das direkt im Navigationsbereich erscheint:

CreateNewForm "frmNeuesFormular"

Formular bereits vorhanden

Wenn man diese Prozedur zwei Mal hintereinander mit dem gleichen Formularnamen aufruft, erhält man die Meldung aus Bild 1. Diese wird durch den Versuch ausgelöst, dem neuen Formular den Namen eines bereits vorhandenen Formulars zu übergeben. Dem können wir bereits zuvor vorbeugen, indem wir abfragen, ob bereits ein Formular dieses Namens vorhanden ist. Ob ein Formular bereits vorhanden ist, können wir auf verschiedene Arten prüfen. Wir könnten zum Beispiel versuchen, es zu öffnen, oder wir durchlaufen eine der Auflistungen der Formulare.

Meldung beim Versuch, einem Formular einen bereits vorhandenen Namen zu geben

Bild 1: Meldung beim Versuch, einem Formular einen bereits vorhandenen Namen zu geben

Wir wählen letztere Variante. Die Funktion heißt ExistsForm und erwartet den Formularnamen als Parameter. Sie liefert das Ergebnis als Booleanwert zurück. Hier deklarieren wir für die Formulare eine Variable des Typs AccessObject. Warum nun AccessObject und nicht Form wie oben in der Prozedur CreateNewForm Weil die dort verwendete Funktion CreateForm ein Objekt des Typs Form erstellt, die Auflistung CurrentProject.AllForms, die wir durchsuchen wollen, jedoch Elemente des Typs AccessObjects liefert.

Mit objForm durchlaufen wir in einer For Each-Schleife alle Elemente der Auflistung CurrentProject.AllForms und prüfen, ob das aktuell mit objForm referenzierte Formular den mit strForm übergebenen Namen hat. Falls ja, stellen wir den Funktionswert auf True ein und verlassen die Funktion. Wenn die Funktion alle Elemente aus CurrentProject.AllForms durchläuft, ohne dass das passende Formular gefunden wird, liefert sie den Rückgabewert False (also den Standardwert für Rückgabewerte des Datentyps Boolean):

Public Function ExistsForm(strForm As String) As Boolean
     Dim objForm As AccessObject
     For Each objForm In CurrentProject.AllForms
         If objForm.Name = strForm Then
             ExistsForm = True
             Exit Function
         End If
     Next objForm
End Function

Formular neu erstellen

Wenn das Formular bereits existiert, können wir den Benutzer fragen, ob das vorhandene Formular überschrieben werden soll. Ist das der Fall, löschen wir das Formular und erstellen es neu. Dazu erweitern wir die Prozedur CreateNewForm wie in Listing 1. Hier fügen wir direkt hinter der Deklaration der Variablen einen Aufruf der Funktion ExistsForm ein.

Public Function CreateNewForm(strName As String) As Boolean
     Dim frm As Form
     Dim strNameTemp As String
     If ExistsForm(strName) Then
         If MsgBox("Formular ''" & strName & "'' ist bereits vorhanden. Überschreiben", vbYesNo + vbExclamation, _
                 "Formular überschreiben") = vbYes Then
             If DeleteForm(strName) = False Then
                 Exit Function
             End If
         Else
             Exit Function
         End If
     End If
     Set frm = CreateForm()
     strNameTemp = frm.Name
     frm.Visible = True
     DoCmd.Close acForm, frm.Name, acSaveYes
     DoCmd.Rename strName, acForm, strNameTemp
     CreateNewForm = True
End Function

Listing 1: Erstellen eines neuen Formulars

Liefert diese den Wert True, dann zeigen wir ein Meldungsfenster an, das den Benutzer fragt, ob er das Formular überschreiben möchte. Falls ja, rufen wir eine Funktion namens DeleteForm auf (siehe weiter unten) und übergeben den Namen des zu löschenden Formulars. Diese könnte fehlschlagen, weil beispielsweise das zu löschende Formular gerade geöffnet ist. In diesem Fall soll die Prozedur einfach verlassen werden – die passende Fehlermeldung soll die Funktion DeleteForm liefern. Wenn der Benutzer die Frage, ob das vorhandene Formular gelöscht werden soll, mit Nein antwortet, soll die Prozedur auch verlassen werden.

Nur wenn das Formular noch nicht existiert oder gelöscht werden konnte, werden die anschließenden Schritte zum Erstellen des neuen Formulars ausgeführt.

Löschen eines vorhandenen Formulars

Wenn das Formular bereits vorhanden ist und der Benutzer es überschreiben möchte, müssen wir es löschen. Dazu haben wir die Funktion DeleteForm definiert, die den Namen des zu löschenden Formulars entgegennimmt und einen Boolean-Wert zurückliefert.

Die Funktion probiert bei deaktivierter eingebauter Fehlerbehandlung aus, ob das Formular mit DoCmd.DeleteObject gelöscht werden kann. Falls ja, erhält die Funktion den Rückgabewert True. Anderenfalls gibt die Funktion die entsprechende Fehlermeldung aus Err.Description aus und gibt den Standardwert False als Funktionsergebnis an die aufrufende Prozedur zurück:

Public Function DeleteForm(strName As String) As Boolean
     On Error Resume Next
     DoCmd.DeleteObject acForm, strName
     If Err.Number = 0 Then
         DeleteForm = True
     Else
         MsgBox Err.Description, vbCritical + vbOKOnly, _
             "Löschen fehlgeschlagen"
     End If
End Function

Damit haben wir bereits eine Funktion zum Erstellen eines neuen Formulars, das allerdings noch komplett leer ist und für das wir auch noch keine Eigenschaften eingestellt haben.

Formular weiterverarbeiten

Nun stehen zwei Aufgaben an: Die erste ist das Einstellen verschiedener Eigenschaften für das Formular. Die zweite ist das Erstellen von Steuerelementen im Formular. Letzteres beschreibt der Beitrag Steuerelemente erstellen (www.access-im-unternehmen.de/1336). Um die Eigenschaften kümmern wir uns jetzt gleich.

Um Eigenschaften einstellen zu können, benötigen wir einen Verweis auf das Formular in der Entwurfsansicht. Das heißt also, dass wir das Formular auch öffnen müssen. Da stellt sich die Frage: Könnten wir mit der Funktion CreateNewForm nicht direkt einen Verweis auf das neu erstellte und in der Formularansicht geöffnete Formular zurückgeben Das könnten wir tun, wir müssten dazu das Formular allerdings auch in dieser Funktion wieder öffnen.

Das Schließen ist dort unbedingt nötig, da wir es sonst nicht umbenennen können. Da wir nicht wissen, ob und wie das Formular nach dem Erstellen direkt weiterverarbeitet werden soll, geben wir einfach nur einen Boolean-Wert zurück, der angibt, ob das Formular erfolgreich erstellt wurde.

Eigenschaften des Formulars einstellen

In der Prozedur, welche die Funktion CreateNewForm aufgerufen hat, können wir nun das Formular in der Entwurfsansicht öffnen und die gewünschten Änderungen vornehmen.

Wie bereits erwähnt, wollen wir uns in diesem Beitrag zunächst um das Einstellen der verschiedenen Eigenschaften des Formulars kümmern und schauen uns diese dabei im Detail an. Das Öffnen gestalten wir wie folgt:

Public Sub Test_CreateNewForm()
     Dim frm As Form
     Dim strForm As String
     strForm = "frmNeuesFormular"
     If CreateNewForm(strForm) = True Then
         DoCmd.OpenForm strForm, acDesign
         Set frm = Forms(strForm)
         With frm
             ''Eigenschaften einstellen
         End With
     End If
End Sub

Hier schreiben wir den Namen des zu erstellenden Formulars direkt in eine Variable, weil wir diesen mehr als einmal benötigen und anschließende Änderungen so nur an einer Stelle erfolgen müssen. Dann erstellen wir das neue Formular mit der Funktion CreateNewForm.

Ist dies erfolgreich, öffnen wir das neu erstellte Formular mit DoCmd.OpenForm in der Entwurfsansicht. Dazu stellen wir den zweiten Parameter View auf acDesign ein.

Damit wir danach komfortabel die Eigenschaften des Formulars einstellen können, referenzieren wir das Formular dann über die Forms-Auflistung und den Namen des Formulars mit der Form-Variablen frm. Für frm stellen wir dann die nachfolgend beschriebenen Eigenschaften ein.

Einstellungen für die Titelleiste

Die Titelleiste des Formulars (siehe Bild 2) verwendet gleich mehrere Eigenschaften.

Elemente der Titelleiste eines Formulars

Bild 2: Elemente der Titelleiste eines Formulars

  • Die Titelleiste des Formulars stellen wir mit der Eigenschaft Caption ein.
  • Ob das Formular das gleiche Icon anzeigen soll wie die Hauptanwendung, legen Sie übrigens nicht mit einer Formular-Eigenschaft fest, sondern in den Access-Optionen mit der Option Als Formular- und Berichtssymbol verwenden. Dies gilt dann für alle Formulare und Berichte.
  • Ob die Schließen-Schaltfläche aktiviert ist, stellen sie mit der Eigenschaft CloseButton ein. Legen Sie den Wert auf False fest, wird die Schaltfläche ausgegraut dargestellt und der Benutzer kann sie nicht betätigen.
  • Die Schaltflächen in der Titelleiste zum Minimieren und Maximieren des Fensters können Sie über die Benutzeroberfläche mit der Eigenschaft MinMaxSchaltflächen einstellen, über VBA mit MinMaxButtons. Die möglichen Werte sind: 0 (Keine), 1 (Min vorhanden), 2 (Max vorhanden) oder 3 (Beide vorhanden).
  • Die Eigenschaft Mit Systemfeldmenü (ControlBox) stellt ein, ob überhaupt Steuerelemente in der Titelleiste angezeigt werden sollen. Falls nicht, sieht die Titelleiste wie in Bild 3 aus.
  • Titelleiste nur mit Überschrift

    Bild 3: Titelleiste nur mit Überschrift

Abmessungen

Die Abmessungen des Formulars wie die Höhe und die Breite stellen Sie mit Eigenschaften für verschiedene Elemente ein. Die Breite ist eine Formular-Eigenschaft, diese entspricht der VBA-Eigenschaft Width. Eine Eigenschaft namens Höhe beziehungsweise Height vermissen wir allerdings im Eigenschaftenblatt. Der Grund ist einfach: Ein Formular kann mehrere Bereiche enthalten, die jeweils eine eigene Höhe haben – zum Beispiel der Detailbereich oder Formularkopf und -Fuß. Die Einstellungen dieser Bereiche besprechen wir weiter unten.

Standardansicht

Die Standardansicht stellt die Eigenschaft DefaultView ein. Diese nimmt die Werte der Enumeration acDefView entgegen:

  • acDefViewContinuous (1): Endlosformular
  • acDefViewDatasheet (2): Datenblatt
  • acDefViewSingle (0): Einzelnes Formular
  • acDefViewSplitForm (5): Geteiltes Formular

Sie haben das Ende des frei verfügbaren Textes erreicht. Möchten Sie ...

TestzugangOder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar