{"id":55000722,"date":"2010-06-01T00:00:00","date_gmt":"2020-05-22T22:13:08","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=722"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"StandardLookupformulare","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/","title":{"rendered":"Standard-Lookupformulare"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg01.met.vgwort.de\/na\/bed4011bd6d04fea8df6ed5f15a4e6fc\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Lookuptabellen speichern meist Werte, die zum Vermeiden von Redundanzen und Inkonsistenzen aus einer anderen Tabelle ausgelagert wurden. Die Formulare f&uuml;r ihre Bearbeitung sehen meist gleich aus: Ein Hauptformular mit einer OK-Schaltfl&auml;che, ein Unterformular mit den Daten &#8211; das war es. Solche Formulare braucht man nicht f&uuml;r jede dieser Tabellen einzurichten: Es reicht ein einziges, dem Sie nur noch mitteilen, aus welcher Tabelle oder Abfrage die angezeigten Felder stammen sollen.<\/b><\/p>\n<p>Wie ein solches Formular aussieht, entnehmen Sie Bild 1: Es zeigt lediglich die vorhandenen Eintr&auml;ge der Lookuptabelle an und bietet die M&ouml;glichkeit, diese zu bearbeiten. Solch ein Formular ist schnell hergestellt: Schnell ein Haupt- und ein Unterformular erstellen, Datenherkunft des Unterformulars einstellen, Felder aus der Feldliste hinzuf&uuml;gen, Unterformular ins Hauptformular einf&uuml;gen, OK-Schaltfl&auml;che unterbringen &#8211; fertig!<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_03\/Lookupformulare-web-images\/pic001.png\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Ein typisches Lookupformular<\/span><\/b><\/p>\n<p>Was aber, wenn man eine ganze Reihe solcher Formulare ben&ouml;tigt Dann kommt schon ein wenig mehr Arbeit auf einen zu. Au&szlig;erdem steigt der Aufwand f&uuml;r &auml;nderungen wie etwa das Hinzuf&uuml;gen einer Fehlerbehandlungen oder Wartungsarbeiten proportional zur Anzahl der Formulare.<\/p>\n<p><b>Aus x mach 1<\/b><\/p>\n<p>Was tun Sie, wenn Sie die gleiche Abfolge identischer Codezeilen in einer oder mehreren VBA-Funktionen verwenden Sie erzeugen nat&uuml;rlich eine Prozedur oder Funktion, welche die enthaltenen Anweisungen an nur einer Stelle versammelt und rufen diese Anweisungen dann &uuml;ber die entsprechende Prozedur beziehungsweise Funktion auf &#8211; gegebenenfalls unter Einbeziehung eines oder mehrerer Parameter, welche die Prozedur oder Funktion individualisieren.<\/p>\n<p>Genau das gleiche machen wir jetzt mit den Lookupformularen. Wenn Sie in einer Anwendung eine Reihe &auml;hnlich aufgebauter Formulare verwenden, denken Sie einmal dar&uuml;ber nach, ob Sie deren Aufbau nicht genau gleich gestalten k&ouml;nnen (oder zumindest so, dass dieser &uuml;ber Parameter im gew&uuml;nschten Ma&szlig;e variiert werden kann).<\/p>\n<p>Wir zeigen, wie das mit einem Lookupformular wie aus Bild 1 funktioniert. Als einzigen Parameter verwenden wir dabei den Namen der Tabelle oder Abfrage, deren Daten angezeigt werden sollen beziehungsweise eine entsprechende SQL-Anweisung. Diese soll mit dem Parameter <b>OpenArgs<\/b> &uuml;bergeben werden, sodass der Aufruf unseres Formulars beispielsweise so aussieht:<\/p>\n<pre>DoCmd.OpenForm &quot;frmLookup&quot;, OpenArgs:=&quot;tblVerbrauchsarten&quot;<\/pre>\n<p>Das aufgerufene Formular wertet diese Datenherkunft dann aus und f&uuml;llt die Felder des Formulars entsprechend.<\/p>\n<p><b>Hauptformular<\/b><\/p>\n<p>Das Hauptformular &uuml;bernimmt die Hauptarbeit des Lookupformulars &#8211; zumindest, was den Code angeht. Ansonsten enth&auml;lt es lediglich das Unterformular <b>sfmLookup<\/b>, das wir im Anschluss beschreiben, sowie eine Schaltfl&auml;che mit der Beschriftung <b>OK<\/b>, die das Formular schlie&szlig;en soll (siehe Bild 2). Diese Schaltfl&auml;che l&ouml;st die folgende Ereignisprozedur aus:<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_03\/Lookupformulare-web-images\/pic002.png\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Das Formular frmLookup samt Unterformular in der Entwurfsansicht<\/span><\/b><\/p>\n<pre>Private Sub cmdOK_Click()\r\n    DoCmd.Close\r\nEnd Sub<\/pre>\n<p>Das Unterformular enth&auml;lt drei ungebundene Textfelder samt Bezeichnungsfeldern. Die Textfelder hei&szlig;en <b>txtValue1<\/b>, <b>txtValue2 <\/b>und <b>txtValue3<\/b>, die Bezeichnungsfelder <b>lblValue1<\/b>, <b>lblValue2 <\/b>und <b>lblValue3<\/b>. Wie Sie die Felder anordnen, ist egal &#8211; hauptsache, Sie stellen die Eigenschaft Standardansicht des Unterformulars auf <b>Datenblatt <\/b>ein.<\/p>\n<p><b>Formular &ouml;ffnen<\/b><\/p>\n<p>Kommen wir zum Aufrufen des Formulars. Dies geschieht, wie bereits erw&auml;hnt, &uuml;ber die <b>DoCmd-OpenForm<\/b>-Anweisung mit dem Namen der Datenherkunft als <b>OpenArgs<\/b>-Parameter. Diesen muss das Formular beim &Ouml;ffnen auswerten, was in einer Prozedur geschieht, die durch das Ereignis <b>Beim &Ouml;ffnen <\/b>geschieht.<\/p>\n<p>Diese Prozedur pr&uuml;ft, ob der <b>OpenArgs<\/b>-Parameter einen Wert enth&auml;lt und bricht das &Ouml;ffnen des Formulars ab, wenn dies nicht der Fall ist:<\/p>\n<pre>Private Sub Form_Open(Cancel As Integer)\r\n    If Len(Nz(Me.OpenArgs, &quot;&quot;)) = 0 Then\r\n        Cancel = True\r\n    End If\r\nEnd Sub<\/pre>\n<p>Dies sollten Sie bedenken, wenn Sie das Formular <b>frmLookup<\/b> der Beispieldatenbank per Doppelklick auf den Eintrag im Datenbankfenster beziehungsweise Navigationsbereich &ouml;ffnen m&ouml;chten.<\/p>\n<p>Nach dieser Pr&uuml;fung geht die eigentliche Arbeit los, und zwar in der Ereignisprozedur <b>Beim Laden <\/b>des Formulars (s. Listing 1).<\/p>\n<p class=\"kastentabelleheader\">Listing 1: Beim Laden des Formulars werden auch die Felder angepasst und gef&uuml;llt.<\/p>\n<pre>Private Sub Form_Load()\r\n    Dim db As DAO.Database\r\n    Dim obj As Object\r\n    Dim strColumnHeader As String\r\n    Dim strOpenArgs As String\r\n    Dim strCaption As String\r\n    Dim i As Integer\r\n    Dim intFieldcount As Integer\r\n    Dim lngWidth As Long\r\n    strOpenArgs = Nz(Me.OpenArgs, &quot;&quot;)\r\n    Set db = CurrentDb\r\n    Me!sfmLookup.Form.Recordsource = strOpenArgs\r\n    WizHook.Key = 51488399\r\n    Select Case WizHook.ObjTypOfRecordSource(strOpenArgs)\r\n    Case 0\r\n    On Error Resume Next\r\n    db.QueryDefs.Delete &quot;qdfTemp&quot;\r\n    On Error Goto 0\r\n    Set obj = db.CreateQueryDef(&quot;qdfTemp&quot;, strOpenArgs)\r\n    Case 1\r\n    Set obj = db.TableDefs(strOpenArgs)\r\n    Case 2\r\n    Set obj = db.QueryDefs(strOpenArgs)\r\n    End Select\r\n    intFieldcount = obj.Fields.Count\r\n    If intFieldcount &gt; 3 Then\r\n        intFieldcount = 3\r\n    End If\r\n    For i = 1 To 3\r\n        If intFieldcount &lt; i Then\r\n            Me!sfmLookup.Form.Controls(&quot;txtValue&quot; &amp; i).ColumnHidden = True\r\n        Else\r\n            Me!sfmLookup.Form.Controls(&quot;txtValue&quot; &amp; i).ControlSource = obj.Fields(i - 1).Name\r\n            strColumnHeader = obj.Fields(i - 1).Name\r\n            On Error Resume Next\r\n            strColumnHeader = obj.Fields(i - 1).Properties(&quot;Caption&quot;)\r\n            On Error Goto 0\r\n            Me!sfmLookup.Form.Controls(&quot;lblValue&quot; &amp; i).Caption = strColumnHeader\r\n            Me!sfmLookup.Form.Controls(&quot;txtValue&quot; &amp; i).ColumnWidth = (Spaltenbreite(db, _\r\n            strOpenArgs, strColumnHeader, Me!sfmLookup.Form.Controls(&quot;txtValue&quot; &amp; i)) + 500)\r\n            lngWidth = lngWidth + Me!sfmLookup.Form.Controls(&quot;txtValue&quot; &amp; i).ColumnWidth\r\n        End If\r\n    Next i\r\n    Me.InsideWidth = Me.InsideWidth - Me.sfmLookup.Width + lngWidth + 500\r\n    Me!sfmLookup.Width = lngWidth + 500\r\n    strCaption = obj.Name\r\n    On Error Resume Next\r\n    strCaption = obj.Properties(&quot;Description&quot;)\r\n    On Error Goto 0\r\n    Me.Caption = strCaption\r\nEnd Sub<\/pre>\n<p><!--30percent--><\/p>\n<p>Das &Ouml;ffnungsargument wird hier zun&auml;chst in der Variablen <b>strOpenArgs <\/b>zwischengespeichert und dem Unterformular &uuml;ber die Eigenschaft <b>Recordsource <\/b>als Datenherkunft zugewiesen. Damit ist das Unterformular an die betroffene Tabelle oder Abfrage gebunden.<\/p>\n<p>Danach ben&ouml;tigten wir ein Objekt, anhand dessen wir die Felder der Datenherkunft durchlaufen k&ouml;nnen, um die Felder des Unterformulars anpassen und f&uuml;llen zu k&ouml;nnen. Da der Benutzer mit dem &Ouml;ffnungsargument beliebige Datenherk&uuml;nfte &uuml;bergeben k&ouml;nnen soll (also Tabellen, Abfragen oder SQL-Ausdr&uuml;cke), haben wir zwei M&ouml;glichkeiten:<\/p>\n<p>Entweder wir &ouml;ffnen ein <b>Recordset<\/b>-Objekt auf Basis der angegebenen Datenherkunft und stellen dies per <b>WHERE<\/b>-Bedingung so ein, dass es keine Datens&auml;tze zur&uuml;ckliefert (denn wir brauchen es ja nur zur Identifikation der Felder), oder wir verwenden eines der Datendefinitions-Objekte wie <b>TableDef <\/b>oder <b>QueryDef<\/b>. Diese enthalten keine Daten, sondern nur die Definition der Tabelle beziehungsweise Abfrage.<\/p>\n<p>Die erste Variante &uuml;bergehen wir diesmal, da wir erst noch pr&uuml;fen m&uuml;ssten, ob der &uuml;bergebene Ausdruck eine Tabelle, Abfrage oder ein SQL-Ausdruck ist und ob dieser gegebenenfalls schon eine WHERE-Klausel enth&auml;lt &#8211; sprich: Es w&uuml;rden eine Reihe Zeichenkettenfunktionen aufgerufen, die wir uns diesmal einfach sparen m&ouml;chten.<\/p>\n<p>Im Falle der <b>TableDef<\/b>-\/<b>QueryDef<\/b>-Variante wissen wir allerdings ebenfalls nicht, ob <b>strOpenArgs <\/b>nun eine Tabelle, eine Abfrage oder einen SQL-Ausdruck enth&auml;lt. Das ist aber kein Problem, denn die nicht dokumentierte <b>WizHook<\/b>-Klasse liefert uns mit <b>ObjTypOfRecordSource <\/b>eine kleine Funktion, der wir den Datenherkunftsausdruck einfach &uuml;bergeben k&ouml;nnen (vorherige Aktivierung durch <b>WizHook.Key = 51488399 <\/b>n&ouml;tig). Heraus kommt eine von drei Zahlen:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>1<\/b>: Tabelle<\/li>\n<li class=\"aufz-hlung\"><b>2<\/b>: Abfrage<\/li>\n<li class=\"aufz-hlung\"><b>0<\/b>: Keins von beiden, in diesem Fall also ein SQL-Ausdruck.<\/li>\n<\/ul>\n<p>Den Verweis auf das Objekt f&uuml;r die sp&auml;tere Abfrage der Datenherkunftsinformationen wie Feldnamen et cetera speichern wir einfach in einer Variablen des Typs <b>Object<\/b>. Darin k&ouml;nnen wir fast alles speichern, und nach der Zuweisung des tats&auml;chlich ben&ouml;tigten Objekts greifen wir auch auf dessen Elemente zu &#8211; nur ohne IntelliSense.<\/p>\n<p>Nun weisen wir diesem in Abh&auml;ngigkeit vom Ergebnis entweder ein <b>TableDef<\/b>-Objekt, ein <b>QueryDef<\/b>-Objekt oder das Ergebnis der <b>CreateQueryDef<\/b>-Methode auf Basis des gegebenen SQL-Ausdrucks zu.<\/p>\n<p>Danach ermittelt die Prozedur die Anzahl der Felder der Datenherkunft. Ist diese gr&ouml;&szlig;er als drei, werden nur die ersten drei Felder ber&uuml;cksichtigt. Ist sie kleiner als drei, werden die ersten n Felder in den ersten Textfeldern angezeigt und die &uuml;brigen Textfelder samt Bezeichnungsfeldern ausgeblendet.<\/p>\n<p>Eine Menge davon geschieht in der nun folgenden <b>For Next<\/b>-Schleife. Sie pr&uuml;ft zun&auml;chst, ob der Index des aktuell behandelten Textfeldes des Unterformulars gr&ouml;&szlig;er als die Anzahl der Felder der Datenherkunft ist und blendet das Textfeld in diesem Fall aus (dies geschieht allerdings, wenn &uuml;berhaupt, in den sp&auml;teren Durchl&auml;ufen der Schleife).<\/p>\n<p>Innerhalb der ersten Durchl&auml;ufe sollten schon einige Textfelder anzupassen sein. Dabei weist die Prozedur dem Textfeld erstmal den Namen des Feldes als Steuerelementinhalt zu &#8211; somit ist dieses Textfeld an das entsprechende Tabellenfeld gebunden.<\/p>\n<p>Danach schreibt die Prozedur zun&auml;chst den Namen des aktuellen Tabellenfelds in die Variable <b>strColumnHeader<\/b>, die sp&auml;ter dem Bezeichnungsfeld als Beschriftung zugewiesen wird. Anschlie&szlig;end pr&uuml;ft sie noch, ob das Feld gegebenenfalls einen Eintrag f&uuml;r die Eigenschaft <b>Beschriftung <\/b>besitzt. Da die Abfrage von <b>Properties(&quot;Caption&quot;) <\/b>zum Fehler f&uuml;hren kann, wenn diese <b>Property <\/b>noch nicht angelegt ist, wird die Fehlerbehandlung kurz vorher ausgeschaltet. Die resultierende Beschriftung gelangt dann in die Eigenschaft <b>Caption <\/b>des Bezeichnungsfeldes des aktuellen Textfeldes.<\/p>\n<p>Dann folgt ein f&uuml;r die Ergonomie des Formulars wichtiger Schritt: &Uuml;ber die Funktion Spaltenbreite wird die maximal notwendige Breite f&uuml;r die aktuell vorliegenden Eintr&auml;ge der Lookuptabelle ermittelt (siehe unten) und der Eigenschaft ColumnWidth des Textfeldes zugewiesen. Diese Eigenschaft wirkt sich &uuml;brigens nur in der Datenblattansicht von Formularen aus.<\/p>\n<p>Diese Breite wird anschlie&szlig;end aufsummiert, um auch die Gesamtbreite des Formulars an die Breiten der einzelnen Spalten anzupassen.<\/p>\n<p>Dies geschieht gleich im Anschluss an die Best&uuml;ckung der Textfelder mit Hilfe der Eigenschaft <b>InsideWidth <\/b>des Hauptformulars beziehungsweise der Eigenschaft <b>Width <\/b>des Unterformularsteuerelements. In beiden F&auml;llen legen wir 500 Twips f&uuml;r die Breite des Datensatzmarkierers und ein wenig zus&auml;tzliche Luft drauf. Schlie&szlig;lich erh&auml;lt das Formular &uuml;ber die Eigenschaft <b>Caption <\/b>noch den Namen der Datenherkunft oder, falls vorhanden, den Beschreibungstext. An diesem Punkt k&ouml;nnen Sie leicht eingreifen, wenn Sie beispielsweise eine eigene &Uuml;berschrift unterbringen m&ouml;chten.<\/p>\n<p><b>Optimale Spaltenbreite ermitteln<\/b><\/p>\n<p>Die Funktion aus Listing 2 ermittelt die Spaltenbreite entsprechend des breitesten Eintrags der Daten, die im betroffenen Textfeld angezeigt werden sollen. Dazu &ouml;ffnet diese zun&auml;chst ein Recordset-Objekt auf Basis der Datenherkunft des Formulars. Anschlie&szlig;end kommt wiederum eine Funktion der WizHook-Klasse zum Einsatz, die in diesem Fall TwipsFromFont hei&szlig;t und die Breite des Textes in einer bestimmten Schriftart und sonstigen schriftartspezifischen Eigenschaften ermittelt. Diese Eigenschaften liefert das ebenfalls als Parameter &uuml;bergebene Steuerelement, das in diesem Fall nat&uuml;rlich die Eigenschaften des im Entwurf sichtbaren Textfeldes liefert, aber nicht repr&auml;sentativ f&uuml;r die entsprechenden Eigenschaften in der Datenblattansicht ist. Sie sollten die Textfelder daher so auslegen, dass die Formatierung des enthaltenen Textes denen der Datenblattansicht entspricht.<\/p>\n<p class=\"kastentabelleheader\">Listing 2: Ermitteln der Spaltenbreite f&uuml;r ein Textfeld<\/p>\n<pre>Public Function Spaltenbreite(db As DAO.Database, strRecordsource As String, _\r\n    strColumnHeader As String, ByVal ctl As Control) As Long\r\n    Dim rst As DAO.Recordset\r\n    Dim lngDX As Long\r\n    Dim strText As String\r\n    Dim varFeldname As String\r\n    Dim lngDY As Long\r\n    Dim lngDXMax As Long\r\n    Set rst = db.OpenRecordset(strRecordsource)\r\n    varFeldname = ctl.ControlSource\r\n    WizHook.Key = 51488399\r\n    WizHook.TwipsFromFont ctl.FontName, ctl.FontSize, ctl.FontWeight, ctl.FontItalic, _\r\n    ctl.FontUnderline, 0, strColumnHeader, 0, lngDXMax, lngDY\r\n    Do While Not rst.EOF\r\n        strText = Nz(rst.Fields(varFeldname).Value)\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        rst.MoveNext\r\n    Loop\r\n    Spaltenbreite = lngDXMax\r\nEnd Function<\/pre>\n<p>Die Funktion durchl&auml;uft in einer <b>Do While<\/b>-Schleife alle Datens&auml;tze der Datenherkunft und untersucht genau das an <b>ctl <\/b>gebundene Steuerelement, zum Beispiel <b>VerbrauchsartID<\/b>. Die beiden Parameter <b>lngDX<\/b> und <b>lngDY <\/b>liefern die Breite und H&ouml;he zur&uuml;ck, den der Text wohl einnehmen wird. Innerhalb der Schleife wird der jeweils breiteste Wert gespeichert und schlie&szlig;lich an die aufrufende Prozedur zur&uuml;ckgeliefert.<\/p>\n<p>Vor dem Durchlaufen der eigentlichen Daten ermittelt die Prozedur auch noch die Breite f&uuml;r den im Bezeichnungsfeld des jeweiligen Textfelds angezeigten Text, damit nicht nachher die Spalte genau der Textbreite der Daten entspricht, aber die Spalten&uuml;berschrift nicht mehr lesbar ist (dies passiert gern bei Lookuptabellen, die nur wenige Datens&auml;tze enthalten und deren Prim&auml;rschl&uuml;sselwerte daher gern kleiner als zweistellig sind und somit nur wenig Platz einnehmen).<\/p>\n<p><b>Fehlerbehandlung<\/b><\/p>\n<p>Nat&uuml;rlich soll das Formular auch den Fehlermeldungen von Access vorbeugen. Gerade in Lookupformularen mit vielen Daten kommt es gern vor, dass ein Benutzer einen neuen Eintrag anlegt, der schon l&auml;ngst vorhanden ist.<\/p>\n<p>Wenn Sie f&uuml;r das entsprechende Feld der Lookuptabelle einen eindeutigen Index anlegen, meckert Access automatisch, wenn der Benutzer einen neuen Wert anlegt, der bereits vorliegt. Das gleiche gilt f&uuml;r den Fall, dass ein Benutzer einen Eintrag aus der Lookuptabelle l&ouml;schen m&ouml;chte, der bereits mit einem oder mehreren Datens&auml;tzen der verkn&uuml;pften Tabelle in Beziehung steht.<\/p>\n<p>Damit Access keine seiner Fehlermeldungen auf den Weg schickt, sondern der Benutzer eine von uns selbst festgelegte und m&ouml;glcherweise verst&auml;ndlichere Meldung erh&auml;lt, legen wir f&uuml;r das Unterformular eine Prozedur an, die durch das Ereignis <b>Bei Fehler <\/b>ausgel&ouml;st wird. Die Prozedur sieht wie in Listing 3 aus.<\/p>\n<p class=\"kastentabelleheader\">Listing 3: Abfangen von Fehlern, die durch das Hinzuf&uuml;gen doppelter Eintr&auml;ge oder das L&ouml;schen verkn&uuml;pfter Datens&auml;tze entstehen<\/p>\n<pre>Private Sub Form_Error(DataErr As Integer, Response As Integer)\r\n    Select Case DataErr\r\n        Case 3022\r\n            MsgBox &quot;Der Wert ''&quot; &amp; Me.txtValue &amp; &quot;'' ist bereits vorhanden.&quot;, _\r\n            vbOKOnly + vbExclamation, &quot;Doppelte Eingabe&quot;\r\n            Me.Undo\r\n            Response = acDataErrContinue\r\n        Case 3200\r\n            MsgBox &quot;Der Wert ''&quot; &amp; Me.txtValue &amp; &quot;'' kann nicht gel&ouml;scht werden, da er bereits mit\r\n            anderen Daten verkn&uuml;pft ist.&quot;, vbOKOnly + vbExclamation, &quot;L&ouml;schen nicht m&ouml;glich&quot;\r\n            Response = acDataErrContinue\r\n    End Select\r\nEnd Sub<\/pre>\n<p>Im Falle eines Fehlers liefert der Parameter <b>DataErr <\/b>die Fehlernummer, die wir innerhalb einer <b>Select Case<\/b>-Bedingung behandeln. Die Fehlernummer <b>3022 <\/b>steht f&uuml;r den Fehler, der durch das Hinzuf&uuml;gen bereits vorhandener Daten in eine eindeutiges Feld ausgel&ouml;st wird. Wir liefern dem Benutzer eine entsprechende Fehlermeldung und sorgen durch R&uuml;ckgabe des Wertes <b>acDataErrContinue <\/b>daf&uuml;r, dass die Ausgabe der eigentlichen Fehlermeldung unterbleibt. Au&szlig;erdem l&ouml;schen wir mit der <b>Undo<\/b>-Methode des Formulars die Eingabe des Benutzers.<\/p>\n<p>Beim Versuch, bereits verkn&uuml;pfte Datens&auml;tze zu l&ouml;schen, l&ouml;st Access Fehler <b>3200 <\/b>aus &#8211; zumindest dann, wenn f&uuml;r die Beziehung zwischen Haupt- und Lookuptabelle referentielle Integrit&auml;t definiert ist. Auch diesen Fehler behandelt die Prozedur entsprechend.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Mit der L&ouml;sung aus diesem Beitrag k&ouml;nnen Sie leicht eigene Lookupformulare mit Leben f&uuml;llen. Wer mehr als drei Felder der Lookuptabelle bearbeiten k&ouml;nnen m&ouml;chte, f&uuml;gt einfach weitere Felder zum Unterformular hinzu und passt den Code entsprechend an. Eine nette Aufgabe w&auml;re es, auch andere Steuerelementtypen wie Kombinationsfelder oder Kontrollk&auml;stchen zu realisieren.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Lookupformulare.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{DF9E186D-8EAC-41DF-88CF-9C86404E90D1}\/aiu_722.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lookuptabellen speichern meist Werte, die zum Vermeiden von Redundanzen und Inkonsistenzen aus einer anderen Tabelle ausgelagert wurden. Die Formulare f&uuml;r ihre Bearbeitung sehen meist gleich aus: Ein Hauptformular mit einer OK-Schaltfl&auml;che, ein Unterformular mit den Daten &#8211; das war es. Solche Formulare braucht man nicht f&uuml;r jede dieser Tabellen einzurichten: Es reicht ein einziges, dem Sie nur noch mitteilen, aus welcher Tabelle oder Abfrage die angezeigten Felder stammen sollen.<\/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":[662010,66032010,44000023],"tags":[],"class_list":["post-55000722","post","type-post","status-publish","format-standard","hentry","category-662010","category-66032010","category-Mit_Formularen_arbeiten"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Standard-Lookupformulare - 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\/StandardLookupformulare\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Standard-Lookupformulare\" \/>\n<meta property=\"og:description\" content=\"Lookuptabellen speichern meist Werte, die zum Vermeiden von Redundanzen und Inkonsistenzen aus einer anderen Tabelle ausgelagert wurden. Die Formulare f&uuml;r ihre Bearbeitung sehen meist gleich aus: Ein Hauptformular mit einer OK-Schaltfl&auml;che, ein Unterformular mit den Daten - das war es. Solche Formulare braucht man nicht f&uuml;r jede dieser Tabellen einzurichten: Es reicht ein einziges, dem Sie nur noch mitteilen, aus welcher Tabelle oder Abfrage die angezeigten Felder stammen sollen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T22:13:08+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg01.met.vgwort.de\/na\/bed4011bd6d04fea8df6ed5f15a4e6fc\" \/>\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=\"13\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Standard-Lookupformulare\",\"datePublished\":\"2020-05-22T22:13:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/\"},\"wordCount\":2074,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/bed4011bd6d04fea8df6ed5f15a4e6fc\",\"articleSection\":[\"2010\",\"3\\\/2010\",\"Mit Formularen arbeiten\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/\",\"name\":\"Standard-Lookupformulare - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/bed4011bd6d04fea8df6ed5f15a4e6fc\",\"datePublished\":\"2020-05-22T22:13:08+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/bed4011bd6d04fea8df6ed5f15a4e6fc\",\"contentUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/bed4011bd6d04fea8df6ed5f15a4e6fc\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/StandardLookupformulare\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Standard-Lookupformulare\"}]},{\"@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":"Standard-Lookupformulare - 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\/StandardLookupformulare\/","og_locale":"de_DE","og_type":"article","og_title":"Standard-Lookupformulare","og_description":"Lookuptabellen speichern meist Werte, die zum Vermeiden von Redundanzen und Inkonsistenzen aus einer anderen Tabelle ausgelagert wurden. Die Formulare f&uuml;r ihre Bearbeitung sehen meist gleich aus: Ein Hauptformular mit einer OK-Schaltfl&auml;che, ein Unterformular mit den Daten - das war es. Solche Formulare braucht man nicht f&uuml;r jede dieser Tabellen einzurichten: Es reicht ein einziges, dem Sie nur noch mitteilen, aus welcher Tabelle oder Abfrage die angezeigten Felder stammen sollen.","og_url":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T22:13:08+00:00","og_image":[{"url":"http:\/\/vg01.met.vgwort.de\/na\/bed4011bd6d04fea8df6ed5f15a4e6fc","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"13\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Standard-Lookupformulare","datePublished":"2020-05-22T22:13:08+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/"},"wordCount":2074,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/bed4011bd6d04fea8df6ed5f15a4e6fc","articleSection":["2010","3\/2010","Mit Formularen arbeiten"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/","url":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/","name":"Standard-Lookupformulare - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/bed4011bd6d04fea8df6ed5f15a4e6fc","datePublished":"2020-05-22T22:13:08+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/#primaryimage","url":"http:\/\/vg01.met.vgwort.de\/na\/bed4011bd6d04fea8df6ed5f15a4e6fc","contentUrl":"http:\/\/vg01.met.vgwort.de\/na\/bed4011bd6d04fea8df6ed5f15a4e6fc"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/StandardLookupformulare\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Standard-Lookupformulare"}]},{"@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\/55000722","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=55000722"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000722\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000722"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000722"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000722"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}