Home > Artikel > Ausgabe 5/2012 > Schnellsuche im Listenfeld

Schnellsuche im Listenfeld

  PDF ansehen

  Download PDF und Beispieldatenbank

Listenfelder eignen sich prima zur Anzeige von Daten in Listenform – vor allem, wenn der Benutzer diese Daten nicht an Ort und Stelle ändern soll. Im Gegensatz zur Datenblattansicht lässt es aber auch eigene Filter- oder Sortiermöglichkeiten vermissen. Dieser Artikel zeigt, wie Sie zumindest eine komfortable Suche nach bestimmten Einträgen realisieren.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1205_Schnellsuche.mdb.

Schnellsuche

Warum heißt die in diesem Artikel vorgestellte Suchfunktion eigentlich Schnellsuche? Nun: Im Gegensatz zu einer Suche, bei der Sie den Suchbegriff in ein Suchfeld eingeben und die Suche dann etwa durch Betätigen der Eingabetaste oder per Klick auf eine entsprechende Schaltfläche anstoßen, soll die Suche hier nach Eingabe jedes einzelnen Zeichens ausgelöst werden. Sprich: Wenn Sie für eine Suche im Feld Artikelname der Tabelle tblArtikel den Buchstaben A eingeben, soll das Listenfeld gleich alle Artikel anzeigen, die mit diesem Buchstaben beginnen. Geben Sie einen weiteren Buchstaben wie etwa L ein, zeigt das Listenfeld nur noch Einträge an, die mit AL beginnen.

Wenn Sie nach allen Artikelnamen suchen wollen, die einen Buchstaben oder eine Zeichenfolge an irgendeiner Stelle enthalten, verwenden Sie entsprechende Platzhalter wie etwa das Sternchen. Der Suchbegriff *A* liefert dann alle Artikel, die den Buchstaben A im Namen enthalten (siehe Bild 1).

Schnellsuche im Listenfeld

Bild 1: Schnellsuche im Listenfeld

Alternativ können Sie die Suche auch so gestalten, dass automatisch alle Artikelnamen ausgegeben werden, die eine bestimmte Zeichenfolge enthalten – dazu später mehr.

Formular mit Schnellsuche erstellen

Legen Sie ein neues Formular an und speichern Sie es unter dem Namen frmSchnellsuche.

Fügen Sie dem Formular dann ein Listenfeld zur Anzeige des Suchergebnisses an. Das Listenfeld soll den Namen lstArtikel erhalten. Es soll nur zur Auswahl eines Artikels dienen, daher reicht es, wenn es die Artikelnamen anzeigt. Damit der ausgewählte Datensatz jedoch eindeutig identifiziert werden kann, muss die Datensatzherkunft des Listenfeldes neben dem Feld Artikelname auch noch das Feld ArtikelID enthalten. Außerdem kann eine Sortierung nach dem Feld Artikelname nicht schaden (siehe Bild 2).

Datensatzherkunft des Listenfeldes

Bild 2: Datensatzherkunft des Listenfeldes

Damit das Listenfeld nur den Artikelnamen, nicht aber das Feld ArtikelID anzeigt, stellen Sie außerdem die Eigenschaften Spaltenanzahl und Spaltenbreiten des Listenfeld-Steuerelements auf die Werte 2 und 0cm ein. Wie ein Wechsel in die Formularansicht zeigt, liefert das Listenfeld bereits die gewünschten Daten (siehe Bild 3). Bevor wir uns um das Textfeld zur Eingabe des Suchergebnisses kümmern, stellen wir noch einige Formulareigenschaften ein. Die Eigenschaften Datensatzmarkierer, Navigationsschaltflächen, Trennlinien und Bildlaufleisten stellen Sie auf den Wert Nein ein. Das Formular wirkt dadurch etwas aufgeräumter, außerdem benötigen wir all diese Elemente aktuell nicht.

Das Listenfeld wird wie gewünscht gefüllt.

Bild 3: Das Listenfeld wird wie gewünscht gefüllt.

Suchfeld anlegen

Als Suchfeld verwenden wir ein herkömmliches Textfeld. Es soll txtSuche heißen und soll über dem Listenfeld platziert werden. Die Eingabe von Suchbegriffen ist kein Problem, aber wie sorgen wir dafür, dass die im Listenfeld angezeigten Artikelnamen nach jeder Änderung des Suchbegriffs aktualisiert werden?

Dazu benötigen wir ein Ereignis und eine entsprechende Ereignisprozedur, die nach jeder Änderung des Textfeldinhalts ausgelöst wird. Habe ich Änderung gesagt? Nun, da gibt es doch eine Ereigniseigenschaft mit dem Namen Bei Änderung. Prüfen Sie also, ob dieses Ereignis das Passende ist und legen dieses an. Dazu markieren Sie das Textfeld, aktivieren das Eigenschaftsfenster und wählen für die Eigenschaft Bei Änderung den Eintrag [Ereignisprozedur] aus (siehe Bild 4). Die nach einem Klick auf die Schaltfläche mit den drei Punkten (...) im VBA-Editor angezeigte Prozedur ergänzen Sie wie folgt:

Anlegen der Ereignisprozedur, die durch das Ereignis Bei Änderung ausgelöst wird.

Bild 4: Anlegen der Ereignisprozedur, die durch das Ereignis Bei Änderung ausgelöst wird.

Private Sub txtSuche_Change()

     Debug.Print "Suchbegriff: " & Me!txtSuche

End Sub

Damit soll zu Testzwecken der aktuelle Inhalt des Textfeldes im Direktfenster ausgegeben werden. Das Ergebnis ist eher ernüchternd: Dort erscheint nämlich nur der Text Suchbegriff:, aber nicht der in das Suchfeld eingegebene Text. Die Lösung ist einfach: Me!txtSuche ist eine Abkürzung für Me!txtSuche.Value. Das lässt sich so abkürzen, weil Value die Standardeigenschaft des Textfeldes ist. Zwischen dem Wert der Eigenschaft Value und dem im Textfeld angezeigten Text gibt es jedoch einen Unterschied: Value wird nämlich erst auf den enthaltenen Text eingestellt, wenn Sie den Inhalt etwa mit der Eingabetaste oder durch den Wechsel zu einem anderen Steuerelement bestätigen.

Dies können Sie leicht prüfen, indem Sie eine Zeichenfolge wie abc eingeben, auf das Listenfeld klicken, dann wieder die Einfügemarke im Textfeld platzieren und ein weiteres Zeichen eintippen. Im Direktfenster erscheint dann die Zeichenfolge Suchbegriff: abc. Zum Glück bietet das Textfeld auch eine Eigenschaft, mit der Sie auf den aktuell angezeigten Text zugreifen können. Diese Eigenschaft heißt Text. Mit der folgenden Änderung der Prozedur wird jeweils der aktuelle Text im Direktfenster ausgegeben:

Private Sub txtSuche_Change()

     Debug.Print "Suchbegriff: " & Me!txtSuche.Text

End Sub

Kriterium zusammensetzen

Mit diesem Wissen ausgestattet, können wir nun den Code zum Zusammenstellen eines Filterkriteriums schreiben. Die folgende Prozedur setzt den Ausdruck zusammen, speichert ihn in einer Variablen namens strKriterium und gibt diesen im Direktfenster des VBA-Editors aus:

Private Sub txtSuche_Change()

     Dim strKriterium As String

     strKriterium = "Artikelname LIKE '" & Me!txtSuche.Text & "*'"

     Debug.Print strKriterium

End Sub

Für die Zeichenfolge abc sieht der Ausdruck wie folgt aus:

Artikelname LIKE 'abc*'

Das Sternchen sorgt dafür, dass alle Artikelnamen geliefert werden, die mit abc beginnen.

Datensatzherkunft aktualisieren

Nun müssen wir mit diesem Kriterium nur noch die Datensatzherkunft des Listenfeldes ausstatten. Daz erweitern wir einfach die Prozedur, die durch das Ereignis Bei Änderung ausgelöst wird, um eine einzige Zeile. Diese hängt das Kriterium an die SQL-Abfrage SELECT ArtikelID, Artikelname FROM tblArtikel WHERE an. Der Teil ORDER BY Artikelname sorgt schließlich noch für die Beibehaltung der vorhandenen Sortierung (siehe Listing 1).

Private Sub txtSuche_Change()

     Dim strKriterium As String

     strKriterium = "Artikelname LIKE '" & Me!txtSuche.Text & "*'"

     Me!lstArtikel.RowSource = "SELECT ArtikelID, Artikelname FROM tblArtikel WHERE " & strKriterium & " ORDER BY Artikelname"

End Sub

Listing 1: Diese Prozedur filtert das Listenfeld nach dem angegebenen Suchbegriff.

Automatische Platzhalter

Je nach Anforderung kann es sein, dass nicht nur nach solchen Einträgen gesucht werden soll, deren Name mit dem angegebenen Suchbegriff beginnt, sondern auch nach solchen, die den Suchbegriff an beliebiger Stelle enthalten. In diesem Fall haben Sie zwei Möglichkeiten:

  • Der Benutzer trägt selbst ein führendes Sternchen (*) in das Suchfeld ein.
  • Oder Sie stellen den SQL-Ausdruck so ein, dass dieser automatisch alle Vorkommen des Suchbegriffs liefert.

Auf die erste Variante müssen Sie den Benutzer gegebenenfalls hinweisen, die zweite Variante lässt sich leicht implementieren. Sie müssen dazu nur ein Sternchen an der richtigen Stelle zum Kriterium hinzufügen:

strKriterium = "Artikelname LIKE '*" & Me!txtSuche.Text & "*'"

Suche mit Option

Gegebenenfalls möchten Sie dem Benutzer ein wenig Hilfestellung bei der Auswahl der beiden Möglichkeiten bieten. Dann fügen Sie dem Formular eine Optionsgruppe mit den beiden Optionen beginnt mit und enthält hinzu (siehe Bild 5). Die Optionsgruppe erhält den Namen ogrSuchart. Die beiden Optionen haben die Werte 1 und 2. Außerdem legen Sie für die Optionsgruppe für die Eigenschaft Standardwert den Wert 1 fest. Das fertige Formular finden Sie übrigens unter dem Namen frmSchnellsucheMitOption in der Beispieldatenbank.

Option zum Auswählen der Filterart

Bild 5: Option zum Auswählen der Filterart

Im Code müssen Sie dann noch zusätzlich auswerten, welche der beiden Varianten der Benutzer gerade gewählt hat. Dies muss natürlich auch beim Wechseln der Option geschehen, und zwar unter Beibehaltung des aktuellen Suchbegriffes.

Damit das Suchergebnis nicht nur beim Ändern des Suchbegriffs, sondern auch beim Auswählen einer anderen Option aktualisiert wird, benötigen wir noch eine Ereignisprozedur, die nach dem Aktualisieren des Wertes der Optionsgruppe ausgelöst wird. Hier verwenden wir klassischerweise die Ereigniseigenschaft Nach Aktualisierung dieses Steuerelements.

Damit wir die Zusammensetzung des Suchbegriffs nur an einer Stelle programmieren müssen, erstellen wir eine private deklarierte Prozedur namens ArtikelSuchen, die von den beiden Ereignisprozeduren aus aufgerufen wird. Die beiden Ereignisprozeduren des Textfeldes und der Optionsgruppe statten wir wie folgt aus:

Private Sub ogrSuchart_AfterUpdate()

     ArtikelSuchen

End Sub

Private Sub txtSuche_Change()

     ArtikelSuchen

End Sub

Die Prozedur ArtikelSuchen gestalten wir im ersten Versuch wie in Listing 2. Der Test der Suchfunktion funktioniert, allerdings nur, bis Sie das erste Mal die Option wechseln. Dies löst den Fehler 2185 aus: Sie können auf die Eigenschaften oder Methoden eines Steuerelements nur verweisen, wenn das Steuerelement den Fokus hat. Dies bezieht sich auf die Text-Eigenschaft: Sie ist nur verfügbar, wenn das Steuerelement den Fokus besitzt. Da dies nicht geht, wenn Sie gleichzeitig auf die Optionsgruppe klicken, speichern wir Inhalt des Textfeldes nach jeder Änderung in einer Variablen namens strSuchbegriff zwischen:

Private Sub ArtikelSuchen()

     Dim strKriterium As String

     If Me!ogrSuchart = 1 Then

         strKriterium = "Artikelname LIKE '" & Me!txtSuche.Text & "*'"

     Else

         strKriterium = "Artikelname LIKE '*" & Me!txtSuche.Text & "*'"

     End If

     Me!lstArtikel.RowSource = "SELECT ArtikelID, Artikelname FROM tblArtikel WHERE " & strKriterium & " ORDER BY Artikelname"

End Sub

Listing 2: Filtern des Listenfeldes nach Suchbegriff und Option, fehlerhafte Version

Dim strSuchbegriff As String

Private Sub txtSuche_Change()

     strSuchbegriff = Me!txtSuche.Text

     ArtikelSuchen

End Sub

Erst danach rufen wir die geänderte Fassung der Prozedur ArtikelSuchen auf, die genauso wie die erste Version aussieht, sich aber auf die Variable strSuchbegriff statt auf die Eigenschaft Text des Textfelds txtSuche bezieht (siehe Listing 3).

If Me!ogrSuchart = 1 Then

     strKriterium = "Artikelname LIKE '" & strSuchbegriff & "*'"

Else

     strKriterium = "Artikelname LIKE '*" & strSuchbegriff & "*'"

End If

Listing 3: Filtern des Listenfeldes nach Suchbegriff und Option

Zusammenfassung und Ausblick

Die Schnellsuche können Sie in verschiedenen Ausprägungen überall einsetzen, wo Sie diese benötigen. Statt eines Listenfeldes lassen sich damit auch die in einem Datenblatt-Unterformular angezeigten Daten filtern. Hier können Sie alternativ zum Ändern der RowSource-Eigenschaft die Filter- sowie die FilterOn-Eigenschaft einsetzen, um die angezeigten Daten zu filtern.