{"id":55001200,"date":"2019-08-01T00:00:00","date_gmt":"2020-05-13T20:55:55","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1200"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Autocomplete_in_Textfeldern","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/","title":{"rendered":"Autocomplete in Textfeldern"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg06.met.vgwort.de\/na\/171bd0632ef84681971ded6378a4d5e9\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Autocomplete kennen Sie vermutlich von Kombinationsfeldern. Hier k&ouml;nnen Sie einen oder mehrere Buchstaben eingeben und das Kombinationsfeld zeigt gleich den n&auml;chsten Eintrag der Datensatzherkunft an, der mit diesen Anfangsbuchstaben beginnt. Dieses Verhalten wollen wir auch gern f&uuml;r Textfelder programmieren. Dazu starten wir mit einer etwas einfacheren Variante, die Sie vielleicht vom VBA-Editor kennen: Wenn Sie dort beginnen, einen Objekt- oder Variablennamen zu schreiben, k&ouml;nnen Sie mit der Tastenkombination Strg + Leertaste daf&uuml;r sorgen, dass IntelliSense aktiviert wird und passende Eintr&auml;ge anzeigt. Wir wollen daf&uuml;r sorgen, dass an dieser Stelle einfach der erste passende Eintrag erscheint &#8211; wenn wir eine Liste der verf&uuml;gbaren Eintr&auml;ge wollten, k&ouml;nnten wir ja direkt ein Kombinationsfeld verwenden.<\/b><\/p>\n<h2>Autocomplete per Tastenkombination<\/h2>\n<p>Im VBA-Editor verwendet man die Tastenkombination <b>Strg + Leertaste<\/b>, um beispielsweise Klassen oder Variablen anzuzeigen, die mit den bisher eingetippten Buchstaben beginnen. Wenn Sie etwa im Direktfenster die Buchstaben <b>Curr <\/b>eingeben und dann diese Tastenkombination verwenden, erscheint die Liste aus Bild 1 zur Auswahl. <\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_1200_001.png\" alt=\"Autocomplete per Intellisense im VBA-Editor\" width=\"549,6265\" height=\"229,0968\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Autocomplete per Intellisense im VBA-Editor<\/span><\/b><\/p>\n<p>Was f&uuml;r ein Verhalten wollen wir bei dieser ersten Technik erhalten und welche Voraussetzungen m&uuml;ssen daf&uuml;r erf&uuml;llt sein Die Voraussetzung ist, dass das Textfeld an ein Feld einer Tabelle gebunden ist, aus dem wir die m&ouml;glichen zu erg&auml;nzenden Texte gewinnen k&ouml;nnen.<\/p>\n<p>Dann wollen wir dem Benutzer erm&ouml;glichen, einen oder mehrere Buchstaben einzugeben und dann mit der Tastenkombination <b>Strg + Leertaste <\/b>den n&auml;chsten passenden Eintrag zu erg&auml;nzen &#8211; so, dass die erg&auml;nzten Buchstaben markiert sind. Wenn wir also etwa in ein Textfeld, das an das Feld <b>Artikelname <\/b>der Tabelle <b>tblArtikel <\/b>gebunden ist, die Zeichenkette <b>Ch <\/b>eingeben und dann <b>Strg + Leertaste <\/b>bet&auml;tigen, soll die Zeichenkette zu <b>Chai <\/b>erg&auml;nzt werden, wobei die erg&auml;nzten Buchstaben markiert sein sollen. Die Einf&uuml;gemarke soll sich dabei hinter dem zuletzt eingegebenen Buchstaben befinden und vor dem ersten Buchstaben der Markierung (siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_1200_002.png\" alt=\"Autocomplete im Textfeld\" width=\"424,7115\" height=\"190,6186\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Autocomplete im Textfeld<\/span><\/b><\/p>\n<p>Das weitere Verhalten h&auml;ngt davon ab, was der Benutzer als n&auml;chstes macht. Hier ist die Auswahl der m&ouml;glichen Schritte:<\/p>\n<ul>\n<li>Verlassen des Textfeldes: aktueller Text inklusive markiertem, vorgeschlagenem Text wird behalten<\/li>\n<li>Bet&auml;tigen der <b>Nach links<\/b>&#8211; oder <b>Nach rechts<\/b>-Taste beziehungsweise der Tasten <b>Pos1 <\/b>oder <b>Ende<\/b>: aktueller Text wird behalten, Markierung wird aufgehoben<\/li>\n<li>Bet&auml;tigen der <b>Zur&uuml;ck<\/b>-Taste: Markierter Text wird gel&ouml;scht.<\/li>\n<li>Eingabe eines anderen Zeichens als des ersten Zeichens der Markierung: Suche nach einem passenden Eintrag und Anzeige der erg&auml;nzenden Zeichen mit Markierung<\/li>\n<li>Eingabe des n&auml;chsten Zeichens der Markierung: Zeichen wird &uuml;bernommen, die restlichen Zeichen bleiben markiert<\/li>\n<\/ul>\n<h2>Tastenkombination abfangen<\/h2>\n<p>Die erste Aufgabe ist, die Tastenkombination <b>Strg + Leertaste <\/b>abzufangen. Wir schauen in einem Kombinationsfeld, wann die Erg&auml;nzung stattfindet &#8211; beim Niederdr&uuml;cken der Taste oder beim Loslassen der Taste. Das Ergebnis ist: Die Erg&auml;nzung erfolgt bereits beim Herunterdr&uuml;cken der Taste. Also verwenden wir das Ereignis <b>Bei Taste ab <\/b>des Textfeldes, das wir in unserem Beispiel <b>txtArtikelname <\/b>genannt haben. <\/p>\n<p>Dazu w&auml;hlen wir im Eigenschaftenblatt f&uuml;r das Ereignis <b>Bei Taste ab <\/b>den Eintrag <b>[Ereignisprozedur] <\/b>aus und klicken dann auf die Schaltfl&auml;che mit den drei Punkten (<b>&#8230;<\/b>) neben dem Eigenschaftsfeld.<\/p>\n<p>Dies legt im Klassenmodul des Formulars die folgende leere Prozedur an:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtArtikelname_KeyDown(KeyCode<span style=\"color:blue;\"> As Integer<\/span>,  Shift<span style=\"color:blue;\"> As Integer<\/span>)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Um zu ermitteln, welche Werte die Parameter <b>KeyCode <\/b>und <b>Shift <\/b>beim Bet&auml;tigen der Tastenkombination <b>Strg + Leertaste <\/b>liefern, geben wir diese innerhalb der Prozedur mit der folgenden Anweisung im Direktfenster aus:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> KeyCode, Shift<\/pre>\n<p>Danach wechseln wir in die Formularansicht, setzen den Fokus in das Textfeld <b>txtArtikel <\/b>und geben die Tastenkombination <b>Strg + Leertaste <\/b>ein. Das Ergebnis ist, dass <b>KeyCode <\/b>den Wert <b>32 <\/b>und <b>Shift <\/b>den Wert <b>2 <\/b>liefert (<b>32 <\/b>entspricht auch der Konstanten <b>vbKeySpace<\/b>, <b>2 <\/b>der Konstanten <b>acCtrlMask<\/b>).<\/p>\n<p>Damit k&ouml;nnen wir schon eine Bedingung in das Ereignis einbauen, unter der wir aktiv werden wollen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtArtikelname_KeyDown(KeyCode<span style=\"color:blue;\"> As Integer<\/span>,  Shift<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">If <\/span>KeyCode = vbKeySpace And Shift = acCtrlMask<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Action!\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Danach gehen wir an die Umsetzung der ersten Aufgabe. Das Ergebnis sieht wie in Listing 1 aus. Die Prozedur verwendet drei Variablen. <b>intPosStart <\/b>speichert die Position der Eingabemarke zwischen und <b>strTreffer <\/b>eventuell gefundene Treffer. <b>strText <\/b>speichert den beim Bet&auml;tigen der Taste im Textfeld vorhandenen Text.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtArtikelname_KeyDown(KeyCode<span style=\"color:blue;\"> As Integer<\/span>, Shift<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>intSelStart<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strTreffer<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strText<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">If <\/span>KeyCode = vbKeySpace And Shift = acCtrlMask<span style=\"color:blue;\"> Then<\/span>\r\n         intSelStart = Me!txtArtikelname.SelStart\r\n         strText = Me!txtArtikelname.Text\r\n         strTreffer = Nz(DLookup(\"Artikelname\", \"tblArtikel\", \"Artikelname LIKE ''\" & strText & \"*''\"), strText)\r\n         Me!txtArtikelname.Text = strTreffer\r\n         Me!txtArtikelname.SelStart = intSelStart\r\n         Me!txtArtikelname.SelLength = 255\r\n         KeyCode = 0\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Automatisches Erg&auml;nzen bei Strg + Leertaste<\/span><\/b><\/p>\n<p>Nach dem Pr&uuml;fen der Tastenkombination speichert die Prozedur die aktuelle Position der Einf&uuml;gemarke in der Variablen <b>intSelStart <\/b>und den aktuellen Text in <b>strText<\/b>. Dann sucht sie mit der <b>DLookup<\/b>-Funktion in der zugrunde liegenden Tabelle nach einem Wert, der mit den Zeichen aus <b>strText <\/b>beginnt.<\/p>\n<p>Findet sie einen solchen Wert, wird dieser in <b>strTreffer <\/b>geschrieben, sonst landet der zweite Parameter der <b>Nz<\/b>-Funktion als Ergebnis in <b>strTreffer <\/b>&#8211; in diesem Fall der vorherige Inhalt des Textfeldes aus <b>strText<\/b>.<\/p>\n<p>Danach folgt die Aktualisierung des Textfeldes. Dabei weisen wir der Eigenschaft <b>Text <\/b>den Inhalt von <b>strTreffer <\/b>zu und setzen die Eingabemarke &uuml;ber die Eigenschaft <b>SelStart <\/b>auf die vorherige Position, also <b>intSelStart<\/b>. Au&szlig;erdem stellen wir die Eigenschaft <b>SelLength <\/b>auf den Wert <b>255 <\/b>ein, was der gr&ouml;&szlig;ten Zeichenkette entspricht, die wir in dieses Textfeld eingeben k&ouml;nnen. Damit markieren wir schlicht den Text von der Position der Einf&uuml;gemarke aus bis zum Schluss.<\/p>\n<p>Danach folgt noch eine wichtige Anweisung (<b>KeyCode = 0<\/b>). Diese sorgt daf&uuml;r, dass die eingegebene Taste nicht an das Textfeld geschickt wird. Ohne diese Anweisung w&uuml;rde die Prozedur zwar wie gew&uuml;nscht funktionieren, aber durch das anschlie&szlig;ende Senden des Leerzeichens an das Textfeld w&uuml;rde der markierte Bereich wieder gel&ouml;scht und durch das Leerzeichen &uuml;berschrieben werden.<\/p>\n<p>Damit haben wir aber nur den Beginn gemacht. Nun kommen wir an den Punkt, wo der Benutzer das n&auml;chste Zeichen eingibt, eines l&ouml;scht, die Einf&uuml;gemarke mit den Tasten <b>Nach links<\/b>, <b>Nach rechts<\/b>, <b>Pos1<\/b> oder <b>Ende<\/b> bewegt oder das Feld verl&auml;sst.<\/p>\n<h2>Einschr&auml;nkung: Einf&uuml;gemarke nicht hinter dem letzten Zeichen<\/h2>\n<p>An dieser Stelle wollen wir uns bereits um eine kleine Einschr&auml;nkung k&uuml;mmern: Der zuvor beschriebene Ablauf soll nicht durchgef&uuml;hrt werden, wenn der Benutzer die Tastenkombination <b>Strg + Leerzeichen <\/b>bet&auml;tigt, w&auml;hrend die Einf&uuml;gemarke sich nicht am Ende des bisher eingegebenen Textes befindet. Wir m&uuml;ssen also noch eine Pr&uuml;fung der Position der Einf&uuml;gemarke bezogen auf den vorhandenen Text hinzuf&uuml;gen. Diese f&uuml;gen wir hinter den beiden Anweisungen zur Ermittlung der Startposition der Markierung und des Textes ein und pr&uuml;fen, ob <b>intSelStart <\/b>genau der L&auml;nge des eingegebenen Textes entspricht &#8211; was bedeutet, dass die Einf&uuml;gemarke sich hinter dem letzten Zeichen befindet:<\/p>\n<pre>---\r\nstrText = Me!txtArtikelname.Text\r\n<span style=\"color:blue;\">If <\/span>intSelStart = <span style=\"color:blue;\">Len<\/span>(strText)<span style=\"color:blue;\"> Then<\/span>\r\n     ...\r\n<span style=\"color:blue;\">End If<\/span>\r\nKeyCode = 0\r\n...<\/pre>\n<h2>Verlassen des Feldes mit Autocomplete<\/h2>\n<p>Wenn der Benutzer mit <b>Strg + Leertaste <\/b>Autocomplete aktiviert und gegebenenfalls eine Erg&auml;nzung hinzugef&uuml;gt hat und dann das Feld beispielsweise mit der Tabulator-Taste oder durch einen Mausklick auf ein anderes Steuer-element verl&auml;sst, soll der enthaltene Text inklusive des markierten Teils beibehalten werden.<\/p>\n<p>F&uuml;r dieses Verhalten brauchen wir gar nichts zu tun &#8211; es ist bereits implementiert.<\/p>\n<h2>Bewegen der Einf&uuml;gemarke<\/h2>\n<p>Die Einf&uuml;gemarke kann der Benutzer bei markiertem Text auf verschiedene Arten bewegen &#8211; zum Beispiel auf die folgenden:<\/p>\n<ul>\n<li><b>Nach links<\/b>-Taste: Bewegt die Einf&uuml;gemarke um eine Position nach links.<\/li>\n<li><b>Nach rechts<\/b>-Taste: Bewegt die Einf&uuml;gemarke um eine Position nach rechts.<\/li>\n<li><b>Pos1<\/b>-Taste: Bewegt die Einf&uuml;gemarke an die erste Position.<\/li>\n<li><b>Ende<\/b>-Taste: Bewegt die Einf&uuml;gemarke an die letzte Position.<\/li>\n<\/ul>\n<p>Wichtig ist an dieser Stelle, dass diese Bewegungen keine &Auml;nderungen am Text vornehmen.<\/p>\n<p>Wir wollen das Verhalten wie bei der Autocomplete-Funktion von Kombinationsfeldern abbilden. Dort wird bei Bet&auml;tigung dieser Tasten die &uuml;bliche Funktion ausgef&uuml;hrt und die Markierung im Text wird entfernt.<\/p>\n<p>Und auch hier bekommen wir das gew&uuml;nschte Verhalten wieder frei Haus geliefert &#8211; es ist bereits implementiert.<\/p>\n<h2>Bet&auml;tigen der Zur&uuml;ck- und der Entf-Taste<\/h2>\n<p>Sie ahnen es bereits: Auch hier brauchen Sie nichts zu tun. Wenn Sie die <b>Zur&uuml;ck<\/b>&#8211; oder die <b>Entf<\/b>-Taste bet&auml;tigen, w&auml;hrend der hintere Teil des Textes markiert ist, wird der markierte Text einfach gel&ouml;scht.<\/p>\n<h2>Eingabe weiterer Zeichen<\/h2>\n<p>Nun wird es allerdings wieder interessant: Wenn der Benutzer ein weiteres Zeichen eingibt, gibt es zwei M&ouml;glichkeiten:<\/p>\n<ul>\n<li>Das Zeichen entspricht dem ersten Zeichen der Markierung. Dann soll dieses Zeichen aus der Markierung herausgenommen werden und die &uuml;brigen in der Markierung enthaltenen Zeichen sollen weiterhin markiert bleiben.<\/li>\n<li>Das Zeichen entspricht nicht dem ersten Zeichen der Markierung. Dann soll die Prozedur eine neue Suche starten, wobei der erste, nicht markierte Teil des Textes im Textfeld plus dem soeben eingegebenen Zeichen als Suchbegriff verwendet wird.<\/li>\n<\/ul>\n<p><!--30percent--><\/p>\n<p>Wir schauen uns erst den Fall an, dass der Benutzer das erste Zeichen der Markierung eingegeben hat. In diesem Fall wollen wir wissen, welches Zeichen der Benutzer eingegeben hat und dieses dann mit dem ersten Zeichen der Markierung vergleichen.<\/p>\n<h2>KeyCode, Shift und Ascii<\/h2>\n<p>Das ist mit den Parametern <b>KeyCode <\/b>und <b>Shift<\/b>, die wir von der Ereignisprozedur geliefert bekommen, nicht so einfach &#8211; zumindest dann nicht, wenn es sich bei den Zeichen nicht um Buchstaben oder Zahlen handelt. Wenn Sie beispielsweise ein kleines <b>a <\/b>eingeben, liefert <b>KeyCode <\/b>den Wert <b>65<\/b>. Wenn Sie ein gro&szlig;es <b>A <\/b>eingeben, also <b>Umschalt + a<\/b>, liefert <b>KeyCode <\/b>ebenfalls den Wert <b>65<\/b>. Zus&auml;tzlich liefert <b>Shift <\/b>den Wert <b>1<\/b>, also <b>acShiftMask<\/b>. Der Ascii-Wert f&uuml;r das gro&szlig;e <b>A <\/b>ist jedoch <b>65<\/b>, f&uuml;r das kleine <b>a <\/b>lautet er <b>97<\/b>. Die Ascii-Werte f&uuml;r Zeichen ermitteln Sie mit der <b>Asc<\/b>-Funktion:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> Asc(\"a\")\r\n97<\/pre>\n<p>Bei den Buchstaben ist das kein Problem: Wir k&ouml;nnten dann in einer kleinen Funktion pr&uuml;fen, ob <b>Shift <\/b>den Wert <b>acShiftMask<\/b> liefert. Ist das der Fall, entspricht der Wert von <b>KeyCode <\/b>dem Ascii-Wert <b>65<\/b>. Ist <b>Shift <\/b>nicht gleich <b>acShiftMask<\/b>, m&uuml;ssen wir zum Wert von <b>KeyCode <\/b>die Zahl <b>32 <\/b>hinzu addieren. <\/p>\n<p>Das funktioniert so f&uuml;r alle Buchstaben. Dann schauen wir uns weitere g&auml;ngige Zeichen an, die in Textfeldern verwendet werden &#8211; zum Beispiel das Minus-Zeichen, das gern als Bindestrich verwendet wird. Die <b>Asc<\/b>-Funktion liefert daf&uuml;r:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> Asc(\"-\")\r\n  45 <\/pre>\n<p><b>KeyCode <\/b>liefert allerdings den Wert <b>189<\/b>. Damit w&uuml;rde die Funktion zum &Uuml;bersetzen von <b>KeyCode <\/b>in Ascii schon umfangreicher werden. Genau genommen m&uuml;ssten wir damit alle Zeichen &uuml;bersetzen, da wir ja nie wissen, welche Zeichen der Benutzer ben&ouml;tigt.<\/p>\n<p>Allerdings gibt es noch eine Alternative: die Ereignisprozedur <b>Bei Taste<\/b>. Die sieht im leeren Zustand f&uuml;r unser Textfeld <b>txtArtikelname <\/b>wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtArtikelname_KeyPress(KeyAscii<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> KeyAscii\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Der hier verwendete Parameter <b>KeyAscii <\/b>liefert genau die gleichen Werte, die auch die <b>Asc<\/b>-Funktion zur&uuml;ckgibt. Damit k&ouml;nnten wir also f&uuml;r die weiterf&uuml;hrende Eingabe von Zeichen arbeiten.<\/p>\n<h2>Zeichen mit dem Bei Taste-Ereignis untersuchen<\/h2>\n<p>Aber wenn wir nun eine weitere Ereignisprozedur hinzunehmen, um die Eingabe regul&auml;rer Zeichen zu untersuchen &#8211; macht es dann Sinn, die Pr&uuml;fung auf <b>Strg + Leerzeichen <\/b>in der Ereignisprozedur <b>Bei Taste ab <\/b>zu belassen Und kommen sich die beiden Prozeduren dann nicht ins Gehege, weil die <b>Bei Taste<\/b>-Ereignisprozedur auch nochmal auf <b>Strg + Leertaste <\/b>reagiert<\/p>\n<p>Ja, es macht Sinn, denn die beiden Ereignisprozeduren kommen sich bei Eingabe der Tastenkombination <b>Strg + Leertaste <\/b>nicht ins Gehege. Genau genommen wird das Ereignis <b>Bei Taste <\/b>durch diese Tastenkombination &uuml;berhaupt nicht ausgel&ouml;st. Also arbeiten wir zun&auml;chst mit dem Ereignis <b>Bei Taste <\/b>weiter.<\/p>\n<p>Die entsprechende Ereignisprozedur f&uuml;llen wir wie folgt:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtArtikelname_KeyPress(KeyAscii<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>intSelStart<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intSelLength<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strText<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strNaechster<span style=\"color:blue;\"> As String<\/span>\r\n     intSelStart = Me!txtArtikelname.SelStart\r\n     intSelLength = Me!txtArtikelname.SelLength\r\n     strText = Me!txtArtikelname.Text\r\n     <span style=\"color:blue;\">If <\/span>intSelLength &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         strNaechster = <span style=\"color:blue;\">Mid<\/span>(strText, intSelStart + 1, 1)\r\n         <span style=\"color:blue;\">If <\/span>KeyAscii = Asc(strNaechster)<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">With<\/span> Me!txtArtikelname\r\n                 .Text = strText\r\n                 .SelStart = intSelStart + 1\r\n                 .SelLength = 255\r\n             End <span style=\"color:blue;\">With<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Der Plan ist prinzipiell gut: Wir erfassen wieder die Position der Markierung und die L&auml;nge der Markierung sowie den gesamten Text. Dann pr&uuml;fen wir, ob es eine Markierung mit mehr als <b>0 <\/b>Zeichen gibt. Ist das der Fall, ermitteln wir den ersten Buchstaben der Markierung und tragen diesen in die Variable <b>strNaechster <\/b>ein.<\/p>\n<p>Wenn <b>KeyAscii <\/b>dem Ascii-Wert von <b>strNaechster <\/b>entspricht, hat der Benutzer genau das n&auml;chste Zeichen eingegeben. Dann schreiben wir den Text aus strText zur&uuml;ck in das Textfeld, lassen die Markierung gegen&uuml;ber der vorherigen Markierung um ein Zeichen weiter hinten beginnen. Au&szlig;erdem soll die Markierung auch wieder bis zum Ende der Zeichenkette gehen. <\/p>\n<p>Allerdings haben wir die Rechnung gemacht, ohne zu ber&uuml;cksichtigen, das nach Abschluss der Ereignisprozedur auch das eingegebene Zeichen noch in das Textfeld geschrieben wird. Hilft auch hier das Einstellen des Parameters auf den Wert <b>0 <\/b>wie es auch schon beim Parameter <b>KeyCode <\/b>der Ereignisprozedur f&uuml;r <b>Bei Taste ab <\/b>war H&auml;ngen wir die Anweisung doch einfach noch hinten an:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtArtikelname_KeyPress(KeyAscii<span style=\"color:blue;\"> As Integer<\/span>)\r\n     ...\r\n     <span style=\"color:blue;\">If <\/span>intSelLength &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         If ...\r\n             ...\r\n             KeyAscii = 0\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Damit erhalten wir das gew&uuml;nschte Ergebnis. Bild 3 zeigt, wie es nun abl&auml;uft: Wenn wir etwa die beiden Buchstaben <b>Ch <\/b>eingeben und dann auf <b>Strg + Leertaste <\/b>dr&uuml;cken, werden die beiden Buchstaben <b>ai <\/b>erg&auml;nzt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_1200_003.png\" alt=\"Autocomplete im Praxiseinsatz\" width=\"424,7115\" height=\"438,7904\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Autocomplete im Praxiseinsatz<\/span><\/b><\/p>\n<p>Geben wir dann den Buchstaben <b>a <\/b>ein, wird dieser &uuml;bernommen und nur noch das <b>i <\/b>befindet sich in der Markierung. Auf die gleiche Weise k&ouml;nnen wir nun auch noch das <b>i <\/b>erg&auml;nzen, sodass die Markierung komplett verschwindet.<\/p>\n<h2>Wenn der Benutzer ein anderes Zeichen eingibt<\/h2>\n<p>Im Gegensatz dazu steht der Fall, dass der Benutzer statt des Buchstabens <b>i <\/b>am Ende den Buchstaben <b>n <\/b>eingibt, sodass dort <b>Chan <\/b>steht. Die Autocomplete-Funktion soll dann erneut nach einem passenden Eintrag in der zugrunde liegenden Tabelle suchen, der in diesem Fall <b>Chang <\/b>lauten w&uuml;rde.<\/p>\n<p>Dazu f&uuml;gen wir der inneren <b>If&#8230;Then<\/b>-Bedingung einen <b>Else<\/b>-Zweig hinzu:<\/p>\n<pre>...\r\n<span style=\"color:blue;\">Else<\/span>\r\n     strText = <span style=\"color:blue;\">Left<\/span>(strText, intSelStart) & Chr(KeyAscii)\r\n     strTreffer = Nz(DLookup(\"Artikelname\", \"tblArtikel\",  \"Artikelname LIKE ''\" & strText & \"*''\"), strText)\r\n     <span style=\"color:blue;\">With<\/span> Me!txtArtikelname\r\n         .Text = strTreffer\r\n         .SelStart = intSelStart + 1\r\n         .SelLength = 255\r\n     End <span style=\"color:blue;\">With<\/span>\r\n     KeyAscii = 0\r\n<span style=\"color:blue;\">End If<\/span>\r\n...<\/pre>\n<p>Dieser stellt zun&auml;chst einen neuen Basistext zusammen, und zwar aus dem nicht markierten Teil des Textes, in unserem Beispiel <b>Cha<\/b>, und dem neu eingegebenen Buchstaben <b>n<\/b>. <b>strText <\/b>enth&auml;lt dann die Zeichenkette <b>Chan<\/b>. Damit durchsuchen wir mit der <b>DLookup<\/b>-Funktion, die wir erstmal aus der Ereignisprozedur <b>Bei Taste ab <\/b>&uuml;bernehmen, erneut das Feld <b>Artikelname <\/b>der Tabelle <b>tblArtikel<\/b>. Mit dem Ergebnis <b>Chang <\/b>f&uuml;llen wir dann das Textfeld und stellen die Markierung so ein, dass diese hinter dem zuletzt eingegebenen Zeichen beginnt und bis zum Ende des Textes reicht. Auch hier sorgen wir mit <b>KeyAscii = 0 <\/b>daf&uuml;r, dass das eingegebene Zeichen nicht mehr in das Textfeld geschrieben wird. Das Ergebnis finden Sie in Bild 4.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_1200_004.png\" alt=\"Vorschlag f&uuml;r einen anderen Artikelnamen\" width=\"424,7115\" height=\"219,3952\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Vorschlag f&uuml;r einen anderen Artikelnamen<\/span><\/b><\/p>\n<h2>Wenn kein Treffer gefunden wird &#8230;<\/h2>\n<p>Wenn wir nun an der vorherigen Stelle kein <b>n <\/b>eingeben, sondern beispielsweise ein <b>x<\/b>, sodass der aktuelle Inhalt des Textfeldes <b>Chax <\/b>lautet, sollte die <b>DLookup<\/b>-Funktion keinen Eintrag finden. In diesem Fall verwendet sie dann den bisherigen Wert f&uuml;r <b>strText <\/b>als Ergebnis.<\/p>\n<p>Das funktioniert auch f&uuml;r alle Zeichen wie gew&uuml;nscht, aber nicht, wenn wir beispielsweise das Leerzeichen eingeben. In diesem Fall wird zwar der markierte Teil des Textes gel&ouml;scht, aber es wird kein Leerzeichen ausgegeben (siehe Bild 5).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_1200_005.png\" alt=\"Ein eingetipptes Leerzeichen l&ouml;scht zwar den markierten Text, aber wird selbst nicht ausgegeben.\" width=\"424,7115\" height=\"380,1286\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Ein eingetipptes Leerzeichen l&ouml;scht zwar den markierten Text, aber wird selbst nicht ausgegeben.<\/span><\/b><\/p>\n<p>Wenn wir den relevanten Teil der Prozedur <b>txtArtikelname_KeyPress <\/b>debuggen, f&auml;llt uns auf, dass zwar strText noch den Text bis zur Einf&uuml;gemarke plus das Leerzeichen enth&auml;lt, aber nach der Zuweisung an die Eigenschaft <b>Text <\/b>des Textfeldes fehlt das Leerzeichen.<\/p>\n<p>Offensichtlich liegt es daran, dass Access Leerzeichen am Ende einer in ein Textfeld eingegebenen Zeichenkette einfach k&uuml;rzt. Das ist in diesem Fall nat&uuml;rlich ung&uuml;nstig, da der Benutzer ja offensichtlich m&ouml;chte, dass an dieser Stelle des Textes ein Leerzeichen erscheint &#8211; zum Beispiel, um zwei durch ein Leerzeichen getrennte W&ouml;rter einzugeben. Also m&uuml;ssen wir im <b>Else<\/b>-Teil der Prozedur pr&uuml;fen, ob der Benutzer ein Leerzeichen eingegeben hat. Ist das der Fall, brauchen wir <b>Keyascii <\/b>nicht auf <b>0 <\/b>einzustellen.<\/p>\n<p>Dazu fassen wir diese Anweisung einfach in eine entsprechende <b>If&#8230;Then<\/b>-Bedingung ein:<\/p>\n<pre><span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> KeyAscii = 32<span style=\"color:blue;\"> Then<\/span>\r\n     KeyAscii = 0\r\n<span style=\"color:blue;\">End If<\/span><\/pre>\n<p>Damit gelingt nun auch die Eingabe von Leerzeichen.<\/p>\n<h2>Test der Funktion<\/h2>\n<p>Damit k&ouml;nnen wir nun mit der Funktion experimentieren. Zur Erinnerung: Autocomplete wird bisher nur mit <b>Strg + Leertaste <\/b>aktiviert. Dann suchen die beiden Prozeduren nach einer passenden Erg&auml;nzung. Danach k&ouml;nnen Sie durch Eingabe von passenden Buchstaben fortfahren oder mit nicht passenden Buchstaben eine neue Suche ansto&szlig;en.<\/p>\n<p>Den ersten Fehler haben wir recht leicht produzieren k&ouml;nnen, indem wir das Feld mit der Tabulator-Taste betreten. Die Prozedur <b>txtArtikelname_KeyPress <\/b>erkennt dies als den <b>KeyAscii<\/b>-Wert <b>9 <\/b>und verf&auml;hrt damit wie mit einem normalen Zeichen. Sie landet dann im <b>Else<\/b>-Teil der inneren <b>If&#8230;Then<\/b>-Bedingung und versucht, das in <b>strTreffer <\/b>gelandete Tabulator-Zeichen f&uuml;r die Eigenschaft <b>Text <\/b>des Textfeldes einzuf&uuml;gen. Dies f&uuml;hrt zum Fehler, wenn das Feld ein Pflichtfeld ist, was bei Artikelname der Fall ist.<\/p>\n<p>F&uuml;r diesen Fall schlie&szlig;en wir die &auml;u&szlig;ere <b>If&#8230;Then<\/b>-Bedingung direkt in eine <b>Select Case<\/b>-Bedingung ein, welche das Tabulator-Zeichen ausschlie&szlig;t:<\/p>\n<pre>Select Case KeyAscii\r\n     <span style=\"color:blue;\">Case <\/span>9\r\n     <span style=\"color:blue;\">Case Else<\/span>\r\n         <span style=\"color:blue;\">If <\/span>intSelLength &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n             ...\r\n         <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Select<\/span><\/pre>\n<h2>Autocomplete nicht immer aktiv<\/h2>\n<p>Die bisherige Funktion startet Autocomplete immer erst dann, wenn der Benutzer die Tastenkombination <b>Strg + Leertaste <\/b>bet&auml;tigt. Es gibt aber noch eine weitere Einstiegsm&ouml;glichkeit: Dazu muss der Benutzer selbst&auml;ndig den hinteren Teil des Feldinhalts markieren. Befindet sich die Einf&uuml;gemarke dann am Beginn der Markierung und gibt der Benutzer ein Zeichen ein, wird die Funktion auch aktiviert.<\/p>\n<p>Wir k&ouml;nnten es noch mit weiteren Bedingungen und Variablen verhindern, dass der Benutzer Autocomplete auf die zuletzt genannte Weise ausl&ouml;st. Aber es ist recht unwahrscheinlich, dass er genau dies tut, sodass wir davon absehen.<\/p>\n<h2>Performance<\/h2>\n<p>Sinnvoll ist diese Variante, wenn das Laden der Daten &uuml;ber ein Netzwerk geschieht und die Last niedrig gehalten werden soll. Man k&ouml;nnte nat&uuml;rlich auch alle Daten f&uuml;r das Feld einmalig beim &Ouml;ffnen des Formulars in ein Array oder Recordset laden, um den Datenverkehr &uuml;ber das Netzwerk auf einen Zugriff zu beschr&auml;nken. Das w&uuml;rde an dieser Stelle allerdings den Rahmen sprengen.<\/p>\n<h2>Autocomplete immer aktiv<\/h2>\n<p>Wenn Ihre Anwendung jedoch eine lokale Desktopanwendung ist oder das Netzwerk so schnell ist, dass sie sich keine Sorgen &uuml;ber ein paar zus&auml;tzliche Zugriffe auf die Datenbank machen m&uuml;ssen, k&ouml;nnen Sie auch eine Variante programmieren, bei der Autocomplete immer aktiv ist.<\/p>\n<p>Dazu legen wir eine Kopie des Formulars <b>frmAutocomplete <\/b>mit dem Namen <b>frmAutocomplete_ImmerAktiv <\/b>an. Das Ziel ist also nun, direkt bei der Eingabe des ersten Zeichens nach passenden Erg&auml;nzungen in dem an das Textfeld gebundene Feld der Datenherkunft zu suchen.<\/p>\n<p>Dazu k&ouml;nnen wir die Prozedur <b>txtArtikelname_KeyDown <\/b>entfernen, denn wir brauchen ja nicht mehr auf die Strg-Taste zu reagieren. Deshalb k&ouml;nnen wir nun alle Eingaben &uuml;ber die Prozedur <b>txtArtikelname_KeyPress<\/b> abwickeln. Die Inhalte der Prozedur k&ouml;nnen wir allerdings teilweise &uuml;bernehmen und anpassen. Das sieht im Endergebnis wie in Listing 2 aus.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtArtikelname_KeyPress(KeyAscii<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>intSelStart<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intSelLength<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strText<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strNaechster<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strTreffer<span style=\"color:blue;\"> As String<\/span>\r\n     intSelStart = Me!txtArtikelname.SelStart\r\n     intSelLength = Me!txtArtikelname.SelLength\r\n     strText = Me!txtArtikelname.Text\r\n     Select Case KeyAscii\r\n         <span style=\"color:blue;\">Case <\/span>8, 9\r\n         <span style=\"color:blue;\">Case Else<\/span>\r\n             <span style=\"color:blue;\">If <\/span>intSelStart = <span style=\"color:blue;\">Len<\/span>(strText)<span style=\"color:blue;\"> Then<\/span>\r\n                 strText = strText & Chr(KeyAscii)\r\n                 strTreffer = Nz(DLookup(\"Artikelname\", \"tblArtikel\", \"Artikelname LIKE ''\" & strText & \"*''\"), strText)\r\n                 <span style=\"color:blue;\">With<\/span> Me!txtArtikelname\r\n                     .Text = strTreffer\r\n                     .SelStart = intSelStart + 1\r\n                     .SelLength = 255\r\n                 End <span style=\"color:blue;\">With<\/span>\r\n                 KeyAscii = 0\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 strNaechster = <span style=\"color:blue;\">Mid<\/span>(strText, intSelStart + 1, 1)\r\n                 <span style=\"color:blue;\">If <\/span>KeyAscii = Asc(strNaechster)<span style=\"color:blue;\"> Then<\/span>\r\n                     <span style=\"color:blue;\">With<\/span> Me!txtArtikelname\r\n                         .Text = strText\r\n                         .SelStart = intSelStart + 1\r\n                         .SelLength = 255\r\n                     End <span style=\"color:blue;\">With<\/span>\r\n                     KeyAscii = 0\r\n                 <span style=\"color:blue;\">Else<\/span>\r\n                     strText = <span style=\"color:blue;\">Left<\/span>(strText, intSelStart) & Chr(KeyAscii)\r\n                     strTreffer = Nz(DLookup(\"Artikelname\", \"tblArtikel\", \"Artikelname LIKE ''\" & strText & \"*''\"), _\r\n                         strText)\r\n                     <span style=\"color:blue;\">With<\/span> Me!txtArtikelname\r\n                         .Text = strTreffer\r\n                         .SelStart = intSelStart + 1\r\n                         .SelLength = 255\r\n                     End <span style=\"color:blue;\">With<\/span>\r\n                     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> KeyAscii = 32<span style=\"color:blue;\"> Then<\/span>\r\n                         KeyAscii = 0\r\n                     <span style=\"color:blue;\">End If<\/span>\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: St&auml;ndig aktives Autocomplete<\/span><\/b><\/p>\n<p>Neu an der Prozedur <b>txtArtikelname_KeyPress <\/b>ist, dass wir nicht mehr pr&uuml;fen, ob <b>intSelLength > 0 <\/b>ist, also ob &uuml;berhaupt eine Markierung vorhanden ist. Stattdessen pr&uuml;fen wir, nachdem wir die drei Variablen <b>intSelStart<\/b>, <b>intSelLength <\/b>und <b>strText <\/b>wie gewohnt gef&uuml;llt haben, ob das erste Zeichen der Markierung sich am Ende des Textes befindet, also ob gar keine Markierung vorhanden ist (<b>intSelStart = Len(strText)<\/b>). Zuvor pr&uuml;fen wir zus&auml;tzlich zum Tabulator-Zeichen noch auf das Entf-Zeichen, das wir ebenfalls von der folgenden Behandlung ausklammern wollen.<\/p>\n<p>Ist also gar keine Markierung vorhanden, entspricht das im Prinzip der Situation, die wir im vorherigen Beispiel beim Bet&auml;tigen der Tastenkombination <b>Strg + Leertaste<\/b> hatten.<\/p>\n<p>Nur m&uuml;ssen wir hier nicht nur nach dem vorhandenen Text im Textfeld suchen, sondern gleich nach dem vorhandenen Text plus dem soeben eingegebenen Zeichen, also <b>strText &#038; Chr(KeyAscii) <\/b>&#8211; wir ermitteln das Zeichen &uuml;ber die <b>Chr<\/b>-Funktion aus dem Ascii-Code. Damit als Suchbegriff rufen wir dann die <b>DLookup<\/b>-Funktion auf und suchen nach passenden Erg&auml;nzungen. Diese tragen wir dann wie in den &uuml;brigen F&auml;llen in das Textfeld ein, indem wir die <b>Text<\/b>-Eigenschaft mit dem Wert aus <b>strTreffer <\/b>f&uuml;llen, <b>SelStart <\/b>auf <b>intSelStart + 1 <\/b>einstellen und <b>SelLength <\/b>auf <b>255<\/b>. Schlie&szlig;lich stellen wir auch hier <b>KeyAscii <\/b>auf den Wert <b>0 <\/b>ein, da wir das neue Zeichen ja schon zum Textfeld hinzugef&uuml;gt haben.<\/p>\n<p>Im <b>Else<\/b>-Teil der Bedingung behalten wir dann die bereits bekannten Elemente aus dem ersten Beispiel bei. Damit bekommen wir dann direkt bei Eingabe des ersten Buchstabens einen Vorschlag f&uuml;r den passenden Eintrag (siehe Bild 6).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_1200_006.png\" alt=\"Autocomplete gleich nach dem ersten Zeichen\" width=\"424,7115\" height=\"222,7428\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Autocomplete gleich nach dem ersten Zeichen<\/span><\/b><\/p>\n<h2>Weitere Tests<\/h2>\n<p>Bei den Experimenten mit dieser neuen Autocomplete-Version haben wir festgestellt, dass beispielsweise die Tastenkombination <b>Strg + Entf<\/b>, die normalerweise den kompletten Inhalt von der Einf&uuml;gemarke bis zum Beginn der Zeichenkette oder bis zum n&auml;chsten Exemplar bestimmter Zeichen wie dem Leerzeichen l&ouml;schen sollte, nur ein Sonderzeichen erzeugt (siehe Bild 7). Deshalb ermitteln wir in der Prozedur mit <b>Debug.Print KeyAscii <\/b>auch den Ascii-Code f&uuml;r dieses Zeichen, was <b>127 <\/b>ergibt. Dieses f&uuml;gen wir dann auch noch in den ersten Zweig der <b>Select Case<\/b>-Bedingung ein:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_1200_007.png\" alt=\"Sonderzeichen bei Eingabe von Strg + Entf\" width=\"424,7115\" height=\"222,7428\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Sonderzeichen bei Eingabe von Strg + Entf<\/span><\/b><\/p>\n<pre>Select Case KeyAscii\r\n     <span style=\"color:blue;\">Case <\/span>8, 9, 127\r\n     ...\r\n<span style=\"color:blue;\">End Select<\/span><\/pre>\n<p>Danach wird <b>Strg + Entf <\/b>korrekt verarbeitet. Gleiches gilt f&uuml;r die Esc-Taste, die wir mit dem Zahlencode <b>27 <\/b>unsch&auml;dlich machen.<\/p>\n<p>Interessanterweise bereitet die Verarbeitung der Tastenkombination <b>Strg + Del <\/b>keine Probleme &#8211; dies l&ouml;scht den kompletten Text von der Einf&uuml;gemarke bis zum Ende des Textes.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Damit haben wir eine sch&ouml;ne Erweiterung f&uuml;r Textfelder programmiert, die Sie zum Beispiel dort einsetzen wollen, wo gleiche Eintr&auml;ge m&ouml;glich und g&auml;ngig sind, aber diese Daten dennoch nicht beispielsweise in einer <b>Lookup<\/b>-Tabelle gespeichert werden. Praktisch ist das grunds&auml;tzlich in allen Feldern, die mit Adressen zusammenh&auml;ngen &#8211; also Vorname, Nachname, Stra&szlig;e, PLZ, Wohnort et cetera.<\/p>\n<p>In einem weiteren Beitrag namens <b>Autocomplete schnell hinzuf&uuml;gen <\/b>(<b>www.access-im-unternehmen.de\/1202<\/b>) in der n&auml;chsten Ausgabe zeigen wir, wie Sie die hier vorgestellte L&ouml;sung unkompliziert zu bestehenden Formularen hinzuf&uuml;gen k&ouml;nnen.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>AutocompleteInTextfeldern.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/29FDEE85-D0A2-4D04-8B27-21494E46E698\/aiu_1200.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Autocomplete kennen Sie vermutlich von Kombinationsfeldern. Hier k&ouml;nnen Sie einen oder mehrere Buchstaben eingeben und das Kombinationsfeld zeigt gleich den n&auml;chsten Eintrag der Datensatzherkunft an, der mit diesen Anfangsbuchstaben beginnt. Dieses Verhalten wollen wir auch gern f&uuml;r Textfelder programmieren. Dazu starten wir mit einer etwas einfacheren Variante, die Sie vielleicht vom VBA-Editor kennen: Wenn Sie dort beginnen, einen Objekt- oder Variablennamen zu schreiben, k&ouml;nnen Sie mit der Tastenkombination Strg + Leertaste daf&uuml;r sorgen, dass IntelliSense aktiviert wird und passende Eintr&auml;ge anzeigt. Wir wollen daf&uuml;r sorgen, dass an dieser Stelle einfach der erste passende Eintrag erscheint &#8211; wenn wir eine Liste der verf&uuml;gbaren Eintr&auml;ge wollten, k&ouml;nnten wir ja direkt ein Kombinationsfeld verwenden.<\/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":[662019,66042019,44000023],"tags":[],"class_list":["post-55001200","post","type-post","status-publish","format-standard","hentry","category-662019","category-66042019","category-Mit_Formularen_arbeiten"],"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>Autocomplete in Textfeldern - 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\/Autocomplete_in_Textfeldern\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Autocomplete in Textfeldern\" \/>\n<meta property=\"og:description\" content=\"Autocomplete kennen Sie vermutlich von Kombinationsfeldern. Hier k&ouml;nnen Sie einen oder mehrere Buchstaben eingeben und das Kombinationsfeld zeigt gleich den n&auml;chsten Eintrag der Datensatzherkunft an, der mit diesen Anfangsbuchstaben beginnt. Dieses Verhalten wollen wir auch gern f&uuml;r Textfelder programmieren. Dazu starten wir mit einer etwas einfacheren Variante, die Sie vielleicht vom VBA-Editor kennen: Wenn Sie dort beginnen, einen Objekt- oder Variablennamen zu schreiben, k&ouml;nnen Sie mit der Tastenkombination Strg + Leertaste daf&uuml;r sorgen, dass IntelliSense aktiviert wird und passende Eintr&auml;ge anzeigt. Wir wollen daf&uuml;r sorgen, dass an dieser Stelle einfach der erste passende Eintrag erscheint - wenn wir eine Liste der verf&uuml;gbaren Eintr&auml;ge wollten, k&ouml;nnten wir ja direkt ein Kombinationsfeld verwenden.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-13T20:55:55+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg06.met.vgwort.de\/na\/171bd0632ef84681971ded6378a4d5e9\" \/>\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=\"20\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Autocomplete in Textfeldern\",\"datePublished\":\"2020-05-13T20:55:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/\"},\"wordCount\":3690,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/171bd0632ef84681971ded6378a4d5e9\",\"articleSection\":[\"2019\",\"4\\\/2019\",\"Mit Formularen arbeiten\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/\",\"name\":\"Autocomplete in Textfeldern - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/171bd0632ef84681971ded6378a4d5e9\",\"datePublished\":\"2020-05-13T20:55:55+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/171bd0632ef84681971ded6378a4d5e9\",\"contentUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/171bd0632ef84681971ded6378a4d5e9\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Autocomplete_in_Textfeldern\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Autocomplete in Textfeldern\"}]},{\"@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":"Autocomplete in Textfeldern - 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\/Autocomplete_in_Textfeldern\/","og_locale":"de_DE","og_type":"article","og_title":"Autocomplete in Textfeldern","og_description":"Autocomplete kennen Sie vermutlich von Kombinationsfeldern. Hier k&ouml;nnen Sie einen oder mehrere Buchstaben eingeben und das Kombinationsfeld zeigt gleich den n&auml;chsten Eintrag der Datensatzherkunft an, der mit diesen Anfangsbuchstaben beginnt. Dieses Verhalten wollen wir auch gern f&uuml;r Textfelder programmieren. Dazu starten wir mit einer etwas einfacheren Variante, die Sie vielleicht vom VBA-Editor kennen: Wenn Sie dort beginnen, einen Objekt- oder Variablennamen zu schreiben, k&ouml;nnen Sie mit der Tastenkombination Strg + Leertaste daf&uuml;r sorgen, dass IntelliSense aktiviert wird und passende Eintr&auml;ge anzeigt. Wir wollen daf&uuml;r sorgen, dass an dieser Stelle einfach der erste passende Eintrag erscheint - wenn wir eine Liste der verf&uuml;gbaren Eintr&auml;ge wollten, k&ouml;nnten wir ja direkt ein Kombinationsfeld verwenden.","og_url":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-13T20:55:55+00:00","og_image":[{"url":"http:\/\/vg06.met.vgwort.de\/na\/171bd0632ef84681971ded6378a4d5e9","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"20\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Autocomplete in Textfeldern","datePublished":"2020-05-13T20:55:55+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/"},"wordCount":3690,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/171bd0632ef84681971ded6378a4d5e9","articleSection":["2019","4\/2019","Mit Formularen arbeiten"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/","url":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/","name":"Autocomplete in Textfeldern - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/171bd0632ef84681971ded6378a4d5e9","datePublished":"2020-05-13T20:55:55+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/#primaryimage","url":"http:\/\/vg06.met.vgwort.de\/na\/171bd0632ef84681971ded6378a4d5e9","contentUrl":"http:\/\/vg06.met.vgwort.de\/na\/171bd0632ef84681971ded6378a4d5e9"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Autocomplete_in_Textfeldern\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Autocomplete in Textfeldern"}]},{"@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\/55001200","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=55001200"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001200\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001200"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001200"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001200"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}