Im Beitrag “Formulare per VBA erstellen” (www.access-im-unternehmen.de/1332) haben wir gezeigt, wie Sie per VBA ein neues, leeres Formular erstellen und seine Eigenschaften einstellen. Darauf wollen wir in diesem Beitrag aufbauen und zeigen, wie Sie dem Formular per VBA die gewünschten Steuerelemente hinzufügen können. Und auch Steuerelemente haben eine Menge Eigenschaften, die wir nach dem Anlegen einstellen müssen – Position, Aussehen und auch wieder Ereigniseigenschaften. Nach der Lektüre des vorliegenden Beitrags haben Sie alle Werkzeuge, die Sie brauchen, um beispielsweise Access-Add-Ins zu nutzen, um einer Anwendung neue Formulare und Steuerelemente hinzuzufügen.
Vorbereitung: Formular anlegen
Als Vorbereitung wollen wir mit den Techniken, die wir im oben genannten Beitrag zum Erstellen von Formularen gelernt haben, zunächst ein neues Formular erzeugen. Dazu verwenden wir eine Funktion, die weitere Funktionen aus dem oben genannten Beitrag nutzt.
Die folgende Funktion erwartet den Namen des zu erstellenden Formulars und übergibt diesen an eine weitere Funktion namens CreateNewForm. Liefert diese den Wert True zurück, wurde das Formular erfolgreich erstellt.
Dann öffnen wir dieses Formular in der Formularansicht und stellen noch die Anzeige von Kopf- und Fußbereich ein – diese Bereiche werden wir weiter unten nämlich auch mit Steuerelementen versehen. Schließlich gibt die Funktion einen Verweis auf das noch in der Entwurfsansicht geöffnete Form-Objekt zurück:
Public Function GetNewForm(strForm As String) As Form Dim frm As Form If CreateNewForm(strForm) = True Then DoCmd.OpenForm strForm, acDesign Set frm = Forms(strForm) With frm RunCommand acCmdFormHdrFtr .Section(acHeader).Visible = True .Section(acFooter).Visible = True End With End If Set GetNewForm = frm End Function
Steuerelemente anlegen per VBA
Diese Funktion rufen wir von der folgenden Prozedur aus auf und referenzieren das erstellte und geöffnete Formular mit der Variablen frm:
Public Sub SteuerelementeAnlegen() Dim frm As Form Set frm = GetNewForm("frmMitSteuerelementen") ''Steuerelemente anlegen End Sub
Danach können wir bereits loslegen, indem wir die gewünschten Anweisungen an Stelle des Kommentars ”Steuerelemente anlegen einfügen! Die minimale Version der Methode CreateControl hat nur zwei Parameter – den Namen des Formulars und den Typ des Steuerelements, hier acTextBox für ein Textfeld:
CreateControl frm.Name, acTextBox
Dieser Befehl legt bereits ein einfaches Steuerelement an, wobei die Position links oben im Detailbereich des Formulars ist.
Wichtig ist, dass Sie genau wie über die Benutzeroberfläche nur Steuerelemente anlegen können, wenn das Formular in der Entwurfsansicht geöffnet ist.
Die Methode CreateControl
Die Methode CreateControl, eigentlich ein Teil des Application-Objekts, aber auch ohne dessen Angabe aufrufbar, hat noch weitere Parameter. Nur die ersten beiden Parameter FormName und ControlType sind Pflichtparameter:
- FormName: Name des Formulars, in dem das Steuerelement angelegt werden soll
- ControlType: Typ des Steuerelements, der durch eine Konstante angegeben wird – zum Beispiel acTextBox, acLabel oder acCommandButton.
- Section: Bereich, in dem das Steuerelement angelegt werden soll. Sinnvolle Werte für das Anlegen von Steuerelementen in Formularen sind acDetail, acHeader und acFooter. Die übrigen Möglichkeiten, die per IntelliSense angezeigt werden, sind für Berichte gedacht.
- Parent: Verweis auf das übergeordnete Steuerelement. Hiermit können Sie beispielsweise festlegen, zu welchem Textfeld ein Bezeichnungsfeld gehört.
- ColumnName: Angabe eines Feldes der Datensatzquelle des Formulars, an welches das Steuerelement gebunden werden soll. Füllt die Eigenschaft Steuerelementinhalt und mehr – siehe weiter unten.
- Left: Position vom linken Rand des Formulars
- Top: Position vom oberen Rand des Formulars
- Width: Breite des Steuerelements
- Height: Höhe des Steuerelements
Textfeld mit Bezeichnungsfeld anlegen
Um ein Textfeld mit einem Bezeichnungsfeld zu erstellen, benötigen Sie zwei Aufrufe der CreateControl-Methode. Mit dem ersten erstellen Sie das Textfeld, mit dem zweiten das Bezeichnungsfeld.
Für das Bezeichnungsfeld stellen wir den Parameter Parent auf das Textfeld ein. Auf diese Weise werden die beiden Steuerelemente so verknüpft, wie es auch beim Anlegen von Textfeldern über den Entwurf geschieht oder wenn Sie Felder aus der Feldliste in den Entwurf ziehen.
Für ein einfaches Textfeld mit einem Bezeichnungsfeld benötigen Sie die folgenden Anweisungen. Die Variablen txt und lbl dienen zum Referenzieren der neu erstellten Steuerelemente. Das Textfeld erstellen wir im Formular mit dem Namen, den wir mit frm.Name für das mit frm wie oben referenzierte Formular abfragen, als acTextBox im Bereich acDetail. Außerdem legen wir die Position mit 1400 Twips vom linken und 100 Twips vom oberen Rand und die Größe mit einer Breite von 2000 Twips und einer Höhe von 300 Twips fest:
Dim txt As TextBox Dim lbl As Label Set txt = CreateControl(frm.Name, acTextBox, acDetail, , , 1400, 100, 2000, 300)
Danach erstellen wir das Bezeichnungsfeld ebenfalls in frm.Name als acLabel im Bereich acDetail. Es soll dem zuvor erstellten Textfeld untergeordnet werden, also geben wir für den Parameter Parent den Namen des Textfeldes an (mit txt.Name). txt.Name funktioniert immer, auch wenn wir den Namen des Textfeldes nicht explizit festgelegt haben und liefert für das erste Textfeld im Formular beispielsweise den Wert Text0.
Die Position und die Abmessungen definieren wir so, dass das Bezeichnungsfeld links vom Textfeld erscheint. Anschließend legen wir noch die Beschriftung fest, indem wir die Eigenschaft Caption für das zuvor definierte und mit der Variablen lbl referenzierte Bezeichnungsfeld auf den Wert Textfeld: festlegen:
Set lbl = CreateControl(frm.Name, acLabel, acDetail, txt.Name, , 100, 100, 1200, 300)
lbl.Caption = "Textfeld:"
Indem Sie das Bezeichnungsfeld mit dem Parent-Parameter an das Textfeld binden, sorgen Sie gleichzeitig dafür, dass die Eigenschaft Bezeichnungsname des Textfeldes auf den Namen des Bezeichnungsfeldes eingestellt wird.
Das Ergebnis finden Sie in Bild 1 (siehe Prozedur FormularMitTextfeldUndBezeichnungsfeld).
Bild 1: Textfeld mit Bezeichnungsfeld
Gebundene Textfelder anlegen
Nun gehen wir einen Schritt weiter und wollen zwei gebundenen Textfelder anlegen. Dazu stellen wir als Erstes die Eigenschaft Recordsource (Datensatzquelle) des Formulars auf die Tabelle tblArtikel ein:
frm.RecordSource = "tblArtikel"
Danach erstellen wir nacheinander zwei Textfelder mit Bezeichnungsfeldern, wobei wir im Gegensatz zum vorherigen Beispiel nun den Parameter ColumnName nutzen, um das Feld anzugeben, an welches das jeweilige Textfeld gebunden werden soll:
Dim txt As TextBox Dim lbl As Label Set txt = CreateControl(frm.Name, acTextBox, acDetail, , "ArtikelID", 1500, 100, 2000, 300) Set lbl = CreateControl(frm.Name, acLabel, acDetail, txt.Name, , 100, 100, 1300, 300) lbl.Caption = "ArtikelID:" Set txt = CreateControl(frm.Name, acTextBox, acDetail, , "Artikelname", 1500, 500, 2000, 300) Set lbl = CreateControl(frm.Name, acLabel, acDetail, txt.Name, , 100, 500, 1300, 300) lbl.Caption = "Artikelname:"
Das so erstellte Formular sieht in der Formularansicht wie in Bild 2 aus (siehe Prozedur GebundeneTextfelder).
Bild 2: Formular mit gebundenen Textfeldern
Gebundene Kombinationsfelder anlegen
Wenn wir die Tabelle tblArtikel betrachten, finden wir als Nächstes zwei Nachschlagefelder.
Diese wollen wir nun in Form von Kombinationsfeldern zum Formular hinzufügen. Für das erste Nachschlagefeld namens KategorieID sieht der dazu nötige Code wie folgt aus:
Dim cbo As ComboBox ... Set cbo = CreateControl(frm.Name, acComboBox, acDetail, , "KategorieID", 1500, 900, 2000, 300) Set lbl = CreateControl(frm.Name, acLabel, acDetail, cbo.Name, , 100, 900, 1300, 300) lbl.Caption = "KategorieID:"
Wie wir in Bild 3 sehen, brauchen wir nur das zugrunde liegende Nachschlagefeld der Tabelle mit dem Parameter Column-Name anzugeben, damit ein neues Kombinationsfeld mit allen in der Tabelle für dieses Feld festgelegten Eigenschaften erstellt wird (siehe Prozedur GebundeneKombinationsfelder).
Bild 3: Formular mit gebundenem Kombinationsfeld
Übernahme von Eigenschaften bei gebundenen Steuerelementen
Wenn Sie mit dem Parameter ColumnName ein Feld der zugrunde liegenden Datensatzquelle angeben, stellt dies nicht nur die Eigenschaft Steuerelementinhalt auf den Namen des zu bindenden Feldes ein. Dazu gehören Eigenschaften wie Textformat, Eingabeformat, Standardwert, Gültigkeitsregel oder Gültigkeitsmeldung. Bei Kombinationsfeldern auf Basis von Nachschlagefeldern werden, wir oben gezeigt, sogar die Eigenschaften des Nachschlagefeldes übernommen.
Detailformular erstellen
Ein oft erledigter Schritt ist das Erstellen eines Detailformulars, also ein Formular, das die Daten einer Tabelle oder Abfrage anzeigen soll. Dazu sind normalerweise einige Schritte nötig wie das Erstellen des Formulars, das Hinzufügen der Datensatzquelle, das Hineinziehen der Felder in den Formularentwurf und gegebenenfalls noch das Anordnen der Felder, weil Access beim Hineinziehen von Feldern aus der Feldliste beispielsweise Kontrollkästchen immer links vom Bezeichnungsfeld anordnet und die übrigen Steuerelemente immer rechts vom Bezeichnungsfeld.
Deshalb zeigen wir im Folgenden eine praktische Anwendung der Techniken, die Sie weiter oben gelernt haben.
Die Prozedur DetailformularErstellen erwartet drei Parameter:
- strForm: Name des zu erstellenden Formulars
- strRecordsource: Name der Datensatzquelle
- lngCaptionWidth: Breite der Bezeichnungsfelder mit einem Standardwert von 1500 Twips
Die Prozedur, deren Code Sie in Listing 1 finden, schließt zunächst eine gegebenenfalls noch geöffnete Instanz des Formulars mit dem in strForm übergebenen Namen. Dann erstellt sie dieses mit der Funktion GetNewForm unter dem angegebenen Namen neu und referenziert das neu erstellte und in der Entwurfsansicht geöffnete Formular mit der Variablen frm.
Public Sub DetailformularErstellen(strForm As String, strRecordsource As String, Optional lngCaptionWidth As Long = 1500) Dim frm As Form Dim db As DAO.Database Dim rst As DAO.Recordset Dim fld As DAO.Field Dim strDisplayControl As String Dim strCaption As String Dim txt As TextBox Dim lbl As Label Dim cbo As ComboBox Dim chk As CheckBox Dim lngTop As Long DoCmd.Close acForm, strForm Set frm = GetNewForm(strForm) frm.RecordSource = strRecordsource Set db = CurrentDb Set rst = db.OpenRecordset(strRecordsource) For Each fld In rst.Fields strDisplayControl = 0 strCaption = "" On Error Resume Next intDisplayControl = fld.Properties("DisplayControl") strCaption = fld.Properties("Caption") On Error GoTo 0 If Len(strCaption) = 0 Then strCaption = fld.Name End If Select Case intDisplayControl Case acCheckBox Set chk = CreateControl(frm.Name, acCheckBox, acDetail, , fld.Name, lngCaptionWidth + 200, lngTop + 100) chk.Name = "chk" & fld.Name Set lbl = CreateControl(frm.Name, acLabel, acDetail, chk.Name, , 100, lngTop + 100, lngCaptionWidth, 300) Case acComboBox Set cbo = CreateControl(frm.Name, acComboBox, acDetail, , fld.Name, lngCaptionWidth + 200, _ lngTop + 100, 2000, 300) cbo.Name = "cbo" & fld.Name Set lbl = CreateControl(frm.Name, acLabel, acDetail, cbo.Name, , 100, lngTop + 100, lngCaptionWidth, 300) Case Else Set txt = CreateControl(frm.Name, acTextBox, acDetail, , fld.Name, lngCaptionWidth + 200, _ lngTop + 100, 2000, 300) txt.Name = "txt" & fld.Name Set lbl = CreateControl(frm.Name, acLabel, acDetail, txt.Name, , 100, lngTop + 100, lngCaptionWidth, 300) End Select lbl.Caption = strCaption lngTop = lngTop + 400 Next fld End Sub
Listing 1: Prozedur zum Erstellen eines Detailformulars
Die einzige Formulareigenschaft, welche die Prozedur einstellt, ist RecordSource. Sie erhält den Wert aus strRecordsource.
Danach referenziert die Prozedur mit db das aktuelle Database-Objekt und mit rst ein Recordset auf Basis der mit strRecordsource übergebenen Datensatzquelle, bei der es sich um eine Tabelle, Abfrage oder auch einen SQL-Ausdruck handeln kann. Anschließend durchläuft sie in einer For Each-Schleife alle Felder der Fields-Auflistung des Recordsets.
In dieser Schleife stellt die Prozedur zunächst die beiden Variablen intDisplayControl und strCaption auf die Werte 0 beziehungsweise eine leere Zeichenkette ein. intDisplayControl soll später den Steuerelementtyp aufnehmen, der für die Anzeige des Feldes in der Datenblattansicht definiert wurde. Dieser Steuerelementtyp wird beim Entwerfen einer Tabelle automatisch von Access vorgegeben – bei Feldern des Datentyps Kurzer Text zum Beispiel Textfeld, bei Nachschlagefeldern Kombinationsfeld oder bei Ja/Nein-Feldern Kontrollkästchen.
Bei reinen Zahlenfeldern wird kein Steuerelement voreingestellt. Bild 4 zeigt, wo Sie die Eigenschaft DisplayControl beziehungsweise Steuerelement anzeigen im Entwurf der Tabelle einsehen können. DisplayControl liefert Werte einer Enumeration wie acTextBox, acComboBox oder acCheckBox.