{"id":55001560,"date":"2025-08-01T00:00:00","date_gmt":"2025-08-03T11:26:12","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1560"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Optimierter_Suchen_und_ErsetzenDialog_Grundgeruest","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Optimierter_Suchen_und_ErsetzenDialog_Grundgeruest\/","title":{"rendered":"Optimierter &#8222;Suchen und Ersetzen&#8220;-Dialog: Grundger&uuml;st"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg01.met.vgwort.de\/na\/c654ed641eb94dd4b2704416b4e33c83\" width=\"1\" height=\"1\" alt=\"\"><b>Der Dialog zum Suchen und Ersetzen f&uuml;r die Suche nach Daten in der Datenblattansicht ist bereits sehr praktisch. Allerdings hatte ein Leser die Anforderung, dass er &ouml;fter mit dem Dialog nach den gleichen Ausdr&uuml;cken sucht, um diese zu ersetzen. Der Dialog hat zwar immer die zuletzt verwendeten zu suchenden und zu ersetzenden Ausdr&uuml;cke gespeichert und in den Auswahlfeldern angeboten, aber wenn er die Datenbank geschlossen und erneut ge&ouml;ffnet hat, war die Arbeit verloren und die Auswahlfelder waren wieder leer. Also bauen wir diesen Dialog einfach nach und erweitern diesen um eine Funktion, welche die zuletzt verwendeten Eintr&auml;ge dauerhaft speichert und diese nach dem Schlie&szlig;en und &Ouml;ffnen der Anwendung wieder bereitstellt.<\/b><\/p>\n<h2>Worum geht es?<\/h2>\n<p>Der Suchen und Ersetzen-Dialog, den wir durch einen besseren Dialog ersetzen wollen, kann &uuml;ber den Ribbon-Eintrag <b>Start|Suchen|Suchen <\/b>ge&ouml;ffnet werden (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_003.png\" alt=\"Aufruf des Suchen und Ersetzen-Dialogs\" width=\"700\" height=\"202,3788\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Aufruf des Suchen und Ersetzen-Dialogs<\/span><\/b><\/p>\n<p>Dies &ouml;ffnet den Dialog mit aktiviertem <b>Suchen<\/b>-Registerreiter (siehe Bild 2). Hier k&ouml;nnen wir nacheinander nach verschiedenen Begriffen suchen. Die zuletzt verwendeten Begriffe werden beim Aufklappen der Auswahl unter <b>Suchen nach: <\/b>direkt bereitgestellt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_004.png\" alt=\"Der Suchen und Ersetzen-Dialog\" width=\"524,559\" height=\"209,8235\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Der Suchen und Ersetzen-Dialog<\/span><\/b><\/p>\n<p>Wir k&ouml;nnen direkt von diesem Dialog aus zur Registerseite <b>Ersetzen <\/b>wechseln. Diese enth&auml;lt lediglich einige zus&auml;tzliche Elemente wie zum Beispiel das Feld zum Eingeben des zu ersetzenden Ausdrucks (siehe Bild 3). Au&szlig;erdem finden wir nun Schaltfl&auml;che zum Ersetzen der aktuellen Fundstelle und aller Fundstellen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_005.png\" alt=\"Registerseite Ersetzen des Suchen und Ersetzen-Dialogs\" width=\"574,559\" height=\"229,8235\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Registerseite Ersetzen des Suchen und Ersetzen-Dialogs<\/span><\/b><\/p>\n<p>Der Dialog kann au&szlig;erdem mit der Taste <b>Strg + F <\/b>ge&ouml;ffnet werden.<\/p>\n<h2>Option &#8222;Suchen in&#8220;<\/h2>\n<p>Der Dialog erlaubt mit <b>Suchen in <\/b>das Festlegen des Suchziels:<\/p>\n<ul>\n<li><b>Aktuelles Feld<\/b>: Durchsucht nur das aktuelle Steuerelement. Bei Datenblatt- oder Endlosansichten bezieht sich das auf das gleiche Steuerelement f&uuml;r jeden Datensatz.<\/li>\n<li><b>Aktuelles Dokument<\/b>: Durchsucht alle Steuerelemente und Datens&auml;tze der aktuellen Ansicht. Dabei wird zuerst Steuerelement f&uuml;r Steuerelement des aktuellen Datensatzes durchsucht und dann folgen die folgenden Datens&auml;tze.<\/li>\n<\/ul>\n<h2>Option &#8222;Vergleichen&#8220;<\/h2>\n<p>Mit <b>Vergleichen <\/b>k&ouml;nnen wir angeben, welcher Teil der Felder untersucht werden soll: <b>Teil des Feldinhalts<\/b>, <b>Ganzes Feld <\/b>oder <b>Anfang des Feldinhalts<\/b>.<\/p>\n<h2>Option &#8222;Suchen&#8220;<\/h2>\n<p>Unter <b>Suchen <\/b>geben wir an, welchen Bereich wir ausgehend vom aktuell markierten Steuerelement untersuchen wollen:<\/p>\n<ul>\n<li><b>Alle<\/b>: Durchsucht von oben nach unten und beginnt von vorn, wenn sich noch Elemente vor dem aktuellen Steuerelement befinden.<\/li>\n<li><b>Aufw&auml;rts<\/b>: Sucht von der aktuellen Position bis zum Start des Dokuments.<\/li>\n<li><b>Abw&auml;rts<\/b>: Sucht von der aktuellen Position bis zum Ende des Dokuments.<\/li>\n<\/ul>\n<h2>Option &#8222;Gro&szlig;-\/Kleinschreibung&#8220;<\/h2>\n<p>Mit <b>Gro&szlig;-\/Kleinschreibung <\/b>k&ouml;nnen wir angeben, ob wir Gro&szlig;- und Kleinschreibung ber&uuml;cksichtigen wollen.<\/p>\n<h2>Option &#8222;Formatierung beachten&#8220;<\/h2>\n<p>Schlie&szlig;lich gibt es noch die Option <b>Formatierung beachten<\/b>. Diese ist zum Beispiel bei Datumsfeldern wichtig, wenn man eine andere Formatierung angegeben hat als das System verwendet. Wenn wir also Datumsangaben eigentlich im Format <b>tt.mm.jjjj <\/b>speichern (zum Beispiel <b>21.06.2025<\/b>), aber f&uuml;r das Tabellenfeld das Format <b>tt-mm-jjjj <\/b>festgelegt haben, wird das Datum als <b>21-06-2025 <\/b>angezeigt.<\/p>\n<p>Eine Suche nach <b>21.06. <\/b>liefert nun in jedem Fall das gesuchte Datum. Wenn wir jedoch nach <b>21-06- <\/b>suchen und <b>Formatierung beachten <\/b>ist deaktiviert, finden wir das Datum nicht.<\/p>\n<p>Erst wenn wir Formatierung beachten aktivieren, liefert auch <b>21-06-<\/b> das gew&uuml;nschte Ergebnis.<\/p>\n<h2>Schaltfl&auml;che &#8222;Weitersuchen&#8220;<\/h2>\n<p>Mit der Schaltfl&auml;che <b>Weitersuchen <\/b>starten wir den Suchvorgang nach dem n&auml;chsten Vorkommen. Klicken wir diese wiederholt an, durchl&auml;uft Access alle Fundstellen.<\/p>\n<h2>Schaltfl&auml;che &#8222;Ersetzen&#8220;<\/h2>\n<p>Diese Schaltfl&auml;che funktioniert nur, wenn zuvor mit <b>Weitersuchen <\/b>eine Fundstelle markiert wurde. Das Anklicken f&uuml;hrt dann zur gew&uuml;nschten Ersetzung und markiert automatisch die n&auml;chste Fundstelle, sofern noch ein weiteres Vorkommen vorhanden ist.<\/p>\n<p>So k&ouml;nnen wir durch wiederholtes Bet&auml;tigen dieser Schaltfl&auml;che alle Vorkommen des gesuchten Begriffes ersetzen.<\/p>\n<h2>Schaltfl&auml;che &#8222;Alle ersetzen&#8220;<\/h2>\n<p>Diese Schaltfl&auml;che ersetzt automatisch alle Vorkommen im angegebenen Bereich. Dazu muss nicht zuvor ein Vorkommen markiert worden sein.<\/p>\n<h2>Wichtig: Lassen sich die grundlegenden Funktionen reproduzieren?<\/h2>\n<p>Bevor wir Zeit investieren, den <b>Suchen und Ersetzen<\/b>-Dialog original nachzubilden und diesen um die gew&uuml;nschten Funktionen zu erweitern, wollen wir erst einmal pr&uuml;fen, ob sich das grundlegende Verhalten &uuml;berhaupt reproduzieren l&auml;sst.<\/p>\n<p>Um per VBA-Code zum Beispiel nach bestimmten Inhalten im Datenblatt zu suchen, m&uuml;ssen wir das Recordset des Datenblatts referenzieren. Die Frage lautet: Gelingt das &uuml;berhaupt per Code? Haben jegliche Datenbl&auml;tter ein Recordset, auf das wir zugreifen k&ouml;nnen &#8211; egal, ob es die Datenblattansicht einer Tabelle, einer Abfrage oder auch eines Formulars ist? Beim Formular wissen wir, dass wir auf das Recordset der Datenblattansicht zugreifen k&ouml;nnen.<\/p>\n<p>Hier referenzieren wir das Formular &uuml;ber die <b>Forms<\/b>-Auflistung und greifen dann &uuml;ber die <b>Recordset<\/b>-Eigenschaft auf das Recordset zu. Aber wie soll das mit Tabellen und Abfragen funktionieren? Immerhin gibt es keine <b>Table<\/b>&#8211; oder <b>Query<\/b>-Auflistungen, die wir analog zur <b>Forms<\/b>-Auflistung nutzen k&ouml;nnten.<\/p>\n<p>Aber ben&ouml;tigen wir &uuml;berhaupt eine Auflistung, um auf das aktuelle Objekt und sein Recordset zugreifen zu k&ouml;nnen?<\/p>\n<p>Schnelle Experimente zeigen: Nein, das ist nicht der Fall. Wie k&ouml;nnen n&auml;mlich die Elemente der <b>Screen<\/b>-Klasse nutzen.<\/p>\n<h2>Per Screen-Klasse auf das aktuelle Datenblatt zugreifen<\/h2>\n<p>Wir schauen uns dies zuerst anhand einer Tabelle an, die wir in der Datenblattansicht ge&ouml;ffnet haben.<\/p>\n<p>&Ouml;ffnen wir parallel dazu den Direktbereich des VBA-Editors und geben dort den Ausdruck <b>Screen.ActiveDatasheet.Name <\/b>ein, erhalten wir tats&auml;chlich den Namen des aktuellen Datenblatts respektive der zugrunde liegenden Tabelle (siehe Bild 4).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_001.png\" alt=\"Zugriff per VBA auf das aktuelle Datenblatt einer Tabelle\" width=\"649,559\" height=\"341,5701\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Zugriff per VBA auf das aktuelle Datenblatt einer Tabelle<\/span><\/b><\/p>\n<p>Also probieren wir auch gleich aus, ob wir damit auch auf ein entsprechendes <b>Recordset<\/b>-Objekt zugreifen k&ouml;nnen. Auch das gelingt:<\/p>\n<pre>  Screen.ActiveDatasheet.Recordset.RecordCount\r\n  100 <\/pre>\n<p>Das Gleiche funktioniert auch, wenn wir eine Abfrage in der Datenblattansicht &ouml;ffnen.<\/p>\n<h2>Zugriff auf das Datenblatt eines Formulars<\/h2>\n<p>Bei Formularen m&uuml;ssen wir differenzieren. Wir k&ouml;nnen hier Formular vorfinden, die ihre Daten direkt in der Datenblattansicht anzeigen oder solche, die Unterformulare f&uuml;r die Datenblattansicht verwenden.<\/p>\n<p>Bei Formularen, die ihre Daten direkt in der Datenblattansicht anzeigen, k&ouml;nnen wir ebenfalls mit <b>Screen.ActiveDatasheet <\/b>arbeiten.<\/p>\n<p>Bei Formularen, die ein Unterformular in der Datenblattansicht anzeigen, gelingt dies nicht so einfach, wie Bild 5 zeigt. Hier erhalten wir eine Fehlermeldung.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_002.png\" alt=\"Fehler beim Zugriff per VBA auf das aktuelle Datenblatt im Unterformular\" width=\"699,559\" height=\"466,9903\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Fehler beim Zugriff per VBA auf das aktuelle Datenblatt im Unterformular<\/span><\/b><\/p>\n<p>Wir k&ouml;nnen auch nicht mit der folgenden Anweisung darauf zugreifen &#8211; hier erhalten wir lediglich das Hauptformular:<\/p>\n<pre>  Screen.ActiveForm.Name\r\nfrmMitarbeiterUebersicht<\/pre>\n<p>Wenn sich der Fokus jedoch in einem der Steuerelemente im Unterformular befindet, k&ouml;nnen wir am einfachsten &uuml;ber folgenden Ausdruck darauf zugreifen:<\/p>\n<pre>  Screen.ActiveControl.Parent.Name\r\nsfmMitarbeiterUebersicht<\/pre>\n<h2>Mehr als nur Datenblatt<\/h2>\n<p>Allerdings funktioniert die Originalfunktion nicht nur in Datenbl&auml;ttern, sondern eigentlich in allen Formularen, die &uuml;berhaupt mindestens ein Steuerelement enthalten, das durchsuchbar ist &#8211; also zum Beispiel ein Textfeld. Wir wollen in diesem Beispiel allerdings nur eine <b>Suchen und Ersetzen<\/b>-Funktion f&uuml;r Datenbl&auml;tter erstellen.<\/p>\n<h2>Weitere Erweiterungsm&ouml;glichkeiten<\/h2>\n<p>Wenn wir schon dabei sind, den <b>Suchen und Ersetzen<\/b>-Dialog zu verbessern, k&ouml;nnen wir auch gleich noch weitere Erg&auml;nzungen hinzuf&uuml;gen.<\/p>\n<p>Zum Beispiel k&ouml;nnten wir den Dialog so programmieren, dass er beim &Ouml;ffnen gleich den Wert im <b>Suchen<\/b>-Feld anzeigt, der im aktuellen Steuerelement mit dem Fokus enthalten ist &#8211; vorausgesetzt, dieses Feld enth&auml;lt einen Wert beziehungsweise kann einen Wert enthalten.<\/p>\n<h2>Ersetzen von Werten<\/h2>\n<p>Beim Ersetzen von Werten ben&ouml;tigen wir ein wenig mehr Code. Wir m&uuml;ssen aus den Parametern des Dialogs eine kleine Prozedur erstellen, die eine <b>UPDATE<\/b>-Anweisung zusammenbaut und ausf&uuml;hrt. Dies schauen wir uns sp&auml;ter im Detail an.<\/p>\n<h2>&#8222;Suchen und Ersetzen&#8220;-Formular nachbauen<\/h2>\n<p>Nachdem die technischen Voraussetzungen gekl&auml;rt sind, bauen wir das <b>Suchen und Ersetzen<\/b>-Formular originalgetreu nach.<\/p>\n<p>Dazu erstellen wir ein neues, leeres Formular und speichern es unter dem Namen <b>frmSuchenUndErsetzen<\/b>. Um es sp&auml;ter vom eingebauten <b>Suchen<\/b>-Dialog unterscheiden zu k&ouml;nnen, tragen wir f&uuml;r Beschriftung den Text <b>Suchen und Ersetzen PRO <\/b>ein.<\/p>\n<p>Dann f&uuml;gen wir erst einmal die Steuerelemente hinzu und legen ihre Namen fest.<\/p>\n<p>Wichtig: Wir f&uuml;gen kein echtes Registersteuerelement hinzu, denn eigentlich ben&ouml;tigen wir kein Registersteuerelement.<\/p>\n<p>Wir haben nicht gepr&uuml;ft, ob Microsoft f&uuml;r den <b>Suchen und Ersetzen<\/b>-Dialog tats&auml;chlich ein Registersteuerelement verwendet und ob dort die auf beiden Registerseiten vorkommenden Steuerelemente jeweils zwei Mal angelegt wurden. Wir werden das jedenfalls nicht tun und stattdessen ein Fake-Registersteuerelement bauen.<\/p>\n<p>Dazu verwenden wir ein wei&szlig;es Rechteck und zwei Schaltfl&auml;chen, die wir &uuml;ber diesem Rechteck platzieren &#8211; genau so, dass der untere Rand der Schaltfl&auml;chen etwas unter dem Rechteck verschwindet. Dazu m&uuml;ssen wir zuerst die Schaltfl&auml;chen anlegen und dann das Rechteck-Steuerelement. In der Z-Reihenfolge werden immer die zuletzt angelegten Steuerelemente &uuml;ber die &uuml;brigen gelegt.<\/p>\n<p>Dementsprechend f&uuml;gen wir auch die &uuml;brigen Steuerelemente erst hinzu, wenn wir das Rechteck angelegt haben, und ordnen diese wie in Bild 6 an.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_006.png\" alt=\"Entwurf des neuen Suchen und Ersetzen-Dialogs\" width=\"599,559\" height=\"360,881\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Entwurf des neuen Suchen und Ersetzen-Dialogs<\/span><\/b><\/p>\n<p>Die Steuerelemente versehen wir mit den folgenden Namen:<\/p>\n<ul>\n<li><b>Registertag <\/b>Suchen: <b>regSuchen<\/b><\/li>\n<li>Register-Schaltfl&auml;che <b>Ersetzen<\/b>: <b>regErsetzen<\/b><\/li>\n<li>Kombinationsfeld <b>Suchen nach<\/b>: <b>cboSuchenNach<\/b><\/li>\n<li>Kombinationsfeld <b>Ersetzen durch<\/b>: <b>cboErsetzenDurch<\/b><\/li>\n<li>Kombinationsfeld <b>Suchen in<\/b>: <b>cboSuchenIn<\/b><\/li>\n<li>Kombinationsfeld <b>Vergleichen<\/b>: <b>cboVergleichen<\/b><\/li>\n<li>Kombinationsfeld <b>Suchen<\/b>: <b>cboSuchen<\/b><\/li>\n<li>Kontrollk&auml;stchen <b>Gro&szlig;-\/Kleinschreibung beachten<\/b>: <b>chkGrossKleinschreibungBeachten<\/b><\/li>\n<li>Kontrollk&auml;stchen <b>FormatierungBeachten<\/b>: <b>chkFormatierungBeachten<\/b><\/li>\n<li>Schaltfl&auml;che <b>Weitersuchen<\/b>: <b>cmdWeitersuchen<\/b><\/li>\n<li>Schaltfl&auml;che <b>Abbrechen<\/b>: <b>cmdAbbrechen<\/b><\/li>\n<li>Schaltfl&auml;che <b>Ersetzen<\/b>: <b>cmdErsetzen<\/b><\/li>\n<li>Schaltfl&auml;che <b>Alle ersetzen<\/b>: <b>cmdAlleErsetzen<\/b><\/li>\n<\/ul>\n<p>F&uuml;r die Schaltfl&auml;chen f&uuml;gen wir passende Icons hinzu, indem wir die jeweilige Schaltfl&auml;che markieren und dann den Ribbonbefehl <b>Formularentwurf|Steuerlemente|Bild einf&uuml;gen <\/b>nutzen.<\/p>\n<p>Den <b>Hintergrund <\/b>der Schaltfl&auml;chen stellen wir auf <b>Transparent <\/b>ein, die <b>Anordnung der Bildbeschriftung <\/b>auf <b>Rechts <\/b>und die <b>Schriftbreite <\/b>f&uuml;r alle au&szlig;er der nicht markierten Registerschaltfl&auml;che auf <b>Fett<\/b>.<\/p>\n<p>Au&szlig;erdem f&uuml;gen wir vor der Eigenschaft <b>Beschriftung <\/b>der Schaltfl&auml;chen jeweils zwei Leerzeichen ein, damit die Beschriftung nicht zu nah an den Icons erscheint.<\/p>\n<p>Da das Formular selbst keine Datensatzquelle hat, stellen wir die Eigenschaften <b>Datensatzmarkierer<\/b>, <b>Navigationsschaltfl&auml;chen <\/b>und <b>Bildlaufleisten <\/b>auf <b>Nein <\/b>und <b>Automatisch zentrieren <\/b>auf <b>Ja <\/b>ein.<\/p>\n<h2>Schaltfl&auml;chen zum Entfernen von Such- und Ersetzungstexten<\/h2>\n<p>Die beiden Kombinationsfelder Suchen nach und Ersetzen durch sollen die bisher eingegebenen Texte anzeigen.<\/p>\n<p>Damit der Benutzer auch mal einen der eingegebenen Texte entfernen kann, wollen wir au&szlig;erdem noch zwei Schaltfl&auml;chen zum L&ouml;schen des aktuell ausgew&auml;hlten Eintrags hinzuf&uuml;gen.<\/p>\n<p>Diese erhalten die Namen <b>cmdSuchenNachLoeschen <\/b>und <b>cmdErsetzenDurchLoeschen<\/b>. Danach sieht der Entwurf wie in Bild 7 aus. Die Funktionalit&auml;t dieser Schaltfl&auml;chen f&uuml;gen wir sp&auml;ter hinzu.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_015.png\" alt=\"Schaltfl&auml;chen zum Leeren\" width=\"424,5589\" height=\"179,6555\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Schaltfl&auml;chen zum Leeren<\/span><\/b><\/p>\n<h2>Bei Eingabetaste automatisch suchen<\/h2>\n<p>Wenn der Benutzer die Eingabetaste bet&auml;tigt, soll die Schaltfl&auml;che <b>cmdWeitersuchen <\/b>ausgel&ouml;st werden. Dazu stellen wir die Eigenschaft <b>Standard <\/b>f&uuml;r diese Schaltfl&auml;che auf <b>Ja <\/b>ein.<\/p>\n<p>Leider funktioniert das nicht, wenn der Fokus auf einer der &uuml;brigen Schaltfl&auml;chen liegt. Dann wird die jeweils aktive Schaltfl&auml;che ausgef&uuml;hrt. Also m&uuml;ssen wir f&uuml;r die &uuml;brigen Tasten noch das Ereignis <b>Bei Taste Ab <\/b>definieren und hier pr&uuml;fen, ob der Benutzer f&uuml;r diese die Eingabetaste bet&auml;tigt hat. Ist das der Fall, soll die Ereignisprozedur der Schaltfl&auml;che <b>cmdWeitersuchen <\/b>ausgel&ouml;st werden. Dazu hinterlegen wir zun&auml;chst die entsprechende Ereignisprozedur, die wir allerdings erst einmal mit einer Dummy-Meldung f&uuml;llen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdWeitersuchen_Click()\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Weitersuchen\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>F&uuml;r die &uuml;brigen Schaltfl&auml;chen  legen wir nun jeweils eine Prozedur f&uuml;r das Ereignis <b>Bei Taste Ab <\/b>an, die wir wie folgt f&uuml;llen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>regSuchen_KeyDown(KeyCode<span style=\"color:blue;\"> As Integer<\/span>, _\r\n         Shift<span style=\"color:blue;\"> As Integer<\/span>)\r\n     Select Case KeyCode\r\n         <span style=\"color:blue;\">Case <\/span>13\r\n             KeyCode = 0\r\n             <span style=\"color:blue;\">Call<\/span> cmdWeitersuchen_Click\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Damit f&uuml;hrt das Bet&auml;tigen der Eingabetaste nun immer die Taste <b>cmdWeitersuchen <\/b>aus.<\/p>\n<h2>Bei Escape-Taste automatisch schlie&szlig;en<\/h2>\n<p>Bet&auml;tigt der Benutzer die <b>Escape<\/b>-Taste, soll der <b>Suchen und Ersetzen<\/b>-Dialog geschlossen werden. Dazu stellen wir die Eigenschaft <b>Abbrechen <\/b>f&uuml;r diese Schaltfl&auml;che auf <b>Ja <\/b>ein.<\/p>\n<p>Die Ereignisprozedur f&uuml;r diese Schaltfl&auml;che k&ouml;nnen wir gleich anlegen. Sie lautet:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdAbbrechen_Click()\r\n     DoCmd.Close acForm, Me.Name\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Kombinationsfelder f&uuml;llen<\/h2>\n<p>Nun f&uuml;llen wir die Kombinationsfelder, zun&auml;chst die drei unteren &#8211; diese nehmen jeweils eine Wertliste auf.<\/p>\n<p>Das Kombinationsfeld <b>cboSuchenIn <\/b>erhalt diese Werteliste:<\/p>\n<pre>\"Aktuelles Feld\";\"Aktuelles Dokument\"<\/pre>\n<p>Damit diese angezeigt wird, stellen wir au&szlig;erdem die Eigenschaft <b>Herkunftsart <\/b>auf <b>Wertliste <\/b>ein. Au&szlig;erdem wollen wir verhindern, dass der Benutzer die Wertliste bearbeiten kann und legen daher noch den Wert <b>Nein <\/b>f&uuml;r die Eigenschaft <b>Wertlistenbearbeitung zulassen <\/b>fest (siehe Bild 8).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_007.png\" alt=\"Einstellen der Werte f&uuml;r die Kombinationsfelder\" width=\"649,559\" height=\"438,2677\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Einstellen der Werte f&uuml;r die Kombinationsfelder<\/span><\/b><\/p>\n<p>Die Einstellungen f&uuml;r die weiteren beiden Kombinationsfelder sind weitgehend identisch. Lediglich die Datensatzherk&uuml;nfte unterscheiden sich. Die f&uuml;r das Kombinationsfeld <b>cboVergleichen <\/b>lautet:<\/p>\n<pre>\"Teil des Feldinhalts\";\"Ganzes Feld\";\"Anfang des Feldinhalts\"<\/pre>\n<p>Und f&uuml;r <b>cboSuchen <\/b>verwenden wir:<\/p>\n<pre>\"Alle\";\"Aufw&auml;rts\";\"Abw&auml;rts\"<\/pre>\n<p>Schlie&szlig;lich wollen wir noch daf&uuml;r sorgen, dass alle drei Kombinationsfelder jeweils den ersten Eintrag bei &Ouml;ffnen des Formulars anzeigen. Au&szlig;erdem soll die Schaltfl&auml;che <b>cmdWeitersuchen <\/b>immer direkt den Fokus erhalten. Dazu f&uuml;gen wir dem Formular eine Ereignisprozedur f&uuml;r das Ereignis <b>Beim Laden <\/b>hinzu, die wie folgt aussieht:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n     Me.cboSuchenIn = Me.cboSuchenIn.ItemData(0)\r\n     Me.cboVergleichen = Me.cboVergleichen.ItemData(0)\r\n     Me.cboSuchen = Me.cboSuchen.ItemData(0)\r\n     Me.cmdWeitersuchen.SetFocus \r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Damit erhalten wir nun das Zwischenergebnis aus Bild 9.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_008.png\" alt=\"Kombinationsfeld in Aktion\" width=\"499,5589\" height=\"264,0526\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: Kombinationsfeld in Aktion<\/span><\/b><\/p>\n<h2>Registerseiten programmieren<\/h2>\n<p>Hier sehen wir allerdings, dass trotz der Aktivierung der Schaltfl&auml;che f&uuml;r die Registerseite <b>Suchen <\/b>auch die Steuerelemente angezeigt werden, die erst f&uuml;r die Registerseite <b>Ersetzen <\/b>eingeblendet werden sollen. Das &auml;ndern wir durch jeweils eine Ereignisprozedur f&uuml;r die beiden Registerschaltfl&auml;chen.<\/p>\n<p>Klickt der Benutzer auf <b>regErsetzen<\/b>, sollen das Kombinationsfeld <b>cboErsetzen <\/b>und die beiden Schaltfl&auml;chen <b>cmdErsetzen <\/b>und <b>cmdAlleErsetzen <\/b>eingeblendet werden. Au&szlig;erdem soll die Schrift der Schaltfl&auml;che <b>regSuchen <\/b>nicht mehr fett dargestellt werden, daf&uuml;r aber die der Schaltfl&auml;che <b>cmdErsetzen<\/b>.<\/p>\n<p>Und schlie&szlig;lich wird der Wert des Feldes <b>Ersetzen <\/b>der zugrunde liegenden Tabelle <b>tblSuchenUndErsetzen <\/b>auf <b>True <\/b>eingestellt, damit dieser Zustand sp&auml;ter wiederhergestellt werden kann:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>regErsetzen_Click()\r\n     Me.cboErsetzenDurch.Visible = <span style=\"color:blue;\">True<\/span>\r\n     Me.cmdErsetzen.Visible = <span style=\"color:blue;\">True<\/span>\r\n     Me.cmdAlleErsetzen.Visible = <span style=\"color:blue;\">True<\/span>\r\n     Me.regSuchen.FontBold = 0\r\n     Me.regErsetzen.FontBold = 1\r\n     Me!Ersetzen = <span style=\"color:blue;\">True<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Schaltfl&auml;che <b>regSuchen <\/b>soll den umgekehrten Effekt bewirken:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>regSuchen_Click()\r\n     Me.cboErsetzenDurch.Visible = <span style=\"color:blue;\">False<\/span>\r\n     Me.cmdErsetzen.Visible = <span style=\"color:blue;\">False<\/span>\r\n     Me.cmdAlleErsetzen.Visible = <span style=\"color:blue;\">False<\/span>\r\n     Me.regSuchen.FontBold = 1\r\n     Me.regErsetzen.FontBold = 0\r\n     Me!Ersetzen = <span style=\"color:blue;\">False<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Wir m&uuml;ssen au&szlig;erdem noch daf&uuml;r sorgen, dass das Kombinationsfeld <b>cboErsetzen <\/b>sowie die beiden Schaltfl&auml;chen <b>cmdErsetzen <\/b>und <b>cmdAlleErsetzen <\/b>zun&auml;chst ausgeblendet sind &#8211; das erledigen wir durch Einstellen der entsprechenden Eigenschaften im Eigenschaftenblatt.<\/p>\n<h2>Formular in verschiedenen Modi &ouml;ffnen<\/h2>\n<p>Standardm&auml;&szlig;ig &ouml;ffnet das Formular nun im Modus <b>Suchen<\/b>. Da wir das Formular jedoch auch direkt zum Ersetzen &ouml;ffnen wollen, f&uuml;gen wir dem Ereignis <b>Beim &Ouml;ffnen <\/b>noch die Abfrage nach dem &Ouml;ffnungsargument hinzu. Lautet dies <b>Ersetzen<\/b>, soll das Formular direkt f&uuml;r das Ersetzen vorbereitet werden.<\/p>\n<p>Zun&auml;chst einmal soll das &Ouml;ffnen des Formulars f&uuml;r diesen Modus so erfolgen:<\/p>\n<pre>DoCmd.OpenForm \"frmSuchenUndErsetzen\", OpenArgs:=\"Ersetzen\"<\/pre>\n<p>In der Ereignisprozedur, die wir f&uuml;r das Ereignis <b>Beim &Ouml;ffnen <\/b>aufrufen, f&uuml;gen wir nun diese Anweisungen hinzu:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Open(Cancel<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> IsNull(Me.OpenArgs)<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">If <\/span>Me.OpenArgs = \"Ersetzen\"<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">Call<\/span> regErsetzen_Click\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 wird die Prozedur <b>regErsetzen_Click <\/b>aufgerufen, wenn als &Ouml;ffnungsparameter <b>Ersetzen <\/b>&uuml;bergeben wurde.<\/p>\n<p>Nach dem &Ouml;ffnen im Suchen-Modus sieht das Formular nun wie in Bild 10 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_009.png\" alt=\"Formular nach dem &Ouml;ffnen im Suchen-Modus\" width=\"499,5589\" height=\"258,239\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 10: Formular nach dem &Ouml;ffnen im Suchen-Modus<\/span><\/b><\/p>\n<h2>Verwalten der Suchen- und Ersetzen-Werte<\/h2>\n<p>Der eigentliche Clou des neuen Suchen und Ersetzen-Formulars soll das Speichern der verwendeten Eintr&auml;ge f&uuml;r die Kombinationsfelder <b>Suchen nach <\/b>und <b>Ersetzen durch <\/b>sein. Hier stellt sich die Frage, wo wir diese Eintr&auml;ge speichern sollen. Wir k&ouml;nnten das in einer oder mehreren Tabellen oder in der Registry erledigen.<\/p>\n<p>Praktischer w&auml;ren Tabellen, da wir hier die Daten direkt nach den gew&uuml;nschten Kriterien sortieren k&ouml;nnten.<\/p>\n<p>Das wir den neuen <b>Suchen und Ersetzen<\/b>-Dialog ohnehin in allen Datenbanken zur Verf&uuml;gung stellen wollen und nicht nur in der Datenbank, in der wir diesen programmieren, werden wir die Datenbank fr&uuml;her oder sp&auml;ter in eine Add-In-Datenbank umwandeln. Also k&ouml;nnen wir hier auch alle notwendigen Tabellen integrieren &#8211; die Daten stehen dann in allen Anwendungen zur Verf&uuml;gung, von denen aus wir den <b>Suchen und Ersetzen<\/b>-Dialog aufrufen.<\/p>\n<p>Stellt sich also die Frage, welche Daten wir wie speichern wollen. Zun&auml;chst ben&ouml;tigen wir in jedem Fall jeweils eine Tabelle f&uuml;r die Begriffe aus den beiden Kombinationsfeldern <b>Suchen nach <\/b>und <b>Ersetzen durch<\/b>. Es kann jedoch auch sinnvoll sein, die &uuml;brigen Einstellungen zu speichern &#8211; also zum Beispiel den aktuell ausgew&auml;hlten Wert der Auswahlfelder <b>Suchen in<\/b>, <b>Vergleichen <\/b>und <b>Suchen <\/b>sowie die Daten der beiden Kontrollk&auml;stchen.<\/p>\n<h2>Tabellen zum Speichern der Suchen- und Ersetzen-Zeichenketten<\/h2>\n<p>Die erste Tabelle hei&szlig;t <b>tblSuchenNach <\/b>und nimmt im Feld <b>Suchen <\/b>alle Begriffe auf, die wir in das Feld <b>cboSuchenNach <\/b>eingeben. Au&szlig;erdem f&uuml;gen wir ein Feld namens <b>KonfigurationID<\/b> hinzu, mit der wir die aktuelle Konfiguration festlegen.<\/p>\n<p>Diese speichert die weiteren Eigenschaften und die Datenbank, f&uuml;r welche wir diese Eigenschaften definiert haben. Schlie&szlig;lich legen wir noch ein Feld namens <b>ErsetzenDurchID <\/b>an. Wichtig: Der Standardwert dieses Feldes muss leer sein.<\/p>\n<p>Das Feld verkn&uuml;pfen wir sp&auml;ter mit dem Prim&auml;rschl&uuml;sselfeld der nachfolgend angelegten Tabelle <b>tblErsetzenDurch<\/b>, damit wir zu dem zuletzt verwendeten Suchbegriff auch noch den eventuell angegebenen Ersetzungstext speichern k&ouml;nnen.<\/p>\n<p>F&uuml;r diese Tabelle legen wir neben dem Prim&auml;rschl&uuml;ssel noch einen weiteren Index fest, der sich aus den beiden Feldern <b>SuchenNach <\/b>und <b>KonfigurationID <\/b>zusammensetzt und f&uuml;r den wir die Eigenschaft <b>Eindeutig <\/b>auf <b>Ja <\/b>einstellen. Damit stellen wir sicher, dass jeder Suchbegriff nur einmal pro Konfiguration gespeichert wird (siehe Bild 11).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_011.png\" alt=\"Tabelle zum Speichern der Suchbegriffe\" width=\"524,559\" height=\"335,894\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 11: Tabelle zum Speichern der Suchbegriffe<\/span><\/b><\/p>\n<p>Die zweite Tabelle namens <b>tblErsetzenDurch <\/b>bauen wir analog auf (siehe Bild 12). Hiermit k&ouml;nnen wir direkt die letzte Ersetzung, die wir einem Suchbegriff zugeordnet haben, ermitteln und bei Auswahl des Suchbegriffs wieder ausw&auml;hlen. Hier wird die Definition eines eindeutigen Indexes zur Begrenzung der Ersetzungstexte etwas komplizierter. <\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_012.png\" alt=\"Tabelle zum Speichern der Inhalte zum Ersetzen\" width=\"499,5589\" height=\"325,4007\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 12: Tabelle zum Speichern der Inhalte zum Ersetzen<\/span><\/b><\/p>\n<p>Schlie&szlig;lich fehlt noch die Tabelle <b>tblSuchenUndErsetzen<\/b>, welche die Konfigurationen speichert (siehe Bild 13).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_010.png\" alt=\"Tabelle zum Speichern der Konfigurationen\" width=\"649,559\" height=\"243,4874\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 13: Tabelle zum Speichern der Konfigurationen<\/span><\/b><\/p>\n<p>An dieser Stelle m&uuml;ssen wir uns entscheiden, ob wir nur eine Konfiguration je Datenbank zulassen wollen oder ob wir dem Benutzer die Gelegenheit geben wollen, gleich mehrere Konfigurationen je Datenbank zu speichern. Wir entscheiden uns an dieser Stelle daf&uuml;r, dass wir je Objekt, f&uuml;r welches der <b>Suchen und Ersetzen<\/b>-Dialog aufgerufen wird, jeweils eine Konfiguration zu speichern. Deshalb f&uuml;gen wir der Tabelle auch ein Feld namens <b>Objektname <\/b>hinzu.<\/p>\n<p>Womit wollen wir diese f&uuml;llen? Wir ermitteln einfach entweder &uuml;ber <b>Screen.ActiveDataSheet.Name<\/b> den Objektnamen der Datenblattansicht oder, wenn dies einen Fehler liefert, den Namen des Formulars, f&uuml;r das der <b>Suchen und Ersetzen<\/b>-Dialog aufgerufen wurde &#8211; mehr dazu sp&auml;ter.<\/p>\n<p>In den beiden Feldern <b>SuchenNach <\/b>und <b>ErsetzenDurch <\/b>speichern wir die zuletzt verwendeten Werte f&uuml;r diese beiden Eigenschaften.<\/p>\n<p>Die folgenden f&uuml;nf Felder der Tabelle <b>tblSuchenUndErsetzen <\/b>nehmen die verwendeten Werte f&uuml;r die drei weiteren Kombinationsfelder und die Kontrollk&auml;stchen auf.<\/p>\n<p>Danach folgt noch das Feld <b>Datenbankname<\/b>. Hier gehen wir davon aus, dass dieser konstant bleibt. Wenn der Benutzer den Datenbanknamen &auml;ndert, wird dazu keine Konfiguration mehr gefunden.<\/p>\n<p>Und schlie&szlig;lich legen wir noch ein <b>Ja\/Nein<\/b>-Feld namens <b>Ersetzen <\/b>an, mit dem wir speichern, ob der Benutzer zuletzt die Registerseite <b>Suchen <\/b>oder <b>Ersetzen <\/b>ge&ouml;ffnet hatte.<\/p>\n<p>Auch f&uuml;r diese Tabelle erstellen wir einen zusammengesetzten, eindeutigen Index, mit dem wir sicherstellen, dass f&uuml;r jede Kombination aus <b>Datenbank <\/b>und <b>Objektname <\/b>nur eine Konfiguration gespeichert wird.<\/p>\n<h2>Beziehungen zwischen den Tabellen<\/h2>\n<p>Schlie&szlig;lich legen wir noch die Beziehungen aus Bild 14 zwischen den Tabellen an, jeweils mit referenzieller Integrit&auml;t und L&ouml;schweitergabe.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_014.png\" alt=\"Beziehungen zwischen den Tabellen\" width=\"599,559\" height=\"405,7237\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 14: Beziehungen zwischen den Tabellen<\/span><\/b><\/p>\n<h2>Speichern und Laden der Konfigurationen<\/h2>\n<p>Damit kommen wir endlich zum technischen Teil: Wie laden und speichern wir die Konfigurationen? Hier haben wir folgende Zeitpunkte definiert:<\/p>\n<ul>\n<li>Wenn das Formular <b>frmSuchenUndErsetzen <\/b>ge&ouml;ffnet wird, pr&uuml;fen wir, ob es eine Konfiguration f&uuml;r dieses Formular in dieser Datenbank gibt. Diese laden wir dann in das Formular.<\/li>\n<li>Wenn der Benutzer auf <b>cmdWeitersuchen <\/b>oder auf <b>cmdErsetzen <\/b>oder <b>cmdAlleErsetzen <\/b>klickt, werden die aktuell in den Kombinationsfeldern <b>cboSuchenNach <\/b>und <b>cboErsetzenDurch <\/b>gespeicherten Werte in die Tabellen <b>tblSuchenNach <\/b>und <b>tblErsetzenDurch <\/b>gespeichert. Au&szlig;erdem tragen wir diese als zuletzt verwendete Eintr&auml;ge in die Tabelle <b>tblSuchenUndErsetzen <\/b>f&uuml;r die aktuelle Konfiguration ein.<\/li>\n<li>Hier kann es sein, dass es noch keine Konfiguration gibt. Also ist dies der Zeitpunkt, an dem wir eine neue Konfiguration anlegen.<\/li>\n<\/ul>\n<h2>Formular und Steuerelemente an die Tabellen binden<\/h2>\n<p>Damit &uuml;berhaupt Daten aus den Tabellen in den Steuerelementen des Formulars angezeigt werden, haben wir zwei M&ouml;glichkeiten. Entweder wir binden wir das Formular an die Tabellen und auch die beiden Kombinationsfelder <b>cboSuchenNach <\/b>und <b>cboErsetzenDurch<\/b>. Oder wir f&uuml;llen die entsprechenden Werte zur Laufzeit und speichern diese zu den oben angegebenen Zeitpunkten ab.<\/p>\n<p>Wir binden das Formular an die Tabelle <b>tblSuchenUndErsetzen<\/b> und stellen die <b>Steuerelementinhalt<\/b>-Eigenschaften auf die entsprechenden Felder dieser Datensatzquelle ein (siehe Bild 15).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1560_013.png\" alt=\"Zuweisen der Felder zur Eigenschaft Steuerelementinhalt\" width=\"649,559\" height=\"352,4939\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 15: Zuweisen der Felder zur Eigenschaft Steuerelementinhalt<\/span><\/b><\/p>\n<p>Gleiches erledigen wir f&uuml;r die beiden Kombinationsfelder <b>cboSuchenNach <\/b>und <b>cboErsetzenDurch<\/b>. Hier legen wir f&uuml;r die Eigenschaft <b>Datensatzherkunft <\/b>die Tabellen <b>tblSuchenNach <\/b>und <b>tblErsetzenDurch <\/b>fest. Au&szlig;erdem stellen wir die Eigenschaft <b>Spaltenanzahl <\/b>jeweils auf <b>2 <\/b>und die Eigenschaft <b>Spaltenbreiten <\/b>auf <b>0cm <\/b>ein, damit der Prim&auml;rsch&uuml;sselwert der Tabelle jeweils ausgeblendet und nur der eigentliche Such- beziehungsweise Ersetzungstext angezeigt wird.<\/p>\n<h2>Auf vorhandene Konfiguration pr&uuml;fen<\/h2>\n<p>Die Konfigurationen h&auml;ngen, wie oben beschrieben, vom Datenbanknamen und von der Bezeichnung der Datenblattansicht ab, f&uuml;r welche der <b>Suchen und Ersetzen<\/b>-Dialog ge&ouml;ffnet wird.<\/p>\n<p>Also m&uuml;ssen wir erst einmal diese beiden Informationen ermitteln. Den Datenbanknamen k&ouml;nnen wir ganz einfach &uuml;ber <b>CurrentProject.Name <\/b>ermitteln.<\/p>\n<p>F&uuml;r den Namen des aktuellen Objekts ben&ouml;tigen wir ein paar Zeilen Code mehr.<\/p>\n<h2>Ermitteln der aktuellen Datenblattansicht<\/h2>\n<p>Die Prozedur <b>AktuelleDatenblattansicht <\/b>aus Listing 1 ermittelt den Namen des Objekts, das aktuell den Fokus hat &#8211; aber nur, wenn es sich in der Datenblattansicht befindet.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>AktuelleDatenblattansicht()<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strObjektname<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objAktuellesObjekt<span style=\"color:blue;\"> As Object<\/span>\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     strObjektname = Screen.ActiveDatasheet.Name\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strObjektname) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> objAktuellesObjekt = Screen.ActiveControl.Parent\r\n         <span style=\"color:blue;\">If <\/span>objAktuellesObjekt.CurrentView = acCurViewDatasheet<span style=\"color:blue;\"> Then<\/span>\r\n             strObjektname = Screen.ActiveControl.Parent.Name\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(strObjektname) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         AktuelleDatenblattansicht = strObjektname\r\n         <span style=\"color:blue;\">Exit Function<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Ermitteln des aktuellen Objekts in der Datenblattansicht<\/span><\/b><\/p>\n<p>Sie deaktiviert die eingebaute Fehlerbehandlung und versucht, mit <b>Screen.ActiveDatasheet.Name <\/b>auf den Namen der Datenblattansicht des aktuell im Fokus befindlichen Objekts zuzugreifen. Das gelingt nur bei Tabellen oder Abfragen, die aktuell in der Datenblattansicht angezeigt werden.<\/p>\n<p>Ist <b>strObjektname <\/b>danach nicht gef&uuml;llt, k&ouml;nnen wir davon ausgehen, das ein anderes Objekt wie ein Formular den Fokus hat. Dann gehen wir davon aus, das eines der Steuerelemente dieses Formulars aktiviert ist und versuchen, &uuml;ber die <b>Parent<\/b>-Eigenschaft auf das &uuml;bergeordnete Element zuzugreifen &#8211; wieder bei deaktivierter Fehlerbehandlung.<\/p>\n<p>F&uuml;r dieses Element pr&uuml;fen wir, ob es in der Datenblattansicht angezeigt wird. Dazu nutzen wir die <b>CurrentView<\/b>-Eigenschaft, die wir mit dem Wert <b>acCurViewDatasheet <\/b>vergleichen.<\/p>\n<p>Ist diese Bedingung erf&uuml;llt, schreiben wir den Namen des <b>Parent<\/b>-Objekts in die Variable <b>strObjektname<\/b>.<\/p>\n<p>Nach dem Durchlaufen dieser Anweisungen ist <b>strObjektname <\/b>entweder gef&uuml;llt oder, wenn aktuell keine Datenblattansicht den Fokus hat, noch leer. Wenn es nicht leer ist, geben wir den Wert als Funktionsergebnis zur&uuml;ck.<\/p>\n<h2>&#8222;Suchen und Ersetzen&#8220;-Dialog &ouml;ffnen<\/h2>\n<p>Wir gehen erst einmal davon aus, dass wir den Dialog zu Testzwecken &uuml;ber einen Doppelklick auf das Element im Navigationsbereich &ouml;ffnen. Wenn der Dialog erscheint und wir dann beispielsweise auf die zu untersuchende Datenblattansicht klicken, verschwindet der Dialog m&ouml;glicherweise hinter dieser nun aktivierten Ansicht. Um das zu verhindern, stellen wir die Eigenschaft <b>Popup <\/b>des Formulars <b>frmSuchenErsetzen <\/b>auf <b>Ja <\/b>ein.<\/p>\n<p>Um zu verhindern, dass der Benutzer durch Durchlaufen aller Steuerelemente mit der Tabulator-Taste zu einem neuen, leeren Datensatz gelangt, stellen wir au&szlig;erdem die Eigenschaft <b>Zyklus <\/b>auf <b>Aktueller Datensatz <\/b>ein.<\/p>\n<h2>Ereignis beim &Ouml;ffnen des Formulars<\/h2>\n<p>Wenn wir das Formular &ouml;ffnen, wird als Erstes das Ereignis <b>Beim &Ouml;ffnen <\/b>ausgel&ouml;st (siehe Listing 2).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Open(Cancel<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>strObjektname<span style=\"color:blue;\"> As String<\/span>\r\n     strObjektname = AktuelleDatenblattansicht\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strObjektname) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Suchen und Ersetzen steht nur f&uuml;r die Datenblattansicht zur Verf&uuml;gung.\", vbOKOnly + vbExclamation, _\r\n             \"Keine Datenblattansicht aktiviert\"\r\n         Cancel = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Exit Sub<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> IsNull(Me.OpenArgs)<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">If <\/span>Me.OpenArgs = \"Ersetzen\"<span style=\"color:blue;\"> Then<\/span>\r\n             bolErsetzen = <span style=\"color:blue;\">True<\/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><b><span style=\"color:darkgrey;\">Listing 2: Prozedur beim &Ouml;ffnen des Formulars<\/span><\/b><\/p>\n<p>Dieses ermittelt mit der Funktion <b>AktuelleDatenblattansicht <\/b>den Namen der aktuell ge&ouml;ffneten und im Fokus befindlichen Datenblattansicht. Hat aktuell keine Datenblattansicht den Fokus, liefert die Funktion eine leere Zeichenkette. Dann erscheint eine Meldung, die den Benutzer darauf hinweis, dass der <b>Suchen und Ersetzen<\/b>-Dialog nur f&uuml;r Datenblattansichten funktioniert. Durch Einstellen des Parameters <b>Cancel <\/b>auf den Wert <b>True <\/b>und Beenden der Prozedur wird das Formular nun gar nicht erst ge&ouml;ffnet.<\/p>\n<p>Au&szlig;erdem stellt die Prozedur den Wert der folgenden Variablen auf <b>True <\/b>ein, wenn als &Ouml;ffnungsargument <b>Ersetzen <\/b>&uuml;bergeben wurde:<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>bolErsetzen<span style=\"color:blue;\"> As Boolean<\/span><\/pre>\n<p>Dieser Wert wird gleich im Ereignis <b>Beim Laden <\/b>weiterverarbeitet.<\/p>\n<h2>Ereignis beim Laden des Formulars<\/h2>\n<p>Im Ereignis <b>Beim Laden <\/b>des Formulars hinterlegen wir einige weitere wichtige Funktionen (siehe Listing 3). Das Formular <b>frmSuchenErsetzen <\/b>zeigt standardm&auml;&szlig;ig ungefiltert die Daten der Tabelle Tabelle <b>tblSuchenUndErsetzen <\/b>an.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>strDatenbankname<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strObjektname<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>dbc<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>lngSuchenUndErsetzenID<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> rst = Me.Recordset\r\n     strDatenbankname = CurrentProject.Name\r\n     strObjektname = AktuelleDatenblattansicht\r\n     rst.FindFirst \"Datenbankname = ''\" & strDatenbankname & \"'' AND Objektname = ''\" & strObjektname & \"''\"\r\n     <span style=\"color:blue;\">If <\/span>rst.NoMatch<span style=\"color:blue;\"> Then<\/span>\r\n         rst.Add<span style=\"color:blue;\">New<\/span>\r\n         rst!Datenbankname = strDatenbankname\r\n         rst!Objektname = strObjektname\r\n         rst!SuchenIn = \"Aktuelles Feld\"\r\n         rst!Vergleichen = \"Teil des Feldinhalts\"\r\n         rst!Suchen = \"Alle\"\r\n         rst!Ersetzen = bolErsetzen\r\n         lngSuchenUndErsetzenID = rst!SuchenUndErsetzenID\r\n         rst.Update\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         lngSuchenUndErsetzenID = rst!SuchenUndErsetzenID\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     Me.cboSuchenNach.RowSource = \"SELECT * FROM tblSuchenNach WHERE KonfigurationID = \" & lngSuchenUndErsetzenID\r\n     Me.cboErsetzenDurch.RowSource = \"SELECT * FROM tblErsetzenDurch WHERE KonfigurationID = \" & lngSuchenUndErsetzenID\r\n     Me.cmdWeitersuchen.SetFocus\r\n     <span style=\"color:blue;\">If <\/span>Me!Ersetzen = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Call<\/span> regErsetzen_Click\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">Call<\/span> regSuchen_Click\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 3: Prozedur beim Laden des Formulars<\/span><\/b><\/p>\n<p>Hier m&uuml;ssen wir pr&uuml;fen, ob es bereits eine Konfiguration f&uuml;r die aktuelle Datenblattansicht und die aktuelle Datenbank gibt und diese anzeigen oder eine neue Konfiguration erstellen und diese mit den wichtigsten Informationen ausstatten.<\/p>\n<p>Die Prozedur deklariert einige Variablen, darunter eine namens <b>dbc <\/b>mit dem Datentyp <b>DAO.Database<\/b>. Diese f&uuml;llen wir nicht wie &uuml;blich mit der Funktion <b>CurrentDb<\/b>, sondern wir verwenden diesmal <b>CodeDb<\/b>. Dies liefert bei Verwendung als Access-Add-In einen Verweis auf die Add-In-Datenbank &#8211; im Gegensatz zu <b>CurrentDb<\/b>, was einen Verweis auf die aufrufende Datenbank liefert.<\/p>\n<p>Die Prozedur holt sich mit <b>rst <\/b>einen Verweis auf das aktuelle Recordset sowie den aktuellen Datenbanknamen (in <b>strDatenbankname<\/b>) und den Namen der aktuellen Datenblattansicht (in <b>strObjektname<\/b>).<\/p>\n<p>Dann versucht sie, mit <b>FindFirst <\/b>einen Datensatz im Recordset zu finden, der zu Datenbankname und Objektname passt.<\/p>\n<p>Findet sie keinen, erstellt sie mit <b>AddNew<\/b> einen neuen Datensatz und tr&auml;gt die entsprechenden Werte in die Felder <b>Datenbankname <\/b>und <b>Objektname <\/b>ein. Au&szlig;erdem ermittelt sie den Wert des neuen Datensatzes der Tabelle <b>tblSuchenUndErsetzen<\/b> und schreibt diesen in die Variable <b>lngSuchenUndErsetzenID<\/b>, bevor sie den Datensatz speichert.<\/p>\n<p>Danach stellt die Prozedur die drei Felder <b>SuchenIn<\/b>, <b>Vergleichen <\/b>und <b>Suchen <\/b>auf den jeweiligen Standardwert ein und das Feld <b>Ersetzen <\/b>auf den aktuellen Wert der zuvor im <b>Beim &Ouml;ffnen<\/b>-Ereignis zugewiesenen Variablen <b>bolErsetzen<\/b>.<\/p>\n<p>Ist bereits ein passender Datensatz vorhanden, wird der Inhalt seines Feldes <b>SuchenUndErsetzenID <\/b>in die Variable <b>lngSuchenUndErsetzenID <\/b>eingetragen.<\/p>\n<p>Nun folgt das F&uuml;llen der beiden Kombinationsfelder <b>cboSuchenNach <\/b>und <b>cboErsetzenDurch<\/b>. Dazu filtern wir die Tabellen <b>tblSuchenNach <\/b>und <b>tblErsetzenDurch <\/b>mit den entsprechenden Werten f&uuml;r das Feld <b>KonfigurationID<\/b>.<\/p>\n<p>Schlie&szlig;lich stellt die Prozedur noch den Fokus auf die Schaltfl&auml;che <b>cmdWeitersuchen <\/b>ein und sorgt in Abh&auml;ngigkeit des Wertes von <b>bolErsetzen<\/b> daf&uuml;r, dass entweder die <b>Suchen<\/b>&#8211; oder die <b>Ersetzen<\/b>-Ansicht aktiviert wird &#8211; die beiden dazu aufgerufenen Prozeduren <b>regErsetzen_Click <\/b>und <b>regSuchen_Click <\/b>haben wir weiter oben bereits beschrieben.<\/p>\n<h2>Eintragen eines Suchtextes<\/h2>\n<p>Damit kommen wir zum Eintragen eines Suchtextes, der noch nicht in der Datensatzherkunft des Kombinationsfeldes <b>cboSuchenNach <\/b>enthalten ist. Dies l&ouml;st das Ereignis <b>Bei Nicht in Liste <\/b>aus, f&uuml;r das wir die Prozedur aus Listing 4 hinterlegen. Diese Prozedur liefert mit NewData den neu eingetragenen Wert und erwartet mit Response einen Parameter, mit dem wir die weitere Behandlung dieses Ereignisses definieren k&ouml;nnen.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cboSuchenNach_NotInList(NewData<span style=\"color:blue;\"> As String<\/span>, Response<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>dbc<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Set<\/span> dbc = CodeDb\r\n     <span style=\"color:blue;\">If <\/span>IsNull(Me.cboErsetzenDurch)<span style=\"color:blue;\"> Then<\/span>\r\n         dbc.Execute \"INSERT INTO tblSuchenNach(SuchenNach, KonfigurationID) VALUES(''\" & NewData & \"'', \" _\r\n             & Me.SuchenUndErsetzenID & \")\", dbFailOnError\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         dbc.Execute \"INSERT INTO tblSuchenNach(SuchenNach, ErsetzenDurchID, KonfigurationID) VALUES(''\" & NewData _\r\n             & \"'', \" & Me.cboErsetzenDurch & \", \" & Me.SuchenUndErsetzenID & \")\", dbFailOnError\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     Response = acDataErrAdded\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Prozedur beim Eintragen eines neuen Suchbegriffs<\/span><\/b><\/p>\n<p>Wir erstellen wieder ein <b>Database<\/b>-Objekt auf Basis der Add-In-Datenbank und pr&uuml;fen, ob es bereits einen Eintrag f&uuml;r das Kombinationsfeld <b>cboErsetzenDurch <\/b>gibt. Ist das nicht der Fall, schreiben wir mit einer <b>INSERT INTO<\/b>-Anweisung einfach einen neuen Datensatz in die Tabelle <b>tblSuchenNach<\/b>, der sowohl den neuen Wert aus <b>NewData <\/b>als auch die ID des verkn&uuml;pften Datensatzes der Tabelle <b>tblSuchenUndErsetzen <\/b>enth&auml;lt.<\/p>\n<p>Ist hingegen bereits ein Wert im Kombinationsfeld <b>cboErsetzenDurch <\/b>ausgew&auml;hlt, soll der neue Suchen-Eintrag direkt mit diesem verkn&uuml;pft werden. Wenn der Benutzer beim n&auml;chsten Mal diesen Eintrag ausw&auml;hlt, k&ouml;nnen wirgleich den passenden, zuletzt verwendeten Ersetzungstext liefern. Dazu verwenden wir eine entsprechende <b>INSERT INTO<\/b>-Abfrage und f&uuml;gen die Werte aus <b>NewData<\/b>, dem Kombinationsfeld <b>cboErsetzenDurch <\/b>und dem Feld <b>SuchenUndErsetzenID <\/b>ein.<\/p>\n<p>Schlie&szlig;lich stellen wir den R&uuml;ckgabeparameter <b>Response <\/b>auf den Wert <b>acDataErrAdded <\/b>ein, was bewirkt, dass der neue Eintrag direkt angezeigt wird.<\/p>\n<h2>Eintragen eines neuen Ersetzungstextes<\/h2>\n<p>Wenn der Benutzer einen neuen, noch nicht vorhandenen Wert in das Kombinationsfeld <b>cboErsetzenDurch <\/b>eintr&auml;gt, l&ouml;st dies das Ereignis <b>Bei Nicht in Liste <\/b>dieses Kombinationsfeldes aus (siehe Listing 5).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cboErsetzenDurch_NotInList(NewData<span style=\"color:blue;\"> As String<\/span>, Response<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>dbc<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Set<\/span> dbc = CodeDb\r\n     dbc.Execute \"INSERT INTO tblErsetzenDurch(ErsetzenDurch, KonfigurationID) VALUES(''\" & NewData & \"'', \" _\r\n         & Me.SuchenUndErsetzenID & \")\", dbFailOnError\r\n     Response = acDataErrAdded\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Prozedur beim Eintragen eines neuen Ersetzungstextes<\/span><\/b><\/p>\n<p>Diese Prozedur arbeitet &auml;hnlich wie die zuvor beschriebene, muss aber nur den neuen Wert aus dem Parameter <b>NewData <\/b>in die Tabelle <b>tblErsetzenDurch <\/b>eintragen &#8211; plus dem Verweis auf den entsprechenden Datensatz der Tabelle <b>tblSuchenUndErsetzen<\/b>.<\/p>\n<h2>Aktualisieren des Suchbegriffs<\/h2>\n<p>Wenn der Benutzer einen neuen Suchbegriff ausw&auml;hlt, l&ouml;st dies das Ereignis <b>Nach Aktualisierung <\/b>des Kombinationsfeldes <b>cboSuchenNach <\/b>aus, f&uuml;r das wir die Ereignisprozedur aus Listing 6 hinterlegen.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cboSuchenNach_AfterUpdate()\r\n     <span style=\"color:blue;\">Dim <\/span>dbc<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rstSuchenNach<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>lngErsetzenDurch<span style=\"color:blue;\"> As Variant<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> dbc = CodeDb\r\n     <span style=\"color:blue;\">Set<\/span> rstSuchenNach = dbc.OpenRecordset(\"SELECT * FROM tblSuchenNach WHERE SuchenNachID = \" _\r\n         & Nz(Me.cboSuchenNach, 0), dbOpenDynaset)\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rstSuchenNach.EOF<span style=\"color:blue;\"> Then<\/span>\r\n         lngErsetzenDurch = rstSuchenNach!ErsetzenDurchID\r\n         Me.cboErsetzenDurch = lngErsetzenDurch\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 6: Prozedur beim Ausw&auml;hlen eines anderen Suchbegriffs<\/span><\/b><\/p>\n<p>Hier wollen wir lediglich pr&uuml;fen, ob es f&uuml;r diesen Suchbegriff bereits einen entsprechenden Ersetzungstext gibt.<\/p>\n<p>Dazu durchsuchen wir die Tabelle <b>tblErsetzenDurch <\/b>nach einem entsprechenden Eintrag. Ist einer vorhanden, lesen wir den Prim&auml;rschl&uuml;sselwert in die Variable <b>varErsetzenDurch <\/b>ein und legen diese dann als Wert des Kombinationsfeldes <b>cboErsetzenDurch <\/b>fest, welches nun den entsprechenden Ersetzungstext anzeigt.<\/p>\n<h2>Ausw&auml;hlen eines anderen Ersetzungstextes<\/h2>\n<p>Wenn wir hingegen einen neuen Ersetzungstext ausw&auml;hlen, wollen wir daf&uuml;r sorgen, dass dieser dem Suchbegriff zugeordnet wird, damit dieser beim n&auml;chsten &Ouml;ffnen des <b>Suchen und Ersetzen<\/b>-Dialogs f&uuml;r die gleiche Datenblattansicht wiederhergestellt werden kann.<\/p>\n<p>Dazu ermitteln wir den aktuellen ID-Wert des Kombinationsfeldes <b>cboErsetzenDurch <\/b>und tragen diesen per <b>UPDATE<\/b>-Anweisung in den entsprechenden Datensatz der Tabelle <b>tblSuchenNach <\/b>ein (siehe Listing 7).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cboErsetzenDurch_AfterUpdate()\r\n     <span style=\"color:blue;\">Dim <\/span>dbc<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>lngErsetzenDurchID<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> dbc = CodeDb\r\n     lngErsetzenDurchID = Me.cboErsetzenDurch\r\n     dbc.Execute \"UPDATE tblSuchenNach SET ErsetzenDurchID = \" & lngErsetzenDurchID & \" WHERE SuchenNachID = \" _\r\n         & Me.cboSuchenNach, dbFailOnError\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Prozedur beim Ausw&auml;hlen eines anderen Ersetzungstextes<\/span><\/b><\/p>\n<h2>L&ouml;schen des aktuellen Eintrags im Suchfeld<\/h2>\n<p>Wenn der Benutzer die Schaltlf&auml;che <b>cmdSuchenNachLoeschen <\/b>bet&auml;tigt, soll der aktuelle Eintrag im Kombinationsfeld <b>cboSuchenNach <\/b>gel&ouml;scht werden.<\/p>\n<p>Das erledigen wir mit der Prozedur aus Listing 8.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdSuchenNachLoeschen_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>dbc<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Set<\/span> dbc = CodeDb\r\n     dbc.Execute \"DELETE FROM tblSuchenNach WHERE SuchenNachID = \" & Nz(Me.cboSuchenNach, 0), dbFailOnError\r\n     Me.cboSuchenNach.Requery\r\n     Me.cboSuchenNach = Null\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 8: Prozedur zum L&ouml;schen des aktuellen Suchbegriffs<\/span><\/b><\/p>\n<p>Die Prozedur ruft eine <b>DELETE<\/b>-Anweisung zum L&ouml;schen des aktuellen Eintrags des Kombinationsfeldes auf. Sollte dieses leer sein, l&auml;uft diese Anweisung ins Leere, da dann der Wert <b>0 <\/b>f&uuml;r den Vergleichswert mit dem Feld <b>SuchenNachID<\/b> &uuml;bergeben wird.<\/p>\n<p>Anschlie&szlig;end aktualisieren wir die Datensatzherkunft des Kombinationsfeldes und leeren dieses durch Einstellen auf den Wert <b>Null<\/b>. Dies ist notwendig, weil dieses gegebenenfalls noch den vorher ausgew&auml;hlten Wert enth&auml;lt.<\/p>\n<h2>L&ouml;schen des aktuellen Eintrags im Ersetzungsfeld<\/h2>\n<p>Etwas komplizierter ist das L&ouml;schen des aktuellen Eintrags im Kombinationsfeld <b>cboErsetzenDurch<\/b>. Wenn wir diesen Eintrag einfach l&ouml;schen, wird der damit verkn&uuml;pfte Datensatz der Tabelle <b>tblSuchenNach <\/b>ebenfalls gel&ouml;scht, weil hier die L&ouml;schweitergabe greift.<\/p>\n<p>Da wir diesen Wert behalten wollen, leeren wir zuvor das Feld <b>ErsetzenDurchID <\/b>f&uuml;r den Datensatz der Tabelle <b>tblSuchenNach<\/b>, der aktuell im Kombinationsfeld <b>cboSuchenNach <\/b>angezeigt wird.<\/p>\n<p>Danach k&ouml;nnen wir den aktuellen Eintrag des Kombinationsfeldes <b>cboErsetzenDurch <\/b>l&ouml;schen. Schlie&szlig;lich aktualisieren wir die Datensatzherkunft dieses Kombinationsfeldes und stellen dieses auf <b>Null <\/b>ein (siehe Listing 9).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdErsetzenDurchLoeschen_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>dbc<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Set<\/span> dbc = CodeDb\r\n     dbc.Execute \"UPDATE tblSuchenNach SET ErsetzenDurchID = NULL WHERE SuchenNachID = \" & Nz(Me.cboSuchenNach, 0), _\r\n         dbFailOnError\r\n     dbc.Execute \"DELETE FROM tblErsetzenDurch WHERE ErsetzenDurchID = \" & Nz(Me.cboErsetzenDurch, 0), dbFailOnError\r\n     Me.cboErsetzenDurch.Requery\r\n     Me.cboErsetzenDurch = Null\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 9: Prozedur zum L&ouml;schen des aktuellen Ersetzungstexts<\/span><\/b><\/p>\n<p>Damit ist Funktionalit&auml;t des Formulars fast vollst&auml;ndig. Wir ben&ouml;tigen allerdings noch die eigentlichen Funktionen zum Suchen und Ersetzen. Da dieses Thema recht komplex ist, behandeln wir es in einem weiteren Teil zur Erstellung der Suchen und Ersetzen-Schaltfl&auml;che.<\/p>\n<h2>Umwandeln in ein Access-Add-In<\/h2>\n<p>Wir schauen uns allerdings noch an, wie wir ein Access-Add-In aus der Datenbank erzeugen. In diesem Fall reicht uns dazu das &Auml;ndern der Dateiendung in <b>.accda <\/b>aus. Insgesamt soll der Dateiname nun <b>amvSuchenUndErsetzen.accda <\/b>lauten.<\/p>\n<p>Warum ben&ouml;tigen wir nicht die &uuml;brigen Elemente wie beispielsweise die Tabelle <b>USysRegInfo<\/b>, die wir normalerweise anlegen, damit das Access-Add-In beim Registrieren &uuml;ber den Add-In-Manager in die Registry eingetragen wird und anschlie&szlig;end &uuml;ber das Add-Ins-Men&uuml; aufgerufen werden kann?<\/p>\n<p>Weil wir dieses Add-In gar nicht &uuml;ber diesen Befehl aufrufen wollen, sondern einen eigenen Eintrag im Ribbon daf&uuml;r anlegen wollen. Dieser soll direkt neben den eingebauten Ribbonbefehlen zum Aufrufen der Suchen- und der Ersetzen-Funktionen von Access integriert werden.<\/p>\n<p>Alles, was wir in der vorliegenden Datenbank noch erledigen m&uuml;ssen, ist das bereitstellen zweier &ouml;ffentlich deklarierter Funktionen, mit denen wir das Formular &ouml;ffnen. Diese sehen wir folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>amvSuchen()\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     DoCmd.OpenForm \"frmSuchenUndErsetzen\"\r\n     Select Case Err.Number\r\n         <span style=\"color:blue;\">Case <\/span>2501\r\n         <span style=\"color:blue;\">Case <\/span>0\r\n         <span style=\"color:blue;\">Case Else<\/span>\r\n             <span style=\"color:blue;\">MsgBox<\/span> Err.Number & \" \" & Err.Description\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Function<\/span>\r\n<span style=\"color:blue;\">Public Function <\/span>amvErsetzen()\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     DoCmd.OpenForm \"frmSuchenUndErsetzen\", _\r\n         OpenArgs:=\"Ersetzen\"\r\n     Select Case Err.Number\r\n         <span style=\"color:blue;\">Case <\/span>2501\r\n         <span style=\"color:blue;\">Case <\/span>0\r\n         <span style=\"color:blue;\">Case Else<\/span>\r\n             <span style=\"color:blue;\">MsgBox<\/span> Err.Number & \" \" & Err.Description\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Warum deaktivieren wir hier die Fehlerbehandlung? Weil es sein kann, dass das &Ouml;ffnen des Formulars abgebrochen wird &#8211; beispielsweise, weil aktuell keine Datenblattansicht den Fokus hat.<\/p>\n<p>Wenn wir den Aufruf eines Formulars mit <b>DoCmd.OpenForm <\/b>abbrechen, l&ouml;st dies den Fehler <b>2501 <\/b>aus. Die Anzeige der entsprechenden Fehlermeldung wollen wir hier jedoch unterbinden und zeigen nur Fehler mit anderen Fehlernummern als <b>2501 <\/b>in einer Meldung an.<\/p>\n<p>Die Funktionen <b>amvSuchen <\/b>und <b>amvErsetzen <\/b>k&ouml;nnen wir nun von externen Datenbanken aus aufrufen.<\/p>\n<p>Das sieht beispielsweise wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Suchen()\r\n     Application.Run CurrentProject.Path _\r\n         & \"\\amvSuchenUndErsetzen.amvSuchen\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Mit dieser Funktion rufen wir die <b>Run<\/b>-Methode des <b>Application<\/b>-Objekts auf. Wenn wir hier den Pfad einer Datenbank angeben und statt der Dateiendung den Namen einer in dieser Datenbank aufzurufenden Funktion angeben, wird diese ausgef&uuml;hrt.<\/p>\n<p>Die einzigen beiden Voraussetzungen sind:<\/p>\n<ul>\n<li>Die Datenbankdatei hat die Dateiendung <b>.accda<\/b>.<\/li>\n<li>Die aufzurufende Routine ist als &ouml;ffentliche <b>Function<\/b>-Prozedur deklariert.<\/li>\n<\/ul>\n<p>Damit k&ouml;nnen wir den <b>Suchen und Ersetzen<\/b>-Dialog grunds&auml;tzlich erst einmal von jeder anderen Datenbank aus ausrufen. Aber wer will schon immer diesen Befehl ausf&uuml;hren?<\/p>\n<p>Deshalb werden wir in einem weiteren Teil dieser L&ouml;sung noch zeigen, wie wir ein COM-Add-In speziell f&uuml;r den <b>Suchen und Ersetzen<\/b>-Dialog erstellen, mit dem wir Access zwei Schaltfl&auml;chen zum Aufrufen des Dialogs hinzuf&uuml;gen.<\/p>\n<p>Dieser Beitrag hei&szlig;t <b>Suchen und Ersetzen mit COM-Add-In <\/b>(<b>www.access-im-unternehmen.de\/1555<\/b>).<\/p>\n<p>In einem letzten Beitrag zu diesem Thema erl&auml;utern wir noch, wie die hier verwendeten Funktionen zum Durchsuchen des Recordsets der aktuellen Datenblattansicht funktionieren: <b>Besserer &#8222;Suchen und Ersetzen&#8220;-Dialog: Funktionen <\/b>(<b>www.access-im-unternehmen.de\/1561<\/b>).<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>amvSuchenUndErsetzen.accda<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/3C716B8D-12DF-4347-863B-AF5391AFDF85\/aiu_1560.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Der Dialog zum Suchen und Ersetzen f&uuml;r die Suche nach Daten in der Datenblattansicht ist bereits sehr praktisch. Allerdings hatte ein Leser die Anforderung, dass er &ouml;fter mit dem Dialog nach den gleichen Ausdr&uuml;cken sucht, um diese zu ersetzen. Der Dialog hat zwar immer die zuletzt verwendeten zu suchenden und zu ersetzenden Ausdr&uuml;cke gespeichert und in den Auswahlfeldern angeboten, aber wenn er die Datenbank geschlossen und erneut ge&ouml;ffnet hat, war die Arbeit verloren und die Auswahlfelder waren wieder leer. Also bauen wir diesen Dialog einfach nach und erweitern diesen um eine Funktion, welche die zuletzt verwendeten Eintr&auml;ge dauerhaft speichert und diese nach dem Schlie&szlig;en und &Ouml;ffnen der Anwendung wieder bereitstellt.<\/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":[662025,66042025,44000028],"tags":[],"class_list":["post-55001560","post","type-post","status-publish","format-standard","hentry","category-662025","category-66042025","category-Ergonomie_und_Benutzeroberflaeche"],"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>Optimierter &quot;Suchen und Ersetzen&quot;-Dialog: Grundger&uuml;st - 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\/Optimierter_Suchen_und_ErsetzenDialog_Grundgeruest\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Optimierter &quot;Suchen und Ersetzen&quot;-Dialog: Grundger&uuml;st\" \/>\n<meta property=\"og:description\" content=\"Der Dialog zum Suchen und Ersetzen f&uuml;r die Suche nach Daten in der Datenblattansicht ist bereits sehr praktisch. Allerdings hatte ein Leser die Anforderung, dass er &ouml;fter mit dem Dialog nach den gleichen Ausdr&uuml;cken sucht, um diese zu ersetzen. Der Dialog hat zwar immer die zuletzt verwendeten zu suchenden und zu ersetzenden Ausdr&uuml;cke gespeichert und in den Auswahlfeldern angeboten, aber wenn er die Datenbank geschlossen und erneut ge&ouml;ffnet hat, war die Arbeit verloren und die Auswahlfelder waren wieder leer. Also bauen wir diesen Dialog einfach nach und erweitern diesen um eine Funktion, welche die zuletzt verwendeten Eintr&auml;ge dauerhaft speichert und diese nach dem Schlie&szlig;en und &Ouml;ffnen der Anwendung wieder bereitstellt.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Optimierter_&quot;Suchen_und_Ersetzen&quot;Dialog_Grundgeruest\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2025-08-03T11:26:12+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg01.met.vgwort.de\/na\/c654ed641eb94dd4b2704416b4e33c83\" \/>\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=\"32\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Optimierter &#8222;Suchen und Ersetzen&#8220;-Dialog: Grundger&uuml;st\",\"datePublished\":\"2025-08-03T11:26:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/\"},\"wordCount\":5722,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/c654ed641eb94dd4b2704416b4e33c83\",\"articleSection\":[\"2025\",\"4\\\/2025\",\"Ergonomie und Benutzeroberfl\u00e4che\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/\",\"name\":\"Optimierter \\\"Suchen und Ersetzen\\\"-Dialog: Grundger&uuml;st - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/c654ed641eb94dd4b2704416b4e33c83\",\"datePublished\":\"2025-08-03T11:26:12+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/c654ed641eb94dd4b2704416b4e33c83\",\"contentUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/c654ed641eb94dd4b2704416b4e33c83\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Optimierter_\\\"Suchen_und_Ersetzen\\\"Dialog_Grundgeruest\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Optimierter &#8222;Suchen und Ersetzen&#8220;-Dialog: Grundger&uuml;st\"}]},{\"@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":"Optimierter \"Suchen und Ersetzen\"-Dialog: Grundger&uuml;st - 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\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/","og_locale":"de_DE","og_type":"article","og_title":"Optimierter \"Suchen und Ersetzen\"-Dialog: Grundger&uuml;st","og_description":"Der Dialog zum Suchen und Ersetzen f&uuml;r die Suche nach Daten in der Datenblattansicht ist bereits sehr praktisch. Allerdings hatte ein Leser die Anforderung, dass er &ouml;fter mit dem Dialog nach den gleichen Ausdr&uuml;cken sucht, um diese zu ersetzen. Der Dialog hat zwar immer die zuletzt verwendeten zu suchenden und zu ersetzenden Ausdr&uuml;cke gespeichert und in den Auswahlfeldern angeboten, aber wenn er die Datenbank geschlossen und erneut ge&ouml;ffnet hat, war die Arbeit verloren und die Auswahlfelder waren wieder leer. Also bauen wir diesen Dialog einfach nach und erweitern diesen um eine Funktion, welche die zuletzt verwendeten Eintr&auml;ge dauerhaft speichert und diese nach dem Schlie&szlig;en und &Ouml;ffnen der Anwendung wieder bereitstellt.","og_url":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/","og_site_name":"Access im Unternehmen","article_published_time":"2025-08-03T11:26:12+00:00","og_image":[{"url":"http:\/\/vg01.met.vgwort.de\/na\/c654ed641eb94dd4b2704416b4e33c83","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"32\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Optimierter &#8222;Suchen und Ersetzen&#8220;-Dialog: Grundger&uuml;st","datePublished":"2025-08-03T11:26:12+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/"},"wordCount":5722,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/c654ed641eb94dd4b2704416b4e33c83","articleSection":["2025","4\/2025","Ergonomie und Benutzeroberfl\u00e4che"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/","url":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/","name":"Optimierter \"Suchen und Ersetzen\"-Dialog: Grundger&uuml;st - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/c654ed641eb94dd4b2704416b4e33c83","datePublished":"2025-08-03T11:26:12+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/#primaryimage","url":"http:\/\/vg01.met.vgwort.de\/na\/c654ed641eb94dd4b2704416b4e33c83","contentUrl":"http:\/\/vg01.met.vgwort.de\/na\/c654ed641eb94dd4b2704416b4e33c83"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Optimierter_\"Suchen_und_Ersetzen\"Dialog_Grundgeruest\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Optimierter &#8222;Suchen und Ersetzen&#8220;-Dialog: Grundger&uuml;st"}]},{"@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\/55001560","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=55001560"}],"version-history":[{"count":1,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001560\/revisions"}],"predecessor-version":[{"id":88075939,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001560\/revisions\/88075939"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001560"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001560"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001560"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}