{"id":55000709,"date":"2010-04-01T00:00:00","date_gmt":"2020-05-22T22:11:33","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=709"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Formulare_generieren","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/","title":{"rendered":"Formulare generieren"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg01.met.vgwort.de\/na\/d64c68c63c114048a674b186610ac43c\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>F&uuml;r Einsteiger sind die Formular-Assistenten von Access sicher eine hilfreiche Einrichtung. Fortgeschrittene Entwickler verwenden diese jedoch eher selten &#8211; sie haben eine individuell verschiedene Vorgehensweise, diese zu erstellen, mit Datenherkunft und Steuerelementen zu bef&uuml;llen und Eigenschaften und Ereignisse festzulegen. Wenn man aber immer wieder &auml;hnliche Formulare ben&ouml;tigt, ist das st&auml;ndige Neuerstellen vergeudete Zeit: Per Copy and Paste oder auch mit ein paar Zeilen Code gelingt dies doch deutlich schneller.<\/b><\/p>\n<p>Die schnellste M&ouml;glichkeit, ein Formular zu erstellen, dass man bereits in ganz &auml;hnlicher Weise produziert hat, ist das Kopieren dieses Formulars &#8211; zumindest, wenn es sich in der gleichen Datenbank befindet. Sollten Sie es f&uuml;r eine andere Anwendung erstellt haben, k&ouml;nnen Sie es &uuml;ber die Import-Funktion von Access ebenfalls schnell hinzuf&uuml;gen.<\/p>\n<p>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&uuml;r das Erstellen von Formularen und Steuerelementen samt Eigenschaften vor.<\/p>\n<p>Ein anderer Grund f&uuml;r das dynamische Erstellen eines Formulars w&auml;re ein Unterformular, dessen Felder erst zur Laufzeit bekannt sind. Ein gutes Beispiel daf&uuml;r ist die L&ouml;sung zum Beitrag <b>Seriendruck mit Access und Word <\/b>(<b>www.access-im-unternehmen.de\/<\/b>). Hier k&ouml;nnen wir zwar direkt eine Tabelle oder Abfrage als Datenherkunft zuweisen (unter VBA etwa mit dem Ausdruck <b>Me.sfm.SourceObject = &quot;Table.tblBeispiel&quot; <\/b>beziehungsweise <b>&quot;Tabelle.tblBeispiel&quot; <\/b>in &auml;lteren Access-Versionen). Wenn das Unterformular aber auch noch die f&uuml;r ein Formular &uuml;blichen Ereignisse bereitstellen soll, um etwa auf &auml;nderungen der enthaltenen Daten reagieren zu k&ouml;nnen, ist das Erstellen eines Formulars zur Laufzeit eine Alternative.<\/p>\n<p>Das Anlegen von Ereignisprozeduren f&uuml;r zur Laufzeit erstellte Formulare demonstrieren wir in einem sp&auml;teren Beitrag.<\/p>\n<p><b>Formulare erstellen<\/b><\/p>\n<p>Das reine Erstellen eines Formulars geht ganz einfach von der Hand und kann gleich im Direktfenster des VBA-Editors geschehen: Die <b>Application<\/b>-Methode <b>CreateForm <\/b>erzeugt im Handumdrehen ein Formular, ganz so als ob Sie es &uuml;ber den entsprechenden Men&uuml;eintrag erledigt h&auml;tten.<\/p>\n<p>Unter Access 2003 oder unter der <b>Dokumentfensteroption <\/b>namens <b>&Uuml;berlappende Fenster <\/b>unter Access 2007 erscheint das Formular allerdings lediglich in Form seiner Titelleiste, was dem Modus <b>Minimiert<\/b> entspricht. Das l&auml;sst sich allerdings leicht mit folgender Anweisung &auml;ndern:<\/p>\n<pre>DoCmd.Restore<\/pre>\n<p>Anschlie&szlig;end k&ouml;nnen wir das Formular nach Bedarf speichern. Dies gelingt nur unter Angabe des Formularnamens, der allerdings beim Aufruf der <b>CreateForm<\/b>-Methode dynamisch erzeugt wird (in der deutschen Version nacheinander <b>Formular1<\/b>, <b>Formular2<\/b>, &#8230;).<\/p>\n<p>Um wirklich das richtige Formular zu speichern, speichern wir gleich beim Anlegen einen Verweis auf das neue Formular in einer Objektvariablen namens <b>frm<\/b>. Dies alles geschieht bereits in einer kleinen Prozedur, die wir anschlie&szlig;end Schritt f&uuml;r Schritt erweitern:<\/p>\n<pre>Public Sub FormularErstellen()\r\nDim frm As Form\r\nSet frm = CreateForm\r\nDoCmd.Restore\r\nDoCmd.Save acForm, frm.Name\r\nEnd Sub<\/pre>\n<p>Wenn Sie das so gespeicherte Formular umbenennen m&ouml;chten, verwenden Sie die Anweisung <b>DoCmd.Rename<\/b>. Diese setzt allerdings voraus, dass das zu &auml;ndernde Formular geschlossen ist.Wenn das Formular geschlossen ist, haben wir aber keinen Zugriff mehr auf die Objektvariable <b>frm<\/b>, um den aktuellen Namen zu ermitteln. Also speichern wir diesen zuvor in der Variablen <b>strForm <\/b>zwischen, schlie&szlig;en das Formular und benennen es erst dann um:<\/p>\n<pre>Dim frm As Form\r\nDim strFormTemp As String\r\nSet frm = CreateForm\r\nstrFormTemp = frm.Name\r\nDoCmd.Restore\r\nDoCmd.Save acForm, strFormTemp\r\nDoCmd.Close acForm, strFormTemp\r\nDoCmd.Rename &quot;frmBeispiel&quot;, acForm, strFormTemp<\/pre>\n<p>Das Ergebnis dieser acht Zeilen ist ein neues Formular mit dem gew&uuml;nschten Namen. Um die Prozedur dynamischer zu gestalten, &uuml;bergeben Sie den gew&uuml;nschten Namen (hier noch <b>frmBeispiel<\/b>) mit einem Parameter:<\/p>\n<pre>Public Sub FormularErstellen(strFormname As String)\r\n...\r\nDoCmd.Rename strFormName, acForm, strFormTemp\r\nEnd Sub<\/pre>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Steuerelemente zum Formular hinzuf&uuml;gen<\/p>\n<p>Steuerelemente f&uuml;gen Sie einem Formular in der Entwurfsansicht mit der <b>CreateControl<\/b>-Methode des <b>Application<\/b>-Objekts hinzu.<\/p>\n<p>Diese erwartet die folgenden Parameter:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>Formname<\/b>: Name des Formulars, in dem das Steuerelement erstellt werden soll<\/li>\n<li class=\"aufz-hlung\"><b>ControlType<\/b>: Konstante, die den Steuerelementtyp angibt, beispielsweise <b>acTextBox<\/b>, <b>acComboBox <\/b>oder <b>acCheckBox<\/b><\/li>\n<li class=\"aufz-hlung\"><b>Section<\/b>: Bereich des Formulars, in dem das Steuerelement angelegt werden soll, beispielsweise <b>acDetail<\/b> f&uuml;r den Detailbereich<\/li>\n<li class=\"aufz-hlung\"><b>Parent<\/b>: &Uuml;bergeordnetes Steuerelement. Eigentlich nur wichtig, wenn man ein Bezeichnungsfeld an ein anderes Steuerelement wie etwa ein Textfeld binden will (optional).<\/li>\n<li class=\"aufz-hlung\"><b>Column<\/b>: Name des Feldes der Datenherkunft, an welches das Steuerelement gebunden werden soll (optional)<\/li>\n<li class=\"aufz-hlung\"><b>Left<\/b>: Abstand vom linken Formularrand in Twips (optional)<\/li>\n<li class=\"aufz-hlung\"><b>Top<\/b>: Abstand vom oberen Rand des Zielbereichs in Twips (optional)<\/li>\n<li class=\"aufz-hlung\"><b>Width<\/b>: Breite in Twips (optional)<\/li>\n<li class=\"aufz-hlung\"><b>Height<\/b>: H&ouml;he in Twips (optional)<\/li>\n<\/ul>\n<p>Wenn Sie ein Steuerelement mit der <b>CreateControl<\/b>-Methode anlegen, k&ouml;nnen Sie einen Verweis darauf in einer entsprechenden Variablen speichern:<\/p>\n<pre>Dim ctl As Control\r\nSet ctl = Application.CreateControl(&quot;frmTest&quot;, acTextBox, acDetail, ...)<\/pre>\n<p>Der Hintergrund ist, dass Sie so noch weitere Einstellungen vornehmen k&ouml;nnen &#8211; etwa um bei Kombinationsfeldern die <b>Nachschlagefeld<\/b>-Eigenschaften aus der Felddefinition auszulesen und abzubilden.<\/p>\n<p><b>Formular mit Daten f&uuml;llen und in der Datenblattansicht anzeigen<\/b><\/p>\n<p>Manche Entwickler arbeiten in Unterformularen sehr viel mit der Datenblattansicht. Sie zeigt die Daten &uuml;bersichtlich an, erm&ouml;glicht das Bearbeiten und auch das Sortieren oder Filtern.<\/p>\n<p>Bauen wir also eine Prozedur, die ein mit der vorherigen Prozedur erstelltes Formular so umwandelt, dass es die gew&uuml;nschte Datenherkunft erh&auml;lt und die Felder der Datenherkunft anzeigt.<\/p>\n<p>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 <b>FormularErstellen<\/b> erzeugt haben.<\/p>\n<p>Die folgenden Zeilen sorgen au&szlig;erdem daf&uuml;r, dass ein eventuell bereits bestehendes Formular gel&ouml;scht und die richtigen Parameter &uuml;bergeben werden:<\/p>\n<pre>Dim strFormname As String\r\nDim strRecordsource As String\r\nstrFormname = &quot;frmBeispiel&quot;\r\nstrRecordsource = &quot;SELECT * FROM tblAdressen&quot;\r\nOn Error Resume Next\r\nDoCmd.DeleteObject acForm, strFormname\r\nOn Error GoTo 0\r\nFormularErstellen strFormname\r\nDatenblattEinrichten strFormname, strRecordsource<\/pre>\n<p>Die Prozedur <b>DatenblattEinrichten <\/b>&ouml;ffnet das mit dem Parameter <b>strFormname <\/b>benannte Formular in der Entwurfsansicht und f&uuml;llt die Objektvariable <b>frm <\/b>mit einem Verweis darauf, um sp&auml;ter komfortabel auf seine Eigenschaften zugreifen zu k&ouml;nnen (s. Listing 1).<\/p>\n<p class=\"kastentabelleheader\">Listing 1: F&uuml;llen eines leeren Formulars mit den Steuerelementen f&uuml;r die Anzeige der Datenblattansicht<\/p>\n<pre>Public Sub DatenblattEinrichten(strFormname As String, strRecordsource As String)\r\n    ''...Deklaration\r\n    DoCmd.OpenForm strFormname, acDesign\r\n    Set frm = Forms(strFormname)\r\n    Set db = CurrentDb\r\n    Set rst = db.OpenRecordset(strRecordsource, dbOpenDynaset)\r\n    For Each fld In rst.Fields\r\n         intControlType = acTextBox\r\n        On Error Resume Next\r\n        intControlType = fld.Properties(&quot;DisplayControl&quot;)\r\n        On Error GoTo 0\r\n        Set ctl = Application.CreateControl(strFormname, intControlType, acDetail)\r\n        ctl.ControlSource = fld.SourceField\r\n        Select Case intControlType\r\n            Case acComboBox\r\n                Set cbo = ctl\r\n                With cbo\r\n                    .RowSource = fld.Properties(&quot;RowSource&quot;)\r\n                    .ColumnCount = fld.Properties(&quot;ColumnCount&quot;)\r\n                    .ColumnWidths = fld.Properties(&quot;ColumnWidths&quot;)\r\n                End With\r\n        End Select\r\n        Set lbl = Application.CreateControl(strFormname, acLabel, acDetail, ctl.Name)\r\n        lbl.Caption = fld.Name\r\n        On Error Resume Next\r\n        lbl.Caption = fld.Properties(&quot;Caption&quot;)\r\n        On Error GoTo 0\r\n    Next fld\r\n    frm.RecordSource = strRecordsource\r\n    frm.DefaultView = acDefViewDatasheet\r\n    DoCmd.Close acForm, frm.Name, acSaveYes\r\nEnd Sub<\/pre>\n<p>Danach wird ein <b>Recordset<\/b>-Objekt mit den Datens&auml;tzen der mit dem Parameter <b>strRecordsource <\/b>angegebenen Tabelle oder Abfrage gef&uuml;llt. Dieses ben&ouml;tigen wir, um die Felder der Datenherkunft zu durchlaufen und die entsprechenden Steuerelemente im Formular anzulegen.<\/p>\n<p>Man k&ouml;nnte die Felder zwar auch &uuml;ber ein <b>TableDef<\/b>&#8211; beziehungsweise ein <b>QueryDef<\/b>-Objekt auslesen, aber dazu m&uuml;sste man noch pr&uuml;fen, ob es sich bei dem in <b>strRecordsource <\/b>angegebenen Objekt um eine Tabelle oder Abfrage handelt.<\/p>\n<p>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&uuml;r die Performance ist (<b>TableDef <\/b>und <b>QueryDef <\/b>enthalten nur die Definition, <b>Recordset <\/b>enth&auml;lt auch Daten und k&ouml;nnte ein wenig mehr Zeit zum F&uuml;llen beanspruchen).<\/p>\n<p>Beim Durchlaufen der einzelnen Felder der Datenherkunft &uuml;ber die <b>Fields<\/b>-Auflistung geschehen folgende Schritte:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Ein Tabellenfeld kann unter anderem als Textfeld, als Kombinationsfeld oder als Kontrollk&auml;stchen angezeigt werden. Die Variable <b>intControlType<\/b> speichert den Typ, wobei diese zuerst mit dem Standardwert <b>acTextBox <\/b>gef&uuml;llt wird. Wenn das Feld nicht als Textfeld angezeigt wird, enth&auml;lt die als <b>Property <\/b>gespeicherte Eigenschaft <b>DisplayControl <\/b>die Konstante f&uuml;r das entsprechende Steuerelement, beispielsweise <b>acComboBox <\/b>oder <b>acCheckBox<\/b>. Dieser Wert landet dann gegebenenfalls statt <b>acTextBox <\/b>in der Variablen <b>intControlType<\/b>.<\/li>\n<li class=\"aufz-hlung\">Die <b>CreateControl<\/b>-Methode erzeugt im Detailbereich des angegebenen Formulars ein Steuerelement des soeben ermittelten Typs und speichert einen Verweis darauf in der Variablen <b>ctl<\/b>.<\/li>\n<li class=\"aufz-hlung\">Die Eigenschaft <b>ControlSource <\/b>(im Eigenschaftsfenster <b>Steuerelementinhalt<\/b>) erh&auml;lt als Wert den Inhalt der Eigenschaft <b>SourceField <\/b>des <b>Field<\/b>-Objekts.<\/li>\n<li class=\"aufz-hlung\">Anschlie&szlig;end untersucht ein <b>Select Case<\/b>-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 <b>Datensatzherkunft <\/b>(<b>RowSource<\/b>), die <b>Spaltenanzahl <\/b>(<b>ColumnCount<\/b>) und die <b>Spaltenbreiten <\/b>(<b>ColumnWidths<\/b>).<\/li>\n<li class=\"aufz-hlung\">Schlie&szlig;lich wird ein passendes Bezeichnungsfeld f&uuml;r jedes Steuerelement erzeugt. Dieses erh&auml;lt als Beschriftung zun&auml;chst den Namen des Feldes. Falls der Entwickler mit der Eigenschaft <b>Beschriftung <\/b>eine alternative Beschriftung hinterlegt hat, besitzt das Feld eine <b>Property <\/b>namens <b>Caption<\/b>. Ist diese vorhanden, wird das Bezeichnungsfeld damit betitelt.<\/li>\n<li class=\"aufz-hlung\">Schlie&szlig;lich wird die Datenherkunft des Formulars auf den mit <b>strRecordsource <\/b>&uuml;bergebenen Ausdruck und die <b>Standardansicht <\/b>auf <b>Datenblatt <\/b>eingestellt.<\/li>\n<li class=\"aufz-hlung\">Im letzten Schritt wird das Formular geschlossen und gespeichert.<\/li>\n<\/ul>\n<p><!--30percent--><\/p>\n<p>Wenn Sie das Formular auf Basis der Tabelle <b>tblAdressen<\/b> der Beispieldatenbank erstellt haben, sieht das Formular nach dem &Ouml;ffnen wie in Bild 1 aus. Ein Wechsel in die Entwurfsansicht liefert allerdings ein &uuml;berraschendes Bild: Dort befindet sich offensichtlich nur ein einziges Steuerelement (siehe Bild 2)! Doch das ist nicht der Fall, denn die Prozedur hat lediglich alle Steuerelemente &uuml;bereinander angelegt beziehungsweise Gr&ouml;&szlig;e und Position nach dem Anlegen nicht mehr ge&auml;ndert.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_02\/GenerischeFormulare-web-images\/pic001.png\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Ein per VBA-Code erstelltes Formular in der Datenblattansicht<\/span><\/b><\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_02\/GenerischeFormulare-web-images\/pic003.png\" alt=\"pic003.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Die Entwurfsansicht ist nur schwer bearbeitbar &#8230;<\/span><\/b><\/p>\n<p>Das ist f&uuml;r die Datenblattansicht eigentlich nicht relevant, aber f&uuml;r die sp&auml;tere Bearbeitung eher unpraktisch &#8211; wozu erstellen wir vollautomatisch ein Formular, wenn wir anschlie&szlig;end doch wieder mehr Handgriffe ausf&uuml;hren m&uuml;ssen, um das Formular unseren W&uuml;nschen anzupassen<\/p>\n<p>Also erweitern wir die Prozedur noch um einige Zeilen, welche die Steuerelemente &uuml;bersichtlich anordnen &#8211; etwa so wie in Bild 3. Diese Abbildung ber&uuml;cksichtigt gleichzeitig eine Einstellung der Gr&ouml;&szlig;e entsprechend des f&uuml;r die angezeigten Daten ben&ouml;tigten Platzes. Au&szlig;erdem sollen auch die Spaltenbreiten der Datenblattansicht entsprechend den bereits in der Datenherkunft enthaltenen Daten optimiert werden.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_02\/GenerischeFormulare-web-images\/pic002.png\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: So sollte das Formular im Entwurf aussehen.<\/span><\/b><\/p>\n<p><b>Formulare f&uuml;r die Formularansicht erstellen<\/b><\/p>\n<p>Nachdem wir die Datenblattansicht abgedeckt haben (wenn auch mit einer etwas komprimierten Entwurfsansicht), widmen wir uns einer etwas komplizierteren Aufgabe: Dem Erstellen eines Formulars, das auch in der Entwurfs- und somit in der Formularansicht ein akzeptables Bild abgibt. Dabei wollen wir folgende Voraussetzungen erf&uuml;llen:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Jedes Steuerelement soll jeweils ein Bezeichnungsfeld besitzen.<\/li>\n<li class=\"aufz-hlung\">Die Steuerelemente sollen mit ein paar Pixeln Abstand untereinander angeordnet werden.<\/li>\n<li class=\"aufz-hlung\">Die Breite der Bezeichnungsfelder soll sich nach dem breitesten Bezeichnungsfeld richten.<\/li>\n<li class=\"aufz-hlung\">Die zu den Bezeichnungsfeldern geh&ouml;renden Steuerelemente sollen jeweils rechts daneben angeordnet werden.<\/li>\n<li class=\"aufz-hlung\">Die Breite von Textfeldern, Kombinationsfeldern und Listenfeldern wird dem breitesten enthaltenen Text angepasst (plus ein paar Prozent f&uuml;r folgende Eintr&auml;ge).<\/li>\n<li class=\"aufz-hlung\">Wenn ein Feld noch keine Daten enth&auml;lt, soll eine per Parameter zu definierende Mindestbreite verwendet werden.<\/li>\n<li class=\"aufz-hlung\">Die Vorgaben f&uuml;r Memofelder sind schwer zu definieren, weil diese ja auch mehrzeilig sein k&ouml;nnen. Eine Idee w&auml;re, die Breite dem breitesten der &uuml;brigen Text-Steuerelemente anzupassen und eine Standardh&ouml;he von vier Zeilen festzulegen.<\/li>\n<li class=\"aufz-hlung\">Kombinationsfelder sollen gegebenenfalls mit den in der Felddefinition festgelegten Nachschlagefeld-Eigenschaften ausgestattet werden.<\/li>\n<li class=\"aufz-hlung\">Die Steuerelemente sollen ordnungsgem&auml;&szlig; mit Pr&auml;fixen versehen werden, also beispielsweise <b>txtText <\/b>f&uuml;r ein Textfeld!<\/li>\n<\/ul>\n<p><b>Prozedur zum Erstellen von Formularen mit passenden Steuerelementbreiten<\/b><\/p>\n<p>Die Prozedur <b>FormularansichtEinrichten <\/b>(s. Listing 2) hat viel mehr zu erledigen als die Prozedur zum Erstellen eines Formulars in der Datenblattansicht. Nach dem Deklarationsteil &ouml;ffnet diese zun&auml;chst das leere, mit der weiter oben vorgestellten Prozedur <b>FormularErstellen <\/b>erstellte Formular in der Entwurfsansicht und verweist mit der <b>Form<\/b>-Objektvariablen <b>frm <\/b>darauf. Dann f&uuml;llt es die Variable <b>db <\/b>mit einem Verweis auf das aktuelle <b>Database<\/b>-Objekt und erzeugt eine Datensatzgruppe mit den im Formular anzuzeigenden Daten.<\/p>\n<p class=\"kastentabelleheader\">Listing 2: Anlegen eines neuen Formulars in der Formularansicht<\/p>\n<pre>Public Sub FormularansichtEinrichten(strFormname As String, strRecordsource As String)\r\n    ''... Deklaration\r\n    DoCmd.OpenForm strFormname, acDesign\r\n    Set frm = Forms(strFormname)\r\n    Set db = CurrentDb\r\n    Set rst = db.OpenRecordset(strRecordsource, dbOpenDynaset)\r\n    Call GetSizeAllLabels(rst, frm.DefaultControl(acTextBox), lngLabelX, lngLabelY)\r\n    sngTop = 100\r\n    For Each fld In rst.Fields\r\n         intControlType = acTextBox\r\n        On Error Resume Next\r\n        intControlType = fld.Properties(&quot;DisplayControl&quot;)\r\n        On Error GoTo 0\r\n        Set ctl = Application.CreateControl(strFormname, intControlType, acDetail, , , lngLabelX _\r\n        + 300, sngTop)\r\n        Call GetMaximalSizeControl(db, strRecordsource, ctl, fld, lngControlX, lngControlY)\r\n        intFieldsize = 0\r\n        On Error Resume Next\r\n        intFieldsize = fld.FieldSize\r\n        If Err.Number = 0 Then ''Memo\r\n            lngControlX = lngControlX \/ 4\r\n            lngControlY = lngControlY * 4\r\n        End If\r\n        On Error GoTo 0\r\n        ctl.Width = lngControlX\r\n        ctl.Height = lngControlY\r\n        ctl.ControlSource = fld.SourceField\r\n        Select Case intControlType\r\n            Case acComboBox\r\n                ctl.RowSource = fld.Properties(&quot;RowSource&quot;)\r\n                ctl.ColumnCount = fld.Properties(&quot;ColumnCount&quot;)\r\n                ctl.ColumnWidths = fld.Properties(&quot;ColumnWidths&quot;)\r\n                ctl.Name = &quot;cbo&quot; &amp; fld.Name\r\n            Case acListBox\r\n                ctl.RowSource = fld.Properties(&quot;RowSource&quot;)\r\n                ctl.ColumnCount = fld.Properties(&quot;ColumnCount&quot;)\r\n                ctl.ColumnWidths = fld.Properties(&quot;ColumnWidths&quot;)\r\n                ctl.Name = &quot;lst&quot; &amp; fld.Name\r\n            Case acCheckBox\r\n                ctl.Name = &quot;chk&quot; &amp; fld.Name\r\n            Case acTextBox\r\n                ctl.Name = &quot;txt&quot; &amp; fld.Name\r\n        End Select\r\n        Call BuildLabel(frm, fld, ctl, intControlType, lngLabelX, lngLabelY, sngTop)\r\n        sngTop = sngTop + ctl.Height + 40 ''f&uuml;r Abstand\r\n    Next fld\r\n    frm.RecordSource = strRecordsource\r\n    frm.DefaultView = acDefViewSingle\r\n    DoCmd.Close acForm, frm.Name, acSaveYes\r\nEnd Sub<\/pre>\n<p>Bevor auch nur ein einziges Steuerelement angelegt werden kann, brauchen wir den Abstand der gebundenen Steuerelemente vom rechten Rand. Dieser h&auml;ngt ma&szlig;geblich von der Breite der Beschriftungsfelder ab, die sich wiederum am enthaltenen Text in der verwendeten Schriftart, Schriftgr&ouml;&szlig;e und weiteren Schrifteigenschaften orientiert. Die maximale Breite der Beschriftungstexte liefert die Funktion <b>GetSizeAllLabels<\/b>, die wir weiter unten beschreiben, mit dem Parameter <b>lngLabelX<\/b>.<\/p>\n<p>Nachdem wir diese wertvolle Information erhalten haben, beginnt die Prozedur, alle Steuerelemente der Datenherkunft in einer <b>For Each<\/b>-Schleife abzuarbeiten. Wir m&uuml;ssen zun&auml;chst herausfinden, mit welchem Steuerelementtyp die Feldinhalte abgebildet werden sollen. Standardm&auml;&szlig;ig ist dies <b>acTextBox<\/b>. Bei Nachschlagefeldern oder <b>Ja\/Nein<\/b>-Feldern k&ouml;nnen dies beispielsweise auch Kombinationsfelder oder Kontrollk&auml;stchen sein. Auskunft dar&uuml;ber gibt eine Eigenschaft des betroffenen <b>Field<\/b>-Objekts, die wir mit dem Ausdruck <b>fld.Properties(&quot;DisplayControl&quot;) <\/b>ermitteln. Diese Eigenschaft ist aber nur vorhanden, wenn ein anderes Steuerelement als ein Textfeld verwendet werden soll. Da der Zugriff auf eine nicht vorhandene <b>Property <\/b>einen Fehler ausl&ouml;st, deaktivieren wir die Fehlerbehandlung hier kurzfristig.<\/p>\n<p>Die folgende Anweisung erstellt dann mit der Methode <b>CreateControl <\/b>auch gleich das gew&uuml;nschte Steuerelement. Der Abstand vom linken Rand des Formulars entspricht der Breite der Bezeichungsfelder plus einem Leerraum, der Abstand vom oberen Rand stammt aus der Variablen <b>sngTop<\/b>. Diese Variable wird jeweils um die H&ouml;he des aktuell hinzugef&uuml;gten Steuerelements erh&ouml;ht.<\/p>\n<p>Auch beim Steuerelement m&ouml;chten wir die optimale Breite ermitteln, die sich nach den bereits im Recordset enthaltenen Daten richtet. Sie sollten also vor dem Anlegen des Formulars mit dieser Prozedur ein paar repr&auml;sentative Daten in die zugrunde liegende Tabelle eintragen. Die Breite des Steuerelements liefert die Prozedur <b>GetMaximalSizeControl<\/b>, die wir ebenfalls im Anschluss beschreiben.<\/p>\n<p>Nun folgt eine kleine Sonderbehandlung f&uuml;r Memofelder: Da diese oft lange Texte enthalten, sollen sie mehrzeilig ausgelegt werden. Ein Memofeld identifizieren wir, indem wir die Eigenschaft <b>FieldSize <\/b>auslesen, die nur f&uuml;r Memofelder vorliegt. Auch hier setzen wir vorbeugend die oben verwendete Fehlerbehandlung ein. Das Memofeld passen wir an, indem wir die von <b>GetMaximalSizeControl <\/b>ermittelte Breite durch vier teilen und die H&ouml;he mit vier multiplizieren.<\/p>\n<p>Anschlie&szlig;end weist die Prozedur dem Steuerelement die ermittelten Ma&szlig;e zu, Gleiches gilt f&uuml;r die Datenherkunft, die wir der Eigenschaft <b>SourceField <\/b>des <b>Field<\/b>-Objekts entnehmen.<\/p>\n<p>Nun folgt eine Sonderbehandlung f&uuml;r die verschiedenen Steuerelementtypen, die erstens einen Steuerelementnamen mit einem entsprechenden Pr&auml;fix vergibt und zweitens die Eigenschaften <b>Datensatzherkunft<\/b>, <b>Spaltenanzahl <\/b>und <b>Spaltenbreite <\/b>f&uuml;r Kombinations- und Listenfelder einstellt.<\/p>\n<p>Erst jetzt wird das Bezeichnungsfeld f&uuml;r das jeweilige Steuerelement hinzugef&uuml;gt. Warum erst jetzt Nun: Die Bindung des Bezeichnungsfelds an ein Steuerelement wird &uuml;ber das Setzen des Parameters <b>Parent <\/b>der <b>CreateControl<\/b>-Methode erzeugt, was das Vorhandensein des Steuerelements, an welches das Bezeichnungsfeld gebunden werden soll, zwingend voraussetzt. Dies und weitere Arbeiten &uuml;bernimmt die Funktion <b>BuildLabel<\/b>.<\/p>\n<p>Schlie&szlig;lich wird die H&ouml;he des neuen Steuerelements zur Variablen <b>sngTop <\/b>hinzuaddiert &#8211; auch hier unter Ber&uuml;cksichtigung eines kleinen Puffers. Auf die gleiche Weise legt die Prozedur die &uuml;brigen Steuerelemente an. Zu guter Letzt weist sie dem Formular die richtige Datenherkunft zu, stellt <b>Formularansicht <\/b>als <b>Standardansicht <\/b>ein und speichert das Formular.<\/p>\n<p><b>Breite der Bezeichnungsfelder ermitteln<\/b><\/p>\n<p>Die Funktion <b>GetSizeAllLabels <\/b>(s. Listing 3) ermittelt die maximale Breite der Bezeichnungsfelder des Formulars. Sie erwartet einen Verweis auf das Recordset mit den Daten und auf ein Standardsteuerelement als Parameter und liefert H&ouml;he und Breite zur&uuml;ck.<\/p>\n<p class=\"kastentabelleheader\">Listing 3: Ermitteln der maximalen Breite der Bezeichnungsfelder eines Formulars<\/p>\n<pre>Public Function GetSizeAllLabels(rst As DAO.Recordset, ctl As Control, lngX As Long, lngY As Long)\r\n    Dim fld As DAO.Field\r\n    Dim strCaption As String\r\n    Dim lngXTemp As Long\r\n    Dim lngYTemp As Long\r\n    For Each fld In rst.Fields\r\n        strCaption = fld.Name\r\n        On Error Resume Next\r\n        strCaption = fld.Properties(&quot;Caption&quot;)\r\n        On Error GoTo 0\r\n        WizHook.Key = 51488399\r\n        WizHook.TwipsFromFont ctl.FontName, ctl.FontSize, ctl.FontWeight, ctl.FontItalic, _\r\n        ctl.FontUnderline, 0, strCaption, 0, lngXTemp, lngYTemp\r\n        If lngXTemp &gt; lngX Then\r\n             lngX = lngXTemp\r\n        End If\r\n        If lngYTemp &gt; lngY Then\r\n             lngY = lngYTemp\r\n        End If\r\n    Next fld\r\nEnd Function<\/pre>\n<p>Die Funktion durchl&auml;uft alle Felder in einer <b>For Each<\/b>-Schleife und speichert zun&auml;chst den Feldnamen in der Variablen <b>strCaption<\/b>. Felder k&ouml;nnen aber auch noch eine vom Feldnamen abweichende Beschriftung aufweisen, welche in der nur dann vorhandenen Eigenschaft <b>Caption <\/b>gespeichert wird.<\/p>\n<p>Um den Fehler beim Auslesen einer nicht vorhandenen <b>Property <\/b>zu umgehen, wird auch hier kurzzeitig die Fehlerbehandlung ausgeschaltet.<\/p>\n<p>Dann kommt der Auftritt der nicht dokumentierten Funktion <b>TwipsFromFont <\/b>der <b>WizHook<\/b>-Klasse: Diese liefert, wenn man ihr die Schrifteigenschaften und den Text &uuml;bergibt, die genaue Breite und H&ouml;he des Textes zur&uuml;ck.<\/p>\n<p>Der Rest ist Flei&szlig;arbeit: Die Prozedur pr&uuml;ft f&uuml;r jedes neue Bezeichnungsfeld, ob die ben&ouml;tigte Breite gr&ouml;&szlig;er als die bis dato gr&ouml;&szlig;te Breite ist, und ersetzt diese gegebenenfalls.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Breite und H&ouml;he eines Steuerelements ermitteln<\/p>\n<p>Die Funktion <b>GetMaximalSizeControl <\/b>ermittelt die Breite eines Steuerelements (s. Listing 4).<\/p>\n<p class=\"kastentabelleheader\">Listing 4: Ermitteln der maximalen Breite eines Steuerelements<\/p>\n<pre>Public Function GetMaximalSizeControl(db As DAO.Database, strRecordsource As String, _\r\n    ByVal ctl As Control, fld As DAO.Field, lngDXMax As Long, lngDYMax As Long)\r\n    ''...Deklaration\r\n    lngDXMax = 0\r\n    lngDYMax = 0\r\n    intControlType = ctl.ControlType\r\n    Select Case intControlType\r\n    Case acCheckBox\r\n    Set ctl = CreateControl(ctl.Parent.Name, acTextBox, acDetail)\r\n    End Select\r\n    On Error Resume Next\r\n    intControlType = fld.Properties(&quot;DisplayControl&quot;)\r\n    On Error GoTo 0\r\n    Select Case intControlType\r\n    Case acComboBox, acListBox\r\n    Set rst = db.OpenRecordset(fld.Properties(&quot;RowSource&quot;))\r\n    strSpaltenbreiten = Split(fld.Properties(&quot;ColumnWidths&quot;), &quot;;&quot;)\r\n    For i = LBound(strSpaltenbreiten) To UBound(strSpaltenbreiten)\r\n        If Not strSpaltenbreiten(i) = 0 Then\r\n            varFeldname = i\r\n            Exit For\r\n        End If\r\n    Next i\r\n    Case Else\r\n    Set rst = db.OpenRecordset(strRecordsource)\r\n    varFeldname = fld.Name\r\n    End Select\r\n    Do While Not rst.EOF\r\n        If IsNumeric(varFeldname) Then\r\n            strText = Nz(rst.Fields(CInt(varFeldname)).Value)\r\n        Else\r\n            strText = Nz(rst.Fields(varFeldname).Value)\r\n        End If\r\n        WizHook.Key = 51488399\r\n        WizHook.TwipsFromFont ctl.FontName, ctl.FontSize, ctl.FontWeight, ctl.FontItalic, _\r\n        ctl.FontUnderline, 0, strText, 0, lngDX, lngDY\r\n        If lngDX &gt; lngDXMax Then\r\n            lngDXMax = lngDX\r\n        End If\r\n        If lngDY &gt; lngDYMax Then\r\n            lngDYMax = lngDY\r\n        End If\r\n        rst.MoveNext\r\n    Loop\r\n    Select Case intControlType\r\n    Case acComboBox\r\n    lngDXMax = lngDXMax + lngDYMax\r\n    Case acListBox\r\n    lngDXMax = lngDXMax + lngDYMax\r\n    lngDYMax = lngDYMax * 8\r\n    Case acCheckBox\r\n    DeleteControl ctl.Parent.Name, ctl.Name\r\n    End Select\r\n    lngDXMax = (lngDXMax + 100) * 1.3\r\n    lngDYMax = lngDYMax * 1.1\r\nEnd Function<\/pre>\n<p>Das ist ungleich schwieriger als das Ermitteln der Breite der Beschriftungsfelder, denn wir m&uuml;ssen ja alle vorhandenen Feldwerte nach dem Text mit dem gr&ouml;&szlig;ten Platzbedarf durchsuchen.<\/p>\n<p>Und manchmal wird es noch komplizierter, denn etwa bei Kombinations- und Listenfeldern m&uuml;ssen wir uns auch noch um deren Datensatzherkunft k&uuml;mmern.<\/p>\n<p>Die Funktion erwartet wiederum einen Verweis auf das aktuelle <b>Database<\/b>-Objekt, die Datenherkunft, einen Verweis auf ein Steuerelement des Formulars, um die Schrifteigenschaften auszulesen, sowie einen Verweis auf das zu untersuchende Feld der Datenherkunft.<\/p>\n<p>Gleich zu Beginn erfahren Kontrollk&auml;stchen eine Sonderbehandlung: Sie werden durch ein herk&ouml;mmliches Textfeld ersetzt, da sie nicht die Eigenschaften aufweisen, die f&uuml;r die Analyse mit der auch hier verwendeten <b>TwipsFromFont<\/b>-Funktion n&ouml;tig sind.<\/p>\n<p>Die Sonderbehandlung f&uuml;r Kombinations- und Listenfelder startet mit deren Erkennung &uuml;ber die Eigenschaft <b>DisplayType<\/b>, die Sie bereits weiter oben kennengelernt haben.<\/p>\n<p>Trifft die Routine auf ein solches Steuerelement, dann untersucht sie nicht die Werte des eigentlichen Steuerelements, sondern die der Datensatzherkunft des Steuerelements, also der Tabelle oder Abfrage, aus der das Steuerelement seine Werte bezieht.<\/p>\n<p>Hier ermittelt die Routine zun&auml;chst die erste Spalte, die das Steuerelement anzeigt, in der Regel also die erste Spalte nach dem gebundenen Feld (die Berechnung der Breite bezieht sich also immer auf die Anzeige einer einzigen Spalte &#8211; sollen etwa in einem Listenfeld mehrere Spalten angezeigt werden, ist manuelle Nacharbeit n&ouml;tig).<\/p>\n<p>Wenn es sich beim aktuellen Steuerelement um ein Textfeld handelt, untersucht die Routine nachfolgend ganz einfach die Inhalte des an dieses Steuerelement gebundenen Feldes.<\/p>\n<p>Die Ermittlung der ben&ouml;tigten Breite ist prinzipiell mit dem f&uuml;r die Breite der Bezeichnungsfelder angewandten Algorithmus identisch. F&uuml;r Kombinations- und Listenfelder gibt es noch ein paar Anpassungen.<\/p>\n<p>So wird f&uuml;r Kombinationsfelder noch ein kleiner Aufschlag f&uuml;r die Schaltfl&auml;che zum Aufklappen des Kombinationsfeldes eingerechnet, und die H&ouml;he von Listenfeldern wird auf acht festgesetzt.<\/p>\n<p><b>Erstellen der Bezeichnungsfelder<\/b><\/p>\n<p>Im Anschluss an das Erstellen eines jeden Steuerelements ruft die Prozedur <b>FormularansichtEinrichten <\/b>die Funktion <b>BuildLabel <\/b>auf, die das passende Bezeichnungsfeld hinzuf&uuml;gt (s. Listing 5).<\/p>\n<p class=\"kastentabelleheader\">Listing 5: Erstellen eines Bezeichnungsfeld f&uuml;r ein Steuerelement<\/p>\n<pre>Public Function BuildLabel(frm As Form, fld As DAO.Field, ctl As Control, intControlType As _\r\n        AcControlType, lngLabelX As Long, lngLabelY As Long, sngTop As Single) As Label\r\n    Dim lbl As Control\r\n    Dim strCaption As String\r\n    Set lbl = Application.CreateControl(frm.Name, acLabel, acDetail, ctl.Name, , 100, sngTop, _\r\n    lngLabelX + 100, lngLabelY)\r\n    strCaption = fld.Name\r\n    On Error Resume Next\r\n    strCaption = fld.Properties(&quot;Caption&quot;)\r\n    On Error GoTo 0\r\n    If frm.DefaultControl(intControlType).AddColon Then\r\n        strCaption = strCaption &amp; &quot;:&quot;\r\n    End If\r\n    lbl.Caption = strCaption\r\n    Set BuildLabel = lbl\r\nEnd Function<\/pre>\n<p>Diese Funktion erwartet einen Verweis auf das Formular-Objekt, in dem das Bezeichnungsfeld erstellt werden soll, einen Verweis auf das Feld, aus dem die im betroffenen Steuerelement anzuzeigenden Daten stammen, einen Verweis auf das Steuerelement selbst, den Typ des Steuerelements, die H&ouml;he, Breite und vertikale Position des zu erzeugenden Bezeichnungsfeldes.<\/p>\n<p>Daraus erzeugt sie dann schon das Bezeichnungsfeld mit den wesentlichen Eigenschaften. Die Prozedur muss noch untersuchen, ob sie den Feldnamen oder den eventuell in der Eigenschaft <b>Caption <\/b>gespeicherten Ausdruck als Beschriftung verwendet.<\/p>\n<p>Au&szlig;erdem ermittelt sie &uuml;ber die Eigenschaft <b>AddColon <\/b>der Standardeinstellungen des aktuellen Steuerelementtyps, ob der Beschriftung ein Doppelpunkt angeh&auml;ngt werden soll.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Die vorgestellten Routinen zum Erstellen von Formularen auf Basis von Tabellen oder Abfragen nehmen Ihnen viel Arbeit ab, wenn Sie schnell ein Formular in der Datenblattansicht oder in der Formularansicht erstellen m&ouml;chten und Ihnen die Vorlagen von Access nicht gefallen.<\/p>\n<p>Gleichzeitig gibt es eine Menge Erweiterungs- und Verbesserungspotenzial. Beginnen wir mit der Datenblattansicht: Hier w&auml;re es leicht, mithilfe der Funktion <b>GetMaximalSizeControl <\/b>die maximale Breite eines Steuerelements zu ermitteln und diese auf die Breite der entsprechenden Spalte des Datenblatts anzuwenden.<\/p>\n<p>Die relevante Eigenschaft lautet <b>ColumnWidth<\/b>. Beachten Sie, dass Sie auch die Breite der Spalten&uuml;berschrift mit einbeziehen, damit diese nicht abgeschnitten wird, wenn die Inhalte weniger Platz als diese beanspruchen sollten.<\/p>\n<p>F&uuml;r die Formulare in der Formularansicht gibt es noch zahlreiche weitere Vorschl&auml;ge:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Sie k&ouml;nnten beispielsweise weitere Parameter hinzuf&uuml;gen, mit denen Sie steuern, wie gro&szlig; der Abstand der Steuerelemente untereinander ist und welchen Abstand der Steuerelemente-Block vom linken, rechten, oberen und unteren Rand des Formularbereichs hat.<\/li>\n<li class=\"aufz-hlung\">Sie brauchen sich nicht auf die Steuerelemente zu beschr&auml;nken, die aus der Datenherkunft resultieren. Warum bauen Sie sich keine Funktion, mit der Sie einem Detailformular zum Bearbeiten von Datens&auml;tzen gleich noch eine <b>OK<\/b>&#8211; und eine <b>Abbrechen<\/b>-Schaltfl&auml;che samt der entsprechenden Ereignisprozeduren hinzuf&uuml;gen<\/li>\n<li class=\"aufz-hlung\">Richtig interessant wird es, wenn Ihre Funktionen zum Erstellen verschiedener Formulare richtig ausgefeilt und bereit f&uuml;r den Praxiseinsatz sind. Sie k&ouml;nnen diese dann in eine Add-In-Datenbank integrieren und daf&uuml;r sorgen, dass Access Ihre Funktionen zum Erstellen von Formularen Seite an Seite mit den eingebauten Assistenten anzeigt. Vielleicht m&ouml;chten Sie die eingebauten Assistenten ja auch gleich rauswerfen<\/li>\n<\/ul>\n<p>Die hier vorgestellten Techniken eignen sich nat&uuml;rlich genauso f&uuml;r die Erstellung von Berichten. Gerade hier macht es Sinn, die Spaltenbreiten automatisiert von den anzuzeigenden Daten abh&auml;ngig zu machen &#8211; immerhin kann der Benutzer in einem Bericht nicht mal eben wie in der Datenblattansicht die Spalten vergr&ouml;&szlig;ern oder verkleinern.<\/p>\n<p>Sie sehen: Es gibt Erweiterungspotenzial, und nach M&ouml;glichkeit greifen wir dies in einem weiteren Beitrag in <b>Access im Unternehmen <\/b>auf.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>FormulareGenerieren.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{C30B7606-57F1-42E8-8452-28772266B303}\/aiu_709.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>F&uuml;r Einsteiger sind die Formular-Assistenten von Access sicher eine hilfreiche Einrichtung. Fortgeschrittene Entwickler verwenden diese jedoch eher selten &#8211; sie haben eine individuell verschiedene Vorgehensweise, diese zu erstellen, mit Datenherkunft und Steuerelementen zu bef&uuml;llen und Eigenschaften und Ereignisse festzulegen. Wenn man aber immer wieder &auml;hnliche Formulare ben&ouml;tigt, ist das st&auml;ndige Neuerstellen vergeudete Zeit: Per Copy and Paste oder auch mit ein paar Zeilen Code gelingt dies doch deutlich schneller.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66022010,662010,44000023,44000025],"tags":[],"class_list":["post-55000709","post","type-post","status-publish","format-standard","hentry","category-66022010","category-662010","category-Mit_Formularen_arbeiten","category-VBA_und_Programmiertechniken"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Formulare generieren - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Formulare generieren\" \/>\n<meta property=\"og:description\" content=\"F&uuml;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&uuml;llen und Eigenschaften und Ereignisse festzulegen. Wenn man aber immer wieder &auml;hnliche Formulare ben&ouml;tigt, ist das st&auml;ndige Neuerstellen vergeudete Zeit: Per Copy and Paste oder auch mit ein paar Zeilen Code gelingt dies doch deutlich schneller.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T22:11:33+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg01.met.vgwort.de\/na\/d64c68c63c114048a674b186610ac43c\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"22\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Formulare generieren\",\"datePublished\":\"2020-05-22T22:11:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/\"},\"wordCount\":3488,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/d64c68c63c114048a674b186610ac43c\",\"articleSection\":[\"2\\\/2010\",\"2010\",\"Mit Formularen arbeiten\",\"VBA und Programmiertechniken\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/\",\"name\":\"Formulare generieren - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/d64c68c63c114048a674b186610ac43c\",\"datePublished\":\"2020-05-22T22:11:33+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/d64c68c63c114048a674b186610ac43c\",\"contentUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/d64c68c63c114048a674b186610ac43c\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Formulare_generieren\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Formulare generieren\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Formulare generieren - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/","og_locale":"de_DE","og_type":"article","og_title":"Formulare generieren","og_description":"F&uuml;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&uuml;llen und Eigenschaften und Ereignisse festzulegen. Wenn man aber immer wieder &auml;hnliche Formulare ben&ouml;tigt, ist das st&auml;ndige Neuerstellen vergeudete Zeit: Per Copy and Paste oder auch mit ein paar Zeilen Code gelingt dies doch deutlich schneller.","og_url":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T22:11:33+00:00","og_image":[{"url":"http:\/\/vg01.met.vgwort.de\/na\/d64c68c63c114048a674b186610ac43c","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"22\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Formulare generieren","datePublished":"2020-05-22T22:11:33+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/"},"wordCount":3488,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/d64c68c63c114048a674b186610ac43c","articleSection":["2\/2010","2010","Mit Formularen arbeiten","VBA und Programmiertechniken"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Formulare_generieren\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/","url":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/","name":"Formulare generieren - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/d64c68c63c114048a674b186610ac43c","datePublished":"2020-05-22T22:11:33+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Formulare_generieren\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/#primaryimage","url":"http:\/\/vg01.met.vgwort.de\/na\/d64c68c63c114048a674b186610ac43c","contentUrl":"http:\/\/vg01.met.vgwort.de\/na\/d64c68c63c114048a674b186610ac43c"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Formulare_generieren\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Formulare generieren"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000709","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000709"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000709\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000709"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000709"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000709"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}