Optimierter „Suchen und Ersetzen“-Dialog: Grundgerüst

Der Dialog zum Suchen und Ersetzen für die Suche nach Daten in der Datenblattansicht ist bereits sehr praktisch. Allerdings hatte ein Leser die Anforderung, dass er öfter mit dem Dialog nach den gleichen Ausdrücken sucht, um diese zu ersetzen. Der Dialog hat zwar immer die zuletzt verwendeten zu suchenden und zu ersetzenden Ausdrücke gespeichert und in den Auswahlfeldern angeboten, aber wenn er die Datenbank geschlossen und erneut geö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äge dauerhaft speichert und diese nach dem Schließen und Öffnen der Anwendung wieder bereitstellt.

Worum geht es?

Der Suchen und Ersetzen-Dialog, den wir durch einen besseren Dialog ersetzen wollen, kann über den Ribbon-Eintrag Start|Suchen|Suchen geöffnet werden (siehe Bild 1).

Aufruf des Suchen und Ersetzen-Dialogs

Bild 1: Aufruf des Suchen und Ersetzen-Dialogs

Dies öffnet den Dialog mit aktiviertem Suchen-Registerreiter (siehe Bild 2). Hier können wir nacheinander nach verschiedenen Begriffen suchen. Die zuletzt verwendeten Begriffe werden beim Aufklappen der Auswahl unter Suchen nach: direkt bereitgestellt.

Der Suchen und Ersetzen-Dialog

Bild 2: Der Suchen und Ersetzen-Dialog

Wir können direkt von diesem Dialog aus zur Registerseite Ersetzen wechseln. Diese enthält lediglich einige zusätzliche Elemente wie zum Beispiel das Feld zum Eingeben des zu ersetzenden Ausdrucks (siehe Bild 3). Außerdem finden wir nun Schaltfläche zum Ersetzen der aktuellen Fundstelle und aller Fundstellen.

Registerseite Ersetzen des Suchen und Ersetzen-Dialogs

Bild 3: Registerseite Ersetzen des Suchen und Ersetzen-Dialogs

Der Dialog kann außerdem mit der Taste Strg + F geöffnet werden.

Option „Suchen in“

Der Dialog erlaubt mit Suchen in das Festlegen des Suchziels:

  • Aktuelles Feld: Durchsucht nur das aktuelle Steuerelement. Bei Datenblatt- oder Endlosansichten bezieht sich das auf das gleiche Steuerelement für jeden Datensatz.
  • Aktuelles Dokument: Durchsucht alle Steuerelemente und Datensätze der aktuellen Ansicht. Dabei wird zuerst Steuerelement für Steuerelement des aktuellen Datensatzes durchsucht und dann folgen die folgenden Datensätze.

Option „Vergleichen“

Mit Vergleichen können wir angeben, welcher Teil der Felder untersucht werden soll: Teil des Feldinhalts, Ganzes Feld oder Anfang des Feldinhalts.

Option „Suchen“

Unter Suchen geben wir an, welchen Bereich wir ausgehend vom aktuell markierten Steuerelement untersuchen wollen:

  • Alle: Durchsucht von oben nach unten und beginnt von vorn, wenn sich noch Elemente vor dem aktuellen Steuerelement befinden.
  • Aufwärts: Sucht von der aktuellen Position bis zum Start des Dokuments.
  • Abwärts: Sucht von der aktuellen Position bis zum Ende des Dokuments.

Option „Groß-/Kleinschreibung“

Mit Groß-/Kleinschreibung können wir angeben, ob wir Groß- und Kleinschreibung berücksichtigen wollen.

Option „Formatierung beachten“

Schließlich gibt es noch die Option Formatierung beachten. 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 tt.mm.jjjj speichern (zum Beispiel 21.06.2025), aber für das Tabellenfeld das Format tt-mm-jjjj festgelegt haben, wird das Datum als 21-06-2025 angezeigt.

Eine Suche nach 21.06. liefert nun in jedem Fall das gesuchte Datum. Wenn wir jedoch nach 21-06- suchen und Formatierung beachten ist deaktiviert, finden wir das Datum nicht.

Erst wenn wir Formatierung beachten aktivieren, liefert auch 21-06- das gewünschte Ergebnis.

Schaltfläche „Weitersuchen“

Mit der Schaltfläche Weitersuchen starten wir den Suchvorgang nach dem nächsten Vorkommen. Klicken wir diese wiederholt an, durchläuft Access alle Fundstellen.

Schaltfläche „Ersetzen“

Diese Schaltfläche funktioniert nur, wenn zuvor mit Weitersuchen eine Fundstelle markiert wurde. Das Anklicken führt dann zur gewünschten Ersetzung und markiert automatisch die nächste Fundstelle, sofern noch ein weiteres Vorkommen vorhanden ist.

So können wir durch wiederholtes Betätigen dieser Schaltfläche alle Vorkommen des gesuchten Begriffes ersetzen.

Schaltfläche „Alle ersetzen“

Diese Schaltfläche ersetzt automatisch alle Vorkommen im angegebenen Bereich. Dazu muss nicht zuvor ein Vorkommen markiert worden sein.

Wichtig: Lassen sich die grundlegenden Funktionen reproduzieren?

Bevor wir Zeit investieren, den Suchen und Ersetzen-Dialog original nachzubilden und diesen um die gewünschten Funktionen zu erweitern, wollen wir erst einmal prüfen, ob sich das grundlegende Verhalten überhaupt reproduzieren lässt.

Um per VBA-Code zum Beispiel nach bestimmten Inhalten im Datenblatt zu suchen, müssen wir das Recordset des Datenblatts referenzieren. Die Frage lautet: Gelingt das überhaupt per Code? Haben jegliche Datenblätter ein Recordset, auf das wir zugreifen können – 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önnen.

Hier referenzieren wir das Formular über die Forms-Auflistung und greifen dann über die Recordset-Eigenschaft auf das Recordset zu. Aber wie soll das mit Tabellen und Abfragen funktionieren? Immerhin gibt es keine Table– oder Query-Auflistungen, die wir analog zur Forms-Auflistung nutzen könnten.

Aber benötigen wir überhaupt eine Auflistung, um auf das aktuelle Objekt und sein Recordset zugreifen zu können?

Schnelle Experimente zeigen: Nein, das ist nicht der Fall. Wie können nämlich die Elemente der Screen-Klasse nutzen.

Per Screen-Klasse auf das aktuelle Datenblatt zugreifen

Wir schauen uns dies zuerst anhand einer Tabelle an, die wir in der Datenblattansicht geöffnet haben.

Öffnen wir parallel dazu den Direktbereich des VBA-Editors und geben dort den Ausdruck Screen.ActiveDatasheet.Name ein, erhalten wir tatsächlich den Namen des aktuellen Datenblatts respektive der zugrunde liegenden Tabelle (siehe Bild 4).

Zugriff per VBA auf das aktuelle Datenblatt einer Tabelle

Bild 4: Zugriff per VBA auf das aktuelle Datenblatt einer Tabelle

Also probieren wir auch gleich aus, ob wir damit auch auf ein entsprechendes Recordset-Objekt zugreifen können. Auch das gelingt:

  Screen.ActiveDatasheet.Recordset.RecordCount
  100 

Das Gleiche funktioniert auch, wenn wir eine Abfrage in der Datenblattansicht öffnen.

Zugriff auf das Datenblatt eines Formulars

Bei Formularen müssen wir differenzieren. Wir können hier Formular vorfinden, die ihre Daten direkt in der Datenblattansicht anzeigen oder solche, die Unterformulare für die Datenblattansicht verwenden.

Bei Formularen, die ihre Daten direkt in der Datenblattansicht anzeigen, können wir ebenfalls mit Screen.ActiveDatasheet arbeiten.

Bei Formularen, die ein Unterformular in der Datenblattansicht anzeigen, gelingt dies nicht so einfach, wie Bild 5 zeigt. Hier erhalten wir eine Fehlermeldung.

Fehler beim Zugriff per VBA auf das aktuelle Datenblatt im Unterformular

Bild 5: Fehler beim Zugriff per VBA auf das aktuelle Datenblatt im Unterformular

Wir können auch nicht mit der folgenden Anweisung darauf zugreifen – hier erhalten wir lediglich das Hauptformular:

  Screen.ActiveForm.Name
frmMitarbeiterUebersicht

Wenn sich der Fokus jedoch in einem der Steuerelemente im Unterformular befindet, können wir am einfachsten über folgenden Ausdruck darauf zugreifen:

  Screen.ActiveControl.Parent.Name
sfmMitarbeiterUebersicht

Mehr als nur Datenblatt

Allerdings funktioniert die Originalfunktion nicht nur in Datenblättern, sondern eigentlich in allen Formularen, die überhaupt mindestens ein Steuerelement enthalten, das durchsuchbar ist – also zum Beispiel ein Textfeld. Wir wollen in diesem Beispiel allerdings nur eine Suchen und Ersetzen-Funktion für Datenblätter erstellen.

Weitere Erweiterungsmöglichkeiten

Wenn wir schon dabei sind, den Suchen und Ersetzen-Dialog zu verbessern, können wir auch gleich noch weitere Ergänzungen hinzufügen.

Zum Beispiel könnten wir den Dialog so programmieren, dass er beim Öffnen gleich den Wert im Suchen-Feld anzeigt, der im aktuellen Steuerelement mit dem Fokus enthalten ist – vorausgesetzt, dieses Feld enthält einen Wert beziehungsweise kann einen Wert enthalten.

Ersetzen von Werten

Beim Ersetzen von Werten benötigen wir ein wenig mehr Code. Wir müssen aus den Parametern des Dialogs eine kleine Prozedur erstellen, die eine UPDATE-Anweisung zusammenbaut und ausführt. Dies schauen wir uns später im Detail an.

„Suchen und Ersetzen“-Formular nachbauen

Nachdem die technischen Voraussetzungen geklärt sind, bauen wir das Suchen und Ersetzen-Formular originalgetreu nach.

Dazu erstellen wir ein neues, leeres Formular und speichern es unter dem Namen frmSuchenUndErsetzen. Um es später vom eingebauten Suchen-Dialog unterscheiden zu können, tragen wir für Beschriftung den Text Suchen und Ersetzen PRO ein.

Dann fügen wir erst einmal die Steuerelemente hinzu und legen ihre Namen fest.

Wichtig: Wir fügen kein echtes Registersteuerelement hinzu, denn eigentlich benötigen wir kein Registersteuerelement.

Wir haben nicht geprüft, ob Microsoft für den Suchen und Ersetzen-Dialog tatsä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.

Dazu verwenden wir ein weißes Rechteck und zwei Schaltflächen, die wir über diesem Rechteck platzieren – genau so, dass der untere Rand der Schaltflächen etwas unter dem Rechteck verschwindet. Dazu müssen wir zuerst die Schaltflächen anlegen und dann das Rechteck-Steuerelement. In der Z-Reihenfolge werden immer die zuletzt angelegten Steuerelemente über die übrigen gelegt.

Dementsprechend fügen wir auch die übrigen Steuerelemente erst hinzu, wenn wir das Rechteck angelegt haben, und ordnen diese wie in Bild 6 an.

Entwurf des neuen Suchen und Ersetzen-Dialogs

Bild 6: Entwurf des neuen Suchen und Ersetzen-Dialogs

Die Steuerelemente versehen wir mit den folgenden Namen:

  • Registertag Suchen: regSuchen
  • Register-Schaltfläche Ersetzen: regErsetzen
  • Kombinationsfeld Suchen nach: cboSuchenNach
  • Kombinationsfeld Ersetzen durch: cboErsetzenDurch
  • Kombinationsfeld Suchen in: cboSuchenIn
  • Kombinationsfeld Vergleichen: cboVergleichen
  • Kombinationsfeld Suchen: cboSuchen
  • Kontrollkästchen Groß-/Kleinschreibung beachten: chkGrossKleinschreibungBeachten
  • Kontrollkästchen FormatierungBeachten: chkFormatierungBeachten
  • Schaltfläche Weitersuchen: cmdWeitersuchen
  • Schaltfläche Abbrechen: cmdAbbrechen
  • Schaltfläche Ersetzen: cmdErsetzen
  • Schaltfläche Alle ersetzen: cmdAlleErsetzen

Für die Schaltflächen fügen wir passende Icons hinzu, indem wir die jeweilige Schaltfläche markieren und dann den Ribbonbefehl Formularentwurf|Steuerlemente|Bild einfügen nutzen.

Den Hintergrund der Schaltflächen stellen wir auf Transparent ein, die Anordnung der Bildbeschriftung auf Rechts und die Schriftbreite für alle außer der nicht markierten Registerschaltfläche auf Fett.

Außerdem fügen wir vor der Eigenschaft Beschriftung der Schaltflächen jeweils zwei Leerzeichen ein, damit die Beschriftung nicht zu nah an den Icons erscheint.

Da das Formular selbst keine Datensatzquelle hat, stellen wir die Eigenschaften Datensatzmarkierer, Navigationsschaltflächen und Bildlaufleisten auf Nein und Automatisch zentrieren auf Ja ein.

Schaltflächen zum Entfernen von Such- und Ersetzungstexten

Die beiden Kombinationsfelder Suchen nach und Ersetzen durch sollen die bisher eingegebenen Texte anzeigen.

Damit der Benutzer auch mal einen der eingegebenen Texte entfernen kann, wollen wir außerdem noch zwei Schaltflächen zum Löschen des aktuell ausgewählten Eintrags hinzufügen.

Diese erhalten die Namen cmdSuchenNachLoeschen und cmdErsetzenDurchLoeschen. Danach sieht der Entwurf wie in Bild 7 aus. Die Funktionalität dieser Schaltflächen fügen wir später hinzu.

Schaltflächen zum Leeren

Bild 7: Schaltflächen zum Leeren

Bei Eingabetaste automatisch suchen

Wenn der Benutzer die Eingabetaste betätigt, soll die Schaltfläche cmdWeitersuchen ausgelöst werden. Dazu stellen wir die Eigenschaft Standard für diese Schaltfläche auf Ja ein.

Leider funktioniert das nicht, wenn der Fokus auf einer der übrigen Schaltflächen liegt. Dann wird die jeweils aktive Schaltfläche ausgeführt. Also müssen wir für die übrigen Tasten noch das Ereignis Bei Taste Ab definieren und hier prüfen, ob der Benutzer für diese die Eingabetaste betätigt hat. Ist das der Fall, soll die Ereignisprozedur der Schaltfläche cmdWeitersuchen ausgelöst werden. Dazu hinterlegen wir zunächst die entsprechende Ereignisprozedur, die wir allerdings erst einmal mit einer Dummy-Meldung füllen:

Private Sub cmdWeitersuchen_Click()
     MsgBox "Weitersuchen"
End Sub

Für die übrigen Schaltflächen legen wir nun jeweils eine Prozedur für das Ereignis Bei Taste Ab an, die wir wie folgt füllen:

Private Sub regSuchen_KeyDown(KeyCode As Integer, _
         Shift As Integer)
     Select Case KeyCode
         Case 13
             KeyCode = 0
             Call cmdWeitersuchen_Click
     End Select
End Sub

Damit führt das Betätigen der Eingabetaste nun immer die Taste cmdWeitersuchen aus.

Bei Escape-Taste automatisch schließen

Betätigt der Benutzer die Escape-Taste, soll der Suchen und Ersetzen-Dialog geschlossen werden. Dazu stellen wir die Eigenschaft Abbrechen für diese Schaltfläche auf Ja ein.

Die Ereignisprozedur für diese Schaltfläche können wir gleich anlegen. Sie lautet:

Private Sub cmdAbbrechen_Click()
     DoCmd.Close acForm, Me.Name
End Sub

Kombinationsfelder füllen

Nun füllen wir die Kombinationsfelder, zunächst die drei unteren – diese nehmen jeweils eine Wertliste auf.

Das Kombinationsfeld cboSuchenIn erhalt diese Werteliste:

"Aktuelles Feld";"Aktuelles Dokument"

Damit diese angezeigt wird, stellen wir außerdem die Eigenschaft Herkunftsart auf Wertliste ein. Außerdem wollen wir verhindern, dass der Benutzer die Wertliste bearbeiten kann und legen daher noch den Wert Nein für die Eigenschaft Wertlistenbearbeitung zulassen fest (siehe Bild 8).

Einstellen der Werte für die Kombinationsfelder

Bild 8: Einstellen der Werte für die Kombinationsfelder

Die Einstellungen für die weiteren beiden Kombinationsfelder sind weitgehend identisch. Lediglich die Datensatzherkünfte unterscheiden sich. Die für das Kombinationsfeld cboVergleichen lautet:

"Teil des Feldinhalts";"Ganzes Feld";"Anfang des Feldinhalts"

Und für cboSuchen verwenden wir:

"Alle";"Aufwärts";"Abwärts"

Schließlich wollen wir noch dafür sorgen, dass alle drei Kombinationsfelder jeweils den ersten Eintrag bei Öffnen des Formulars anzeigen. Außerdem soll die Schaltfläche cmdWeitersuchen immer direkt den Fokus erhalten. Dazu fügen wir dem Formular eine Ereignisprozedur für das Ereignis Beim Laden hinzu, die wie folgt aussieht:

Private Sub Form_Load()
     Me.cboSuchenIn = Me.cboSuchenIn.ItemData(0)
     Me.cboVergleichen = Me.cboVergleichen.ItemData(0)
     Me.cboSuchen = Me.cboSuchen.ItemData(0)
     Me.cmdWeitersuchen.SetFocus 
End Sub

Damit erhalten wir nun das Zwischenergebnis aus Bild 9.

Kombinationsfeld in Aktion

Bild 9: Kombinationsfeld in Aktion

Registerseiten programmieren

Hier sehen wir allerdings, dass trotz der Aktivierung der Schaltfläche für die Registerseite Suchen auch die Steuerelemente angezeigt werden, die erst für die Registerseite Ersetzen eingeblendet werden sollen. Das ändern wir durch jeweils eine Ereignisprozedur für die beiden Registerschaltflächen.

Klickt der Benutzer auf regErsetzen, sollen das Kombinationsfeld cboErsetzen und die beiden Schaltflächen cmdErsetzen und cmdAlleErsetzen eingeblendet werden. Außerdem soll die Schrift der Schaltfläche regSuchen nicht mehr fett dargestellt werden, dafür aber die der Schaltfläche cmdErsetzen.

Und schließlich wird der Wert des Feldes Ersetzen der zugrunde liegenden Tabelle tblSuchenUndErsetzen auf True eingestellt, damit dieser Zustand später wiederhergestellt werden kann:

Private Sub regErsetzen_Click()
     Me.cboErsetzenDurch.Visible = True
     Me.cmdErsetzen.Visible = True
     Me.cmdAlleErsetzen.Visible = True
     Me.regSuchen.FontBold = 0
     Me.regErsetzen.FontBold = 1
     Me!Ersetzen = True
End Sub

Die Schaltfläche regSuchen soll den umgekehrten Effekt bewirken:

Private Sub regSuchen_Click()
     Me.cboErsetzenDurch.Visible = False
     Me.cmdErsetzen.Visible = False
     Me.cmdAlleErsetzen.Visible = False
     Me.regSuchen.FontBold = 1
     Me.regErsetzen.FontBold = 0
     Me!Ersetzen = False
End Sub

Wir müssen außerdem noch dafür sorgen, dass das Kombinationsfeld cboErsetzen sowie die beiden Schaltflächen cmdErsetzen und cmdAlleErsetzen zunächst ausgeblendet sind – das erledigen wir durch Einstellen der entsprechenden Eigenschaften im Eigenschaftenblatt.

Formular in verschiedenen Modi öffnen

Standardmäßig öffnet das Formular nun im Modus Suchen. Da wir das Formular jedoch auch direkt zum Ersetzen öffnen wollen, fügen wir dem Ereignis Beim Öffnen noch die Abfrage nach dem Öffnungsargument hinzu. Lautet dies Ersetzen, soll das Formular direkt für das Ersetzen vorbereitet werden.

Zunächst einmal soll das Öffnen des Formulars für diesen Modus so erfolgen:

DoCmd.OpenForm "frmSuchenUndErsetzen", OpenArgs:="Ersetzen"

In der Ereignisprozedur, die wir für das Ereignis Beim Öffnen aufrufen, fügen wir nun diese Anweisungen hinzu:

Private Sub Form_Open(Cancel As Integer)
     If Not IsNull(Me.OpenArgs) Then
         If Me.OpenArgs = "Ersetzen" Then
             Call regErsetzen_Click
         End If
     End If
End Sub

Damit wird die Prozedur regErsetzen_Click aufgerufen, wenn als Öffnungsparameter Ersetzen übergeben wurde.

Nach dem Öffnen im Suchen-Modus sieht das Formular nun wie in Bild 10 aus.

Formular nach dem Öffnen im Suchen-Modus

Bild 10: Formular nach dem Öffnen im Suchen-Modus

Verwalten der Suchen- und Ersetzen-Werte

Der eigentliche Clou des neuen Suchen und Ersetzen-Formulars soll das Speichern der verwendeten Einträge für die Kombinationsfelder Suchen nach und Ersetzen durch sein. Hier stellt sich die Frage, wo wir diese Einträge speichern sollen. Wir könnten das in einer oder mehreren Tabellen oder in der Registry erledigen.

Praktischer wären Tabellen, da wir hier die Daten direkt nach den gewünschten Kriterien sortieren könnten.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar