Flexible Suche in Formularen

Es gibt viele Möglichkeiten, eine Suche über die Datensätze einer Tabelle zu programmieren. Wir wollen in diesem Beitrag eine sehr flexible Variante vorstellen. Damit können Sie sowohl einfach Suchbegriffe eingeben, mit denen dann alle für die Suche angegebenen Felder durchsucht werden. Andererseits soll die Suche auch das gezielte Ermitteln von Datensätzen ermöglichen, deren Felder bestimmte Werte enthalten. Um die Angabe der Feldnamen zu vereinfachen, haben wir der Suche auch noch eine Funktion zur Autovervollständigung hinzugefügt.

Vorweg ist zu erwähnen, dass wir hier keine Suchfunktion mit nicht überschaubaren Möglichkeiten produzieren möchten. Vielmehr soll sie sich an der Praxis orientieren – in diesem Fall an meiner Praxis. Mein Bedarf an einer Suchfunktion, speziell an der hier vorgestellten, resultiert aus einer wachsenden Kundendatenbank.

Früher verwendete ich eine Suchfunktion, die bestimmte Felder nach dem angegebenen Suchbegriff durchforstete. Wenn ich also die ersten Buchstaben des Nachnamens eines Kunden eingegeben habe, sollte das Formular nach den Kunden mit diesem Nachnamen gefiltert werden.

Da ich aber nicht nur das Feld Nachname, sondern auch noch andere Felder nach dem eingegebenen Suchbegriff durchsuchte, erschienen plötzlich Such-treffer, bei denen etwa der Straßenname mit den gleichen Buchstaben begann wie der Nachname.

Bei einer überschaubaren Anzahl von Kundendatensätzen ist da kein Problem: Man blättert halt schnell durch die gefilterten Datensätze und landet so schnell bei dem gesuchten Kunden. Mit einer kleinen Anzahl Kunden klappte das recht gut. Mit wachsender Anzahl funktionierte es allerdings immer schlechter, da auch die Anzahl der Suchtreffer wuchs.

Da ich keine Lust hatte, schon wieder eine neue Suchfunktion zu programmieren, machte ich aus der Not eine Tugend und suchte fortan nach Elementen in den Kundendaten, die eine kleinere Treffermenge versprachen.

Wenn ein Kunde also etwa den Nachnamen Meier trägt, habe ich erst gar nicht mehr nach dem Nachnamen gesucht, sondern den Vornamen als Suchbegriff eingegeben. Dumm nur, wenn der gesuchte Kunde etwa Michael Meier heißt – so waren auf jeden Fall eine Menge Treffer zu erwarten.

Auch interessant waren Kunden mit einem Nachnamen, der auch als Vorname verwendet wird – auch hier fallen eine Reihe Treffer mehr an als man eigentlich durchblättern möchte.

Also musste eine neue Suchfunktion her: Eine, die zwar immer noch die flexible Suche über alle festgelegten Suchfelder erlaubte, aber die auch die konkrete Angabe der zu durchsuchenden Felder erlaubte (s. Bild 1). Wenn man also etwa einfach den Nachnamen Meier eingibt, sollten alle festgelegten Felder nach dieser Zeichenkette durchsucht werden.

Beispiel für die Suche in einem Formular in der Formularansicht

Bild 1: Beispiel für die Suche in einem Formular in der Formularansicht

Um nur solche Datensätze zu finden, die den Wert Meier nur im Feld Nachname enthalten, soll der Benutzer diesen Ausdruck angeben können:

Nachname:Meier

Wenn die Suche zu viele Treffer liefert, kann der Benutzer das Ergebnis weiter einschränken – etwa durch zusätzliche Angabe des Vornamens:

Vorname:Michael Nachname:Meier

„Und“ oder „Oder“

Die große Frage, die sich nun stellt, ist folgende: Benötigen wir eine Und-Verknüpfung für alle Vergleichskriterien oder eine Oder-Verknüpfung – oder gar beide Und sollte man gegebenenfalls sogar Klammern zum Einstellen der Priorität der Verknüpfungen hinzufügen können Normalerweise sollte eine Und-Verknüpfung ausreichen. Wenn man zusätzlich zum gesuchten Nachnamen noch den Vornamen eingibt, soll das Suchergebnis auch nur die Datensätze enthalten, bei denen beide Suchkriterien zutreffen. Dies gilt zumindest dann, wenn man nach genau einem Kundendatensatz sucht. Aber auch hier gibt es Ausnahmen: Es kann ja zum Beispiel sein, dass Sie nicht wissen, ob der Nachname des Kunden nun in der Lieferadresse (etwa im Feld Nachname_Liefer) oder in der Rechnungsadresse (zum Beispiel Nachname_Rechnung) gespeichert ist. Dann wäre es natürlich sinnvoll, wenn die Suchfunktion die beiden Suchausdrücke per Or verknüpfen würde. Also enthält die Lösung die Möglichkeit, And und Or als Verknüpfungsoperatoren zu verwenden.

In allen Feldern suchen

Und die Suchfunktion soll noch ein weiteres interessantes Feature liefern – nämlich die Suche über alle möglichen Felder. Dies soll immer dann geschehen, wenn der Benutzer einen Suchbegriff ohne Angabe des zu durchsuchenden Feldes angibt.

Die Eingabe des Ausdrucks Chai ohne vorheriges Artikelname: soll also alle Felder nach diesem Ausdruck durchsuchen.

Automatische Ergänzung

Eine der wichtigsten Funktionen der Suche ist die automatische Ergänzung bei der Eingabe der zu durchsuchenden Felder. Wenn die Datenherkunft also etwa ein Feld namens Artikelname enthält und der Benutzer gibt die Buchstaben Art ein, dann soll das Suchtextfeld automatisch die fehlenden Buchstaben (hier ikelname) anzeigen und gegebenenfalls nach Betätigen der Tab-Taste oder nach Eingabe des Doppelpunkts (:) hinzufügen (s. Bild 2).

Automatische Ergänzung von Suchfeldern

Bild 2: Automatische Ergänzung von Suchfeldern

Einschränkung

In der aktuellen Version funktioniert die Suche nach Textpassagen in Feldern des Datentyps Text oder Memo problemlos. Auch die Suche nach Zahlen oder Datumsangaben gelingt, allerdings nur für den Gleich-Operator. Größer/Kleiner und ähnliche Operatoren sind hier noch nicht umgesetzt.

Einsatz der Lösung

Ein Beispiel für den Einsatz der Lösung liefert das Formular frmFormularansicht. Hier haben wir ein Formular, das die Datensätze der Tabelle tblArtikel in der Formularansicht anzeigt, mit einem Suchfeld versehen. Im Beispiel soll die Suche alle Artikel liefern, deren Feld Artikelname den Wert Chai enthält – was genau einen Treffer bringt (siehe unten in der Abbildung: Datensatz 1 von 1).

Welche Schritte sind zum Anwenden der Lösung nötig In Kurzfassung sind es die folgenden:

  • Hinzufügen eines Textfeldes zur Eingabe des Suchbegriffs
  • Erstellen einer Abfrage, die alle zu durchsuchenden Felder enthält
  • Anlegen einer Ereignisprozedur für das Ereignis Beim Laden, das die Suchfunktion initialisiert
  • Anlegen einer Ereignisprozedur für das Ereignis Beim Entladen, um die Suchfunktion zu beenden
  • Anlegen einer Ereignisprozedur, die nach dem Start der Suche ausgelöst wird und die Aktion zum Filtern des Formulars, Unterformulars oder Listenfeldes enthält

Textfeld für die Suche hinzufügen

Im ersten Schritt fügen Sie dem Formular an der gewünschten Stelle ein Textfeld hinzu, das Sie zur Eingabe des Suchbegriffs nutzen möchten – beispielsweise im oberen Bereich des Formulars. Im ersten Beispiel des Formulars frmFormularansicht, das die Daten der Tabelle tblArtikel anzeigt, nennen wir dieses Steuerelement txtSucheNach (s. Bild 3).

Hinzufügen eines Suchfeldes zum Formular

Bild 3: Hinzufügen eines Suchfeldes zum Formular

Abfrage mit den zu durchsuchenden Feldern erstellen

Neben der Datenherkunft für das Formular benötigen wir noch eine Abfrage, welche die zu durchsuchenden Felder enthält. Warum aber sollte man nicht einfach die gleiche Abfrage verwenden, die auch als Datenherkunft für das zu durchsuchende Formular dient Aus einem ganz einfachen Grund: Im Beispiel des Formulars frmFormular-ansicht etwa werden nur Daten der Tabelle tblArtikel angezeigt. Nun könnte man annehmen, dass dies auch für die Ermittlung der zu durchsuchenden Felder gilt. Das ist manchmal der Fall, aber nicht hier: Die Datenherkunft des Formulars liefert nämlich mit den beiden Feldern LieferantID und KategorieID zwei Nachschlagefelder, die ja nur die Werte der Primärschlüsselfelder der verknüpften Einträge aus den Tabellen tblLieferanten und tblKategorien enthalten. Wenn wir nun als Suchbegriff etwa für die Kategorie den Wert Getränke eingeben, finden wir in der Datenherkunft des Formulars natürlich keinen passenden Datensatz, weil das Feld KategorieID dort nur Zahlenwerte wie 1, 2, 3 et cetera enthält.

Wenn wir aber nach den eigentlichen Werten hinter den als Nachschlagefeld definierten Feldern suchen möchten, müssen wir die verknüpften Tabellen noch zur Datenherkunft für die Suchfunktion hinzufügen. Dies sieht dann wie in Bild 4 aus: Hier haben wir einer neuen Abfrage namens qryArtikelsuche nicht nur die Tabelle tblArtikel, sondern auch noch die beiden verknüpften Tabellen tblKategorien und tblLieferanten hinzugefügt. Nachdem alle benötigten Tabellen in der Abfrage enthalten sind, ist es wichtig, nur die Felder zum Entwurfsraster hinzuzufügen, die auch für die Suche herangezogen werden sollen – plus dem Primärschlüsselfeld der eigentlich zu durchsuchenden Tabelle, also ArtikelID.

Abfrage mit den zu durchsuchenden Feldern

Bild 4: Abfrage mit den zu durchsuchenden Feldern

In diesem Fall fügen wir also zunächst die Felder ArtikelID und Artikelname hinzu. Dann folgt in der Tabelle tblArtikel das Feld LieferantID, welches wir aber nicht zur Datenherkunft hinzufügen – wir wollen ja nicht nach den Primärschlüsselwerten der Tabelle tblLieferanten suchen.

Stattdessen ziehen Sie das Feld Firma aus der Tabelle tblLieferanten in das Entwurfsraster. Auch das nächste Feld namens KategorieID benötigen wir nicht, sondern das Feld Kategoriename der verknüpften Tabelle tblKategorien. Die übrigen Felder der Tabelle tblArtikel können wir dann wieder direkt in das Entwurfsraster der Abfrage ziehen.

Hier fehlt nur noch eine kleine Optimierung: Im Formular wird etwa das Feld KategorieID mit der Bezeichnung Kategorie angezeigt. Der Name des Feldes in der Abfrage, die für die Suche verwendet werden soll, lautet hingegen Kategoriename. ähnlich sieht es für das Feld Lieferant aus, das in der verknüpften Tabelle Firma heißt. In beiden Fällen versehen wir die Felder der Suchabfrage mit einem entsprechenden Alias: Kategoriename wird durch Kategorie:Kategoriename ersetzt, Firma durch Lieferant:Firma (s. Bild 5).

Optimierung: Anpassen der Felder der verknüpften Tabellen an den Feldnamen der Haupttabelle

Bild 5: Optimierung: Anpassen der Felder der verknüpften Tabellen an den Feldnamen der Haupttabelle

Diese Abfrage taucht nirgends im Formular auf. Sie wird lediglich für zwei Zwecke benötigt: Erstens als Lieferant für die Feldnamen, die im Suchtextfeld bei der Eingabe der Anfangsbuchstaben automatisch ergänzt werden sollen, zweitens als Abfrage, welche zur Ermittlung der gesuchten Datensätze dient.

Beim Laden: Suche initialisieren

Die Suchfunktion steckt komplett in einem einzigen Klassenmodul. Dieses müssen Sie im Klassenmodul des Formulars instanzieren und ihm einige Informationen übergeben, die es für die Implementierung der Suchfunktion für das Formular benötigt.

Dazu sind zwei Schritte nötig. Der erste ist die Deklaration einer Objektvariablen namens objFlexSearch im Kopf des Klassenmoduls des Formulars:

Dim WithEvents objFlexSearch  As clsFlexSearch

Der zweite ist das Hinzufügen einer Ereignisprozedur, die durch das Ereignis Beim Laden des Formulars ausgelöst wird. Für dieses hinterlegen Sie den folgenden Code:

Private Sub Form_Load()
     Set objFlexSearch = New clsFlexSearch
     With objFlexSearch
         .Suchabfrage = "qryArtikelsuche"
         .PKFeld = "ArtikelID"
         .PKFeldEinschliessen = False
         Set .Suchfeld = Me!txtSucheNach
     End With
End Sub

Die Eigenschaften der Klasse clsFlexSearch werden im VBA-Fenster per IntelliSense bereitgestellt und können so leicht gefüllt werden (s. Bild 6).

Die Eigenschaften der Klasse clsFlexSearch werden per IntelliSense bereitgestellt.

Bild 6: Die Eigenschaften der Klasse clsFlexSearch werden per IntelliSense bereitgestellt.

Die Eigenschaften haben die folgende Bedeutung:

  • Suchabfrage: Name der gespeicherten Abfrage, die wir soeben erstellt haben
  • PKFeld: Name des Primärschlüsselfeldes in der Suchabfrage, nach der die Datensätze der im Formular angezeigten Datenherkunft gefiltert werden sollen
  • PKFeldEinschliessen: Gibt an, ob das Primärschlüsselfeld als Suchbegriff verwendet werden soll.
  • Suchfeld: Verweis auf das Textfeld, in das der Benutzer die Suchausdrücke eingibt.

Beim Entladen: Suchfunktion beenden

Beim Entwickeln der Suchfunktion gab es öfters Probleme, wenn das Formular oder die Anwendung geschlossen wurde, wenn die Objektvariable nicht durch Setzen des Wertes Nothing geleert wurde – Access stürzte dann einfach ab.

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