Home > Artikel > Ausgabe 1/2012 > Einfache Suchfunktion für Formulare

Einfache Suchfunktion für Formulare

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Die Suche von Daten in den Tabellen einer Datenbank ist eine Aufgabe, die fast jede Datenbankanwendung erfüllen muss. Die grundlegenden Techniken bestehen darin, Suchbegriffe in ein Formular einzugeben und die daraus resultierende Ergebnismenge in einem geeigneten Steuerelement anzuzeigen – beispielsweise in einem Unterformular in der Datenblattansicht, in einem Listenfeld oder auch einfach in einem gefilterten Formular in der Formularansicht. Die wichtigste Grundlagen ist dabei, die Datenherkunft mit den entsprechenden Kriterien zu spicken. Wie es geht, zeigt dieser Beitrag.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1201_EinfacheSuchfunktion.mdb.

Artikelabfrage

Für die verschiedenen Beispiele dieses Artikels wird die Artikeltabelle der Beispieldatenbank herhalten. Sie liefert diverse Text- und Zahlenfelder, die sich für das Zusammenstellen der benötigten Abfragen eignen. Der Vollständigkeit halber haben wir die ursprüngliche Tabelle noch um Datumsfeld namens AngelegtAm erweitert.

Suchen per Abfrage

Die Grundlagen zum Durchsuchen einer Abfrage nach verschiedenen Kriterien finden Sie beispielsweise in den Artikeln SQL: SELECT-Abfragen, Teil II, Filtern nach Zahlen, Filtern von Textfeldern oder Datum und Zeit. Im vorliegenden Artikel erfahren Sie, wie Sie die in diesen Artikeln gewonnenen Kenntnisse dazu nutzen können, dem Benutzer eine Eingabemöglichkeit für Suchbegriffe zu bieten, eine entsprechende Abfrage zu formulieren und das Ergebnis darzustellen.

Einen der möglichen Bausteine haben Sie bereits im Artikel Einsatz von Parametern kennengelernt. Sie können einer Abfrage einen Parameter in Form eines in eckigen Klammern eingefassten Ausdrucks als Bedingung hinzufügen, der vor dem Anzeigen des Abfrageergebnisses abgefragt und ausgewertet wird.

In Grundzügen bauen wir auf dieser Technik auf, Sie werden jedoch auch anderen Techniken kennenlernen, um das gewünschte Ergebnis zu erhalten.

Aufbau der Formulare

In den Beispielen soll der Benutzer den Namen eines Artikels oder einen Teil des Namens in ein Textfeld eingeben. Nach einem Mausklick auf die Suchen-Schaltfläche soll ein Unterformular in der Datenblattansicht die gefundenen Datensätze als Suchergebnis anzeigen.

Wir erstellen zunächst das Formular an, das später als Unterformular eingesetzt wird. Legen Sie dazu ein neues Formular an und speichern Sie es unter dem Namen sfmArtikelsuche (sfm steht für Subform). Wählen Sie für die Eigenschaft Datenherkunft zunächst die Tabelle tblArtikel aus.

Nach der Auswahl stehen in der Feldliste alle Felder der gewählten Datenherkunft bereit. Ziehen Sie alle Felder in den Detailbereich der Entwurfsansicht des Formulars. Stellen Sie dann die Eigenschaft Standardansicht auf den Wert Datenblatt ein (siehe Bild 1).

Entwurfsansicht des Unterformulars sfmArtikelsuche

Bild 1: Entwurfsansicht des Unterformulars sfmArtikelsuche

Speichern Sie nun das Unterformular und schließen Sie es. Anschließend erstellen Sie ein weiteres neues Formular und speichern es unter dem Namen frmArtikelsuche. Es handelt sich dabei um das Hauptformular, das gleich das Unterformular aufnehmen wird. Zuvor legen Sie jedoch noch die benötigten Steuerelemente an. Das erste ist ein Textfeld namens txtSuche, das zweite eine Schaltfläche namens cmdSuche (siehe Bild 2).

Hauptformular der Artikelsuche

Bild 2: Hauptformular der Artikelsuche

Nun fügen Sie das Unterformular sfmArtikelsuche ein, indem Sie es mit der Maus aus dem Datenbankfenster beziehungsweise dem Navigationsbereich in den Detailbereich des Entwurfs des Formulars frmArtikelsuche ziehen.

Das Formular mit dem Unterformular sieht in der Entwurfsansicht nun wie in Bild 3 aus. Sie können nun noch das Bezeichnungsfeld des Unterformulars mit der Beschriftung Suchergebnis ausstatten und gegebenenfalls Formular und Unterformular noch etwas breiter gestalten, damit der Benutzer mehr Daten auf einen Blick sieht und weniger scrollen muss. Stellen Sie außerdem die Eigenschaften Bildlaufleisten, Navigationsschaltflächen und Datensatzmarkierer auf Nein ein – diese Elemente brauchen Sie für das Hauptformular nicht.

Haupt- und Unterformular in der Entwurfsansicht

Bild 3: Haupt- und Unterformular in der Entwurfsansicht

Nach einem Wechsel in die Formularansicht können Sie außerdem noch die Schriftgröße im Unterformular anpassen, indem Sie auf einen der Spaltenköpfe klicken und dann in der Symbolleiste oder im Ribbon den gewünschten Wert für die Schriftgröße eingeben. Das Formular ist nun fast fertig und sieht wie in Bild 4 aus.

Ohne weitere Handgriffe zeigt das Unterformular einfach alle Datensätze an.

Bild 4: Ohne weitere Handgriffe zeigt das Unterformular einfach alle Datensätze an.

Suchen per Filter

Die einfachste Möglichkeit, die Datensätze des Unterformulars durch die Eingabe eines Suchbegriffs einzuschränken, ist der Einsatz der Eigenschaft Filter des Unterformulars.

Dies funktioniert folgendermaßen: Der Benutzer gibt einen Suchbegriff in das Textfeld txtSuche ein und betätigt dann die Schaltfläche mit der Beschriftung Suchen. Dies löst eine Ereignisprozedur an, die Sie wie folgt anlegen:

  • Öffnen Sie das Formular frmArtikelsuche in der Entwurfsansicht.
  • Klicken Sie auf die Schaltfläche und aktivieren Sie mit der Taste F4 das Eigenschaftsfenster, sofern noch nicht sichtbar.
  • Wählen Sie für die Eigenschaft Beim Klicken auf der Registerseite Ereignis den Eintrag [Ereignisprozedur] für die Eigenschaft Beim Klicken aus und klicken Sie anschließend auf die Schaltfläche rechts mit den drei Punkten (...).
  • Im VBA-Editor erscheint nun die leere Prozedur, die Sie wie folgt füllen (siehe auch Bild 5):
  • Diese Prozedur führt den Suchvorgang durch.

    Bild 5: Diese Prozedur führt den Suchvorgang durch.

Private Sub cmdSuche_Click()

     Dim strFilter As String

     If Len(Me!txtSuche) > 0 Then

         strFilter = "Artikelname LIKE '" _

             & Me!txtSuche & "'"

         Me!sfmArtikelsuche.Form.Filter = strFilter

         Me!sfmArtikelsuche.Form.FilterOn = True

     Else

         Me!sfmArtikelsuche.Form.Filter = ""

     End If

End Sub

Wenn Sie nun in die Formularansicht wechseln, können Sie die Prozedur gleich ausprobieren. Geben Sie einen Suchbegriff in das Suchfeld ein, zum Beispiel C*. Klicken Sie dann auf die Schaltfläche Suchen, löst dies die soeben angelegte Prozedur aus.

Die If-Bedingung prüft zunächst, ob die Länge der Zeichenkette im Textfeld txtSuche länger als 0 Zeichen ist, also ob dort überhaupt ein Suchbegriff eingetragen wurde. Falls ja, wird ein Filterkriterium für die Eigenschaft Filter zusammengesetzt, das aus der Angabe des zu durchsuchenden Feldes, dem Vergleichsoperator LIKE und einem Vergleichsausdruck besteht, der sich aus zwei Hochkommata und dem Inhalt des Textfeldes zusammensetzt.

Dieser Ausdruck wird anschließend der Eigenschaft Filter des im Unterformularsteuerelements enthaltenen Formulars zugewiesen. Dies allein bewirkt noch nichts, erst muss noch der Wert der Eigenschaft FilterOn auf den Wert True eingestellt werden. Das Ergebnis sieht wie in Bild 6 aus.

Das Suchformular in Aktion

Bild 6: Das Suchformular in Aktion

Andersherum soll das Auslösen der Suche bei nicht vorhandenem Suchbegriff alle Einträge der Tabelle tblArtikel anzeigen. Dies geschieht, wenn die Bedingung der If-Bedingung nicht erfüllt, die Länge der Zeichenkette im Textfeld txtSuche also 0 ist. In diesem Fall wird schlicht der Ausdruck für die Eigenschaft Filter auf eine leere Zeichenkette eingestellt ("").

Nun ist dies alles nur halb so ergonomisch, wenn der Benutzer jedes Mal auf die Schaltfläche drücken muss, anstatt einfach nur die Eingabetaste zum Absenden des Suchbegriffs zu betätigen.

Damit diese Schaltfläche automatisch beim Betätigen der Eingabetaste ausgelöst wird, stellen Sie die Eigenschaft Standard für diese Schaltfläche auf den Wert Ja ein (siehe Bild 7).

Einstellen der Schaltfläche cmdSuche als Standardschaltfläche des Formulars

Bild 7: Einstellen der Schaltfläche cmdSuche als Standardschaltfläche des Formulars

Suche per Recordsource

Das Zuweisen der Tabelle tblArtikel zur Eigenschaft Datenherkunft können Sie auch per VBA-Code erledigen. Der Eigenschaft Datenherkunft lassen sich außerdem nicht nur Tabellennamen wie tblArtikel, sondern auch Abfragenamen oder gar SQL-Ausdrücke wie SELECT * FROM tblArtikel zuweisen.

Dies können Sie sich auch für die Programmierung einer Suchfunktion zunutze machen. In diesem Fall stellen Sie in der Ereignisprozedur, die durch die Schaltfläche cmdSuchen ausgelöst wird, einen SQL-Ausdruck zusammen, der anschließend der Eigenschaft Recordsource des im Unterformularsteuerelement sfmArtikelsuche angezeigten Formulars zugewiesen wird:

Private Sub cmdSuche_Click()

     Dim strSQL As String

     If Len(Me!txtSuche) > 0 Then

         strSQL = "SELECT * FROM tblArtikel WHERE " _

             & "Artikelname LIKE '" & Me!txtSuche & "'"

     Else

         strSQL = "SELECT * FROM tblArtikel"

     End If

     Me!sfmArtikelsuche.Form.RecordSource = strSQL

End Sub

Sollte hier kein Suchbegriff vorliegen, wird die Abfrage SELECT * FROM tblArtikel als Datenherkunft übergeben. Diese Version der Suchfunktion finden Sie in der Beispieldatenbank im Formular frmArtikelsuche_Recordset.

Suche mit Platzhalter

In der aktuellen Form kann der Benutzer die Platzhalter selbst eingeben, sie werden dann automatisch in die Suche mit einbezogen. Wenn Sie etwa den Ausruck A* verwenden, lautet der Filter des ersten Beispiels

Artikelname LIKE 'A*'

und die SELECT-Anweisung des zweiten Beispiels sieht so aus:

SELECT * FROM tblArtikel WHERE Artikelname LIKE 'A*'

Sie können natürlich auch gleich entsprechende Platzhalter in die Prozeduren zum Zusammenstellen der Filter beziehungsweise der SELECT-Abfrage integrieren.

Beim Zusammenstellen des Filters für das erste Beispiele verwenden Sie dann etwa den folgenden Ausdruck:

strFilter = "Artikelname LIKE '" & Me!txtSuche & "*'"

Entscheidend ist das Sternchen als Platzhalter am Ende des Ausdrucks. Wenn der Filter alle Artikelnamen erfassen soll, welche die angegebene Zeichenkette enthalten, können Sie auch vorn und hinten einen Platzhalter einfügen:

strFilter = "Artikelname LIKE '*" & Me!txtSuche & "*'"

Beim Zusammenstellen der SELECT-Anweisung im zweiten Beispiel würde das so aussehen – hier erst der Ausdruck für alle Artikelnamen, die mit dem angegebenen Suchbegriff beginnen:

strSQL = "SELECT * FROM tblArtikel WHERE " _

& "Artikelname LIKE '" & Me!txtSuche & "*'"

Sollen alle Artikel angezeigt werden, deren Artikelname den Suchbegriff enthält, fügen Sie noch ein Sternchen hinzu:

strSQL = "SELECT * FROM tblArtikel WHERE " _

& "Artikelname LIKE '*" & Me!txtSuche & "*'"

Suche nach Zahlenwerten

Nachdem wir eine Suche nach einer Zeichenkette implementiert haben, fügen wir eine Suche nach Zahlenwerten hinzu – genau genommen die Suche nach Artikeln, deren Einzelpreis sich in bestimmten Grenzen befindet. Für den Start prüfen wir zunächst den genauen Preis des Artikels, später soll dann ein Preisbereich angegeben werden können. In der Beispieldatenbank haben wir das Formular frmArtikelsuche zum Erweitern der Suchfunktion in ein neues Formular namens frmArtikelsucheMitPreis kopiert. Diesem fügen Sie nun zunächst zwei neue Steuerelemente hinzu – ein Textfeld namens txtSucheEinzelpreis und eine Schaltfläche namens cmdSucheEinzelpreis (siehe Bild 8). Für die Schaltfläche hinterlegen Sie die folgende Prozedur, die durch das Ereignis Beim Klicken ausgelöst wird:

Für die Suche nach einem bestimmten Einzelpreis verwenden wir zunächst eine eigene Schaltfläche.

Bild 8: Für die Suche nach einem bestimmten Einzelpreis verwenden wir zunächst eine eigene Schaltfläche.

Private Sub cmdSucheEinzelpreis_Click()

     Dim strFilter As String

     If Len(Me!txtSucheEinzelpreis) > 0 Then

         strFilter = "Einzelpreis = " _

             & Me!txtSucheEinzelpreis

         Me!sfmArtikelsuche.Form.Filter = strFilter

         Me!sfmArtikelsuche.Form.FilterOn = True

     Else

         Me!sfmArtikelsuche.Form.Filter = ""

     End If

End Sub

Die Prozedur prüft wiederum, ob das Textfeld txtSucheEinzelpreis überhaupt einen Wert enthält. Anschließend setzt sie einen Filter zusammen, der das Feld Einzelpreis der Tabelle tblArtikel mit dem im Textfeld txtSucheEinzelpreis vergleicht. Dies gelingt ganz hervorragend, bis ein Benutzer einen Wert eingibt, den Access nicht als Zahlenwert interpretieren kann – zum Beispiel eine Zahl mit Währung wie 10,- EUR. Dies löst dann den Fehler aus Bild 9 aus.

Fehler bei Eingabe von Text in ein Zahlenfeld

Bild 9: Fehler bei Eingabe von Text in ein Zahlenfeld

Wie können Sie dies ändern? Kein Problem: Sie müssen nur vor der Auswertung prüfen, ob das Feld einen numerischen Wert enthält. Dazu stellt VBA die Funktion IsNumeric zur Verfügung. Diese integrieren Sie einfach in die vorhandene Prozedur (vollständige Version siehe Formularmodul):

If IsNumeric(Me!txtSucheEinzelpreis) Then

     '... Filter zusammenstellen und anwenden

Else

     MsgBox "Bitte geben Sie eine Zahl für " _

         & "das Suchfeld 'Einzelpreis' ein.", _

         vbExclamation, "Falsche Eingabe"

     Me!txtSucheEinzelpreis.SetFocus

     Exit Sub

End If

Wenn das Feld einen numerischen Wert enthält, filtert die Prozedur das Unterformular wie gewünscht. Falls nicht, erscheint zuerst ein Meldungsfenster, dann wird der Fokus auf das Textfeld zur Eingabe des Kriteriums verschoben und die Prozedur verlassen.

Auch die Fehlermeldung müssen wir noch beleuchten. Diese lautete:

Syntaxfehler (fehlender Operator) in Abfrageausdruck 'Einzelpreis = 10 EUR'.

Die Prozedur setzt hier schlicht einen Filterausdruck zusammen, der den Inhalt eines Zahlenfeldes (hier genau genommen den eines Währungsfeldes) mit einer Zeichenkette vergleichen will.

Dies gelingt nicht, weil VBA schlicht den Teil hinter der Zahl 10 nicht verarbeiten kann.

Suche nach Artikeln eines Preisbereichs

Bauen wir die Suche nach Artikeln mit einem bestimmten Preis doch noch ein wenig aus. Im Formular frmArtikelsucheMitPreisbereich soll der Benutzer nicht nur einen festen Preis eingeben können, sondern einen Preisbereich. Dafür benennen Sie das erste Textfeld von txtSucheEinzelpreis in txtSuchePreisVon um und legen ein weiteres Textfeld namens txtSuchePreisBis an (siehe Bild 10).

Steuerelemente zur Eingabe von Preisbereichen

Bild 10: Steuerelemente zur Eingabe von Preisbereichen

Hier kann es nun passieren, dass der Benutzer nur einen Wert für den Mindestpreis oder den Maximalpreis angibt. Vielleicht gibt er auch Werte für beide Textfelder ein. In jedem Fall sollte das Unterformular ein entsprechendes Ergebnis anzeigen:

  • Wenn nur das Textfeld txtSuchePreisVon einen Wert enthält, soll das Ergebnis alle Artikel liefern, deren Preis größer oder gleich dem angegebenen Preis ist.
  • Wenn nur das Textfeld txtSuchePreisBis einen Wert enthält, soll das Ergebnis alle Artikel enthalten, deren Preis maximal dem angegebenen Preis entspricht.
  • Wenn beide Textfelder gefüllt wurden, müssen Sie zunächst prüfen, ob der Wert im Feld txtSuchePreisVon kleiner oder gleich dem Wert aus dem Textfeld txtSuchePreisBis ist. Ist dies der Fall, soll das Unterformular alle Artikel anzeigen, deren Einzelpreis zwischen den beiden angegebenen Preisgrenzen liegt – inklusive der Artikel, deren Preis genau den angegebenen Werten entspricht.

Um dies umzusetzen, legen wir eine Ereignisprozedur an, die durch einen Klick auf die Schaltfläche cmdSucheEinzelpreis_Click ausgelöst wird und die wie in Listing 1 aussieht. Diese Prozedur sieht komplizierter aus, als sie ist.

Private Sub cmdSucheEinzelpreis_Click()

     Dim strFilter As String

     If Not IsNull(Me!txtSuchePreisVon) And Not IsNumeric(Me!txtSuchePreisVon) Then

         MsgBox "Bitte geben Sie eine Zahl für den Mindestpreis ein.", vbExclamation, "Falsche Eingabe"

         Me!txtSuchePreisVon.SetFocus

         Exit Sub

     End If

     If Not IsNull(Me!txtSuchePreisBis) And Not IsNumeric(Me!txtSuchePreisBis) Then

         MsgBox "Bitte geben Sie eine Zahl für den maximalen Preis ein.", vbExclamation, "Falsche Eingabe"

         Me!txtSuchePreisBis.SetFocus

         Exit Sub

     End If

     If Me!txtSuchePreisVon > 0 And Me!txtSuchePreisBis > 0 Then

         If Me!txtSuchePreisVon > Me!txtSuchePreisBis Then

             MsgBox "Der Mindestpreis muss kleiner als der Maximalpreis sein."

             Exit Sub

         End If

     End If

     If Me!txtSuchePreisVon > 0 Then

         strFilter = strFilter & "AND Einzelpreis >= " & Me!txtSuchePreisVon

     End If

     If Me!txtSuchePreisBis > 0 Then

         strFilter = strFilter & " AND Einzelpreis <= " & Me!txtSuchePreisBis

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!