Formulare generieren

Für Einsteiger sind die Formular-Assistenten von Access sicher eine hilfreiche Einrichtung. Fortgeschrittene Entwickler verwenden diese jedoch eher selten – sie haben eine individuell verschiedene Vorgehensweise, diese zu erstellen, mit Datenherkunft und Steuerelementen zu befüllen und Eigenschaften und Ereignisse festzulegen. Wenn man aber immer wieder ähnliche Formulare benötigt, ist das ständige Neuerstellen vergeudete Zeit: Per Copy and Paste oder auch mit ein paar Zeilen Code gelingt dies doch deutlich schneller.

Die schnellste Möglichkeit, ein Formular zu erstellen, dass man bereits in ganz ähnlicher Weise produziert hat, ist das Kopieren dieses Formulars – zumindest, wenn es sich in der gleichen Datenbank befindet. Sollten Sie es für eine andere Anwendung erstellt haben, können Sie es über die Import-Funktion von Access ebenfalls schnell hinzufügen.

Es gibt aber noch eine Alternative: Warum programmieren Sie sich nicht eine kleine Funktion, die Ihnen immer wiederkehrende Schritte beim Erstellen von Formularen abnimmt In diesem Beitrag stellen wir Ihnen die notwendigen Grundlagen für das Erstellen von Formularen und Steuerelementen samt Eigenschaften vor.

Ein anderer Grund für das dynamische Erstellen eines Formulars wäre ein Unterformular, dessen Felder erst zur Laufzeit bekannt sind. Ein gutes Beispiel dafür ist die Lösung zum Beitrag Seriendruck mit Access und Word (www.access-im-unternehmen.de/). Hier können wir zwar direkt eine Tabelle oder Abfrage als Datenherkunft zuweisen (unter VBA etwa mit dem Ausdruck Me.sfm.SourceObject = "Table.tblBeispiel" beziehungsweise "Tabelle.tblBeispiel" in älteren Access-Versionen). Wenn das Unterformular aber auch noch die für ein Formular üblichen Ereignisse bereitstellen soll, um etwa auf änderungen der enthaltenen Daten reagieren zu können, ist das Erstellen eines Formulars zur Laufzeit eine Alternative.

Das Anlegen von Ereignisprozeduren für zur Laufzeit erstellte Formulare demonstrieren wir in einem späteren Beitrag.

Formulare erstellen

Das reine Erstellen eines Formulars geht ganz einfach von der Hand und kann gleich im Direktfenster des VBA-Editors geschehen: Die Application-Methode CreateForm erzeugt im Handumdrehen ein Formular, ganz so als ob Sie es über den entsprechenden Menüeintrag erledigt hätten.

Unter Access 2003 oder unter der Dokumentfensteroption namens Überlappende Fenster unter Access 2007 erscheint das Formular allerdings lediglich in Form seiner Titelleiste, was dem Modus Minimiert entspricht. Das lässt sich allerdings leicht mit folgender Anweisung ändern:

DoCmd.Restore

Anschließend können wir das Formular nach Bedarf speichern. Dies gelingt nur unter Angabe des Formularnamens, der allerdings beim Aufruf der CreateForm-Methode dynamisch erzeugt wird (in der deutschen Version nacheinander Formular1, Formular2, …).

Um wirklich das richtige Formular zu speichern, speichern wir gleich beim Anlegen einen Verweis auf das neue Formular in einer Objektvariablen namens frm. Dies alles geschieht bereits in einer kleinen Prozedur, die wir anschließend Schritt für Schritt erweitern:

Public Sub FormularErstellen()
Dim frm As Form
Set frm = CreateForm
DoCmd.Restore
DoCmd.Save acForm, frm.Name
End Sub

Wenn Sie das so gespeicherte Formular umbenennen möchten, verwenden Sie die Anweisung DoCmd.Rename. Diese setzt allerdings voraus, dass das zu ändernde Formular geschlossen ist.Wenn das Formular geschlossen ist, haben wir aber keinen Zugriff mehr auf die Objektvariable frm, um den aktuellen Namen zu ermitteln. Also speichern wir diesen zuvor in der Variablen strForm zwischen, schließen das Formular und benennen es erst dann um:

Dim frm As Form
Dim strFormTemp As String
Set frm = CreateForm
strFormTemp = frm.Name
DoCmd.Restore
DoCmd.Save acForm, strFormTemp
DoCmd.Close acForm, strFormTemp
DoCmd.Rename "frmBeispiel", acForm, strFormTemp

Das Ergebnis dieser acht Zeilen ist ein neues Formular mit dem gewünschten Namen. Um die Prozedur dynamischer zu gestalten, übergeben Sie den gewünschten Namen (hier noch frmBeispiel) mit einem Parameter:

Public Sub FormularErstellen(strFormname As String)
...
DoCmd.Rename strFormName, acForm, strFormTemp
End Sub

Steuerelemente zum Formular hinzufügen

Steuerelemente fügen Sie einem Formular in der Entwurfsansicht mit der CreateControl-Methode des Application-Objekts hinzu.

Diese erwartet die folgenden Parameter:

  • Formname: Name des Formulars, in dem das Steuerelement erstellt werden soll
  • ControlType: Konstante, die den Steuerelementtyp angibt, beispielsweise acTextBox, acComboBox oder acCheckBox
  • Section: Bereich des Formulars, in dem das Steuerelement angelegt werden soll, beispielsweise acDetail für den Detailbereich
  • Parent: Übergeordnetes Steuerelement. Eigentlich nur wichtig, wenn man ein Bezeichnungsfeld an ein anderes Steuerelement wie etwa ein Textfeld binden will (optional).
  • Column: Name des Feldes der Datenherkunft, an welches das Steuerelement gebunden werden soll (optional)
  • Left: Abstand vom linken Formularrand in Twips (optional)
  • Top: Abstand vom oberen Rand des Zielbereichs in Twips (optional)
  • Width: Breite in Twips (optional)
  • Height: Höhe in Twips (optional)

Wenn Sie ein Steuerelement mit der CreateControl-Methode anlegen, können Sie einen Verweis darauf in einer entsprechenden Variablen speichern:

Dim ctl As Control
Set ctl = Application.CreateControl("frmTest", acTextBox, acDetail, ...)

Der Hintergrund ist, dass Sie so noch weitere Einstellungen vornehmen können – etwa um bei Kombinationsfeldern die Nachschlagefeld-Eigenschaften aus der Felddefinition auszulesen und abzubilden.

Formular mit Daten füllen und in der Datenblattansicht anzeigen

Manche Entwickler arbeiten in Unterformularen sehr viel mit der Datenblattansicht. Sie zeigt die Daten übersichtlich an, ermöglicht das Bearbeiten und auch das Sortieren oder Filtern.

Bauen wir also eine Prozedur, die ein mit der vorherigen Prozedur erstelltes Formular so umwandelt, dass es die gewünschte Datenherkunft erhält und die Felder der Datenherkunft anzeigt.

Diese Prozedur verwendet zwei Parameter: den Namen des Formulars und den Namen der zu verwendenden Datenherkunft beziehungsweise den entsprechenden SQL-Ausdruck. Vor dem Aufruf dieser Funktion sollten Sie bereits ein leeres Formular mit der Prozedur FormularErstellen erzeugt haben.

Die folgenden Zeilen sorgen außerdem dafür, dass ein eventuell bereits bestehendes Formular gelöscht und die richtigen Parameter übergeben werden:

Dim strFormname As String
Dim strRecordsource As String
strFormname = "frmBeispiel"
strRecordsource = "SELECT * FROM tblAdressen"
On Error Resume Next
DoCmd.DeleteObject acForm, strFormname
On Error GoTo 0
FormularErstellen strFormname
DatenblattEinrichten strFormname, strRecordsource

Die Prozedur DatenblattEinrichten öffnet das mit dem Parameter strFormname benannte Formular in der Entwurfsansicht und füllt die Objektvariable frm mit einem Verweis darauf, um später komfortabel auf seine Eigenschaften zugreifen zu können (s. Listing 1).

Listing 1: Füllen eines leeren Formulars mit den Steuerelementen für die Anzeige der Datenblattansicht

Public Sub DatenblattEinrichten(strFormname As String, strRecordsource As String)
    ''...Deklaration
    DoCmd.OpenForm strFormname, acDesign
    Set frm = Forms(strFormname)
    Set db = CurrentDb
    Set rst = db.OpenRecordset(strRecordsource, dbOpenDynaset)
    For Each fld In rst.Fields
         intControlType = acTextBox
        On Error Resume Next
        intControlType = fld.Properties("DisplayControl")
        On Error GoTo 0
        Set ctl = Application.CreateControl(strFormname, intControlType, acDetail)
        ctl.ControlSource = fld.SourceField
        Select Case intControlType
            Case acComboBox
                Set cbo = ctl
                With cbo
                    .RowSource = fld.Properties("RowSource")
                    .ColumnCount = fld.Properties("ColumnCount")
                    .ColumnWidths = fld.Properties("ColumnWidths")
                End With
        End Select
        Set lbl = Application.CreateControl(strFormname, acLabel, acDetail, ctl.Name)
        lbl.Caption = fld.Name
        On Error Resume Next
        lbl.Caption = fld.Properties("Caption")
        On Error GoTo 0
    Next fld
    frm.RecordSource = strRecordsource
    frm.DefaultView = acDefViewDatasheet
    DoCmd.Close acForm, frm.Name, acSaveYes
End Sub

Danach wird ein Recordset-Objekt mit den Datensätzen der mit dem Parameter strRecordsource angegebenen Tabelle oder Abfrage gefüllt. Dieses benötigen wir, um die Felder der Datenherkunft zu durchlaufen und die entsprechenden Steuerelemente im Formular anzulegen.

Man könnte die Felder zwar auch über ein TableDef– beziehungsweise ein QueryDef-Objekt auslesen, aber dazu müsste man noch prüfen, ob es sich bei dem in strRecordsource angegebenen Objekt um eine Tabelle oder Abfrage handelt.

Dies sparen wir uns aus Bequemlichkeit und weil wir wissen, dass das Erstellen von Formularen wohl nicht zur Laufzeit geschehen wird und somit nicht wichtig für die Performance ist (TableDef und QueryDef enthalten nur die Definition, Recordset enthält auch Daten und könnte ein wenig mehr Zeit zum Füllen beanspruchen).

Beim Durchlaufen der einzelnen Felder der Datenherkunft über die Fields-Auflistung geschehen folgende Schritte:

  • Ein Tabellenfeld kann unter anderem als Textfeld, als Kombinationsfeld oder als Kontrollkästchen angezeigt werden. Die Variable intControlType speichert den Typ, wobei diese zuerst mit dem Standardwert acTextBox gefüllt wird. Wenn das Feld nicht als Textfeld angezeigt wird, enthält die als Property gespeicherte Eigenschaft DisplayControl die Konstante für das entsprechende Steuerelement, beispielsweise acComboBox oder acCheckBox. Dieser Wert landet dann gegebenenfalls statt acTextBox in der Variablen intControlType.
  • Die CreateControl-Methode erzeugt im Detailbereich des angegebenen Formulars ein Steuerelement des soeben ermittelten Typs und speichert einen Verweis darauf in der Variablen ctl.
  • Die Eigenschaft ControlSource (im Eigenschaftsfenster Steuerelementinhalt) erhält als Wert den Inhalt der Eigenschaft SourceField des Field-Objekts.
  • Anschließend untersucht ein Select Case-Konstrukt, ob es sich bei dem Steuerelement um ein Kombinationsfeld handelt, und stellt weitere Eigenschaften auf die im Originalfeld voreingestellten Werte ein. Dabei handelt es sich um die Datensatzherkunft (RowSource), die Spaltenanzahl (ColumnCount) und die Spaltenbreiten (ColumnWidths).
  • Schließlich wird ein passendes Bezeichnungsfeld für jedes Steuerelement erzeugt. Dieses erhält als Beschriftung zunächst den Namen des Feldes. Falls der Entwickler mit der Eigenschaft Beschriftung eine alternative Beschriftung hinterlegt hat, besitzt das Feld eine Property namens Caption. Ist diese vorhanden, wird das Bezeichnungsfeld damit betitelt.
  • Schließlich wird die Datenherkunft des Formulars auf den mit strRecordsource übergebenen Ausdruck und die Standardansicht auf Datenblatt eingestellt.
  • Im letzten Schritt wird das Formular geschlossen und gespeichert.

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

TestzugangOder bist Du bereits Abonnent? Dann logge Dich gleich hier ein. Die Zugangsdaten findest Du entweder in der aktuellen Print-Ausgabe auf Seite U2 oder beim Online-Abo in der E-Mail, die Du als Abonnent regelmäßig erhältst:

Schreibe einen Kommentar