Schnelle Suche mit Klasse

Sie kennen sicher die Art von Schnellsuche, bei der direkt bei der Eingabe von Zeichen gefiltert wird. Diese kann sich auf eines oder mehrere Felder beziehen, arbeitet aber sonst prinzipiell immer gleich: Das Eingeben eines Zeichens löst ein Ereignis aus, dass den aktuellen Suchbegriff ermittelt, eine SQL-Where-Bedingung zusammenstellt und diese dem Filter-Kriterium des Formulars zuweist. Wie Sie eine solche Suche ganz leicht implementieren, zeigt dieser Beitrag.

In letzter Zeit stelle ich fest, dass ich eine solche Suche eigentlich in fast allen Formularen benötige – egal, ob es sich um die Formular-, Endlos- oder Datenblattansicht handelt. In der Regel reicht die Eingabe eines oder mehrerer Buchstaben aus, um schnell beim gesuchten Datensatz zu landen – eine effizientere Suchmethode gibt es nicht.

Eine Ausnahme ist es wohl, wenn Sie aus vielen Datensätzen einen oder mehrere herausfiltern möchten, die bestimmte Kriterien aufweisen – dann sind Sie aber mit einer Abfrage oder einer darauf aufbauenden umfassenderen Suchfunktion besser bedient. Die Lösung aus diesem Beitrag bezieht sich eher auf solche Anwendungsfälle, bei denen Sie mal eben den Kunden zu einer E-Mail-Anfrage herausfinden möchten oder diesen über seine Kundennummer identifizieren möchten.

Beispielsuche

Die Basis für die in diesem Beitrag beschriebene Lösung ist ein Formular wie das aus Abb. 1 (siehe Formular frmSchnellsuche in der Beispieldatenbank). Das Formular zeigt Daten in der Endlosansicht an und besitzt ein Textfeld zur Eingabe von Suchbegriffen.

pic002.png

Abb. 1: Die Beispielsuche in Aktion

Nach der Eingabe etwa des Buchstabens L filtert das Formular bereits und zeigt nur noch alle Datensätze an, deren Artikelname mit dem Buchstaben L beginnt.

Wenn Sie hier nun den Buchstaben A eingeben, zeigt das Formular nur noch alle Artikel an, deren Name mit La beginnt.

Im Entwurf sieht das Formular wie in Abb. 2 aus. Es ist an die Tabelle tblArtikel gebunden und verwendet für die Eigenschaft Standardansicht den Wert Endlosformular. Das Textfeld im Kopf des Formulars heißt txtSchnellsuche und besitzt eine Prozedur, die durch das Ereignis Bei änderung ausgelöst wird.

pic001.png

Abb. 2: Entwurfsansicht der Beispielsuche

Die Prozedur stellt zunächst ein Filterkriterium zusammen, dass aus dem Feldnamen, dem Vergleichsoperator (hier LIKE) und dem Wert der Eigenschaft Text des Such-Textfeldes besteht. Dieser Ausdruck wird dann der Eigenschaft Filter zugewiesen.

Dies geschieht jedoch nur, wenn das Suchfeld einen Vergleichswert enthält. Es kann jedoch auch sein, dass der Benutzer ein Zeichen eingibt und dieses wieder löscht. In diesem Fall gäbe es keinen Suchbegriff mehr.

Das Filterkriterium würde zwar wegen des enthaltenen Sternchens (*) dennoch wie erwartet alle Datensätze zurückliefern, aber gegebenenfalls fällt das statisch eingebaute Sternchen später einmal weg – und dann liefert das Filterkriterium schlicht keinen Datensatz mehr zurück. Also prüft die Prozedur zunächst die Länge des Vergleichswerts:

Private Sub txtSuche_Change()
    Dim strFilter As String
    If Not Len(Me!txtSuche.Text) = 0 Then
        strFilter = "Artikelname LIKE ''" & Me!txtSuche.Text & "*''"
        Me.Filter = strFilter
        Me.FilterOn = True
    Else
        Me.Filter = ""
        Me.FilterOn = False
    End If
End Sub

Warum verwenden wir hier die Text-Eigenschaft und nicht den Wert des Suchfeldes Weil der Wert erst nach dem Abschließen der Eingabe etwa durch Drücken der Eingabetaste oder Verlassen des Suchfeldes auf die aktuell im Textfeld enthaltene Zeichenkette eingestellt wird. Die Text-Eigenschaft hingegen liefert immer den aktuell angezeigten Text.

Hakelige Eingabe

Je nach der aktuellen Einstellungen der Option Cursorverhalten bei Eintritt in Feld kann es vorkommen, dass der komplette Suchbegriff markiert wird oder die Einfügemarke wieder zum Beginn des eingegebenen Textes verschoben wird.

Obwohl es nicht so aussieht, verliert das Textfeld zur Eingabe des Suchbegriffes kurz den Fokus, während der Filter eingestellt wird – und wenn das Textfeld den Fokus zurückerhält, stellt Access den Cursor so ein, wie es in den Access-Optionen vorgesehen ist.

Unter Access 2010 finden Sie diese Einstellung etwa unter Backstage|Access-Optionen und dort im Bereich Clienteinstellungen (s. Abb. 3).

pic003.png

Abb. 3: Einstellung für das Cursorverhalten

Dummerweise können Sie sich nicht darauf verlassen, dass der Benutzer die von Ihnen gewünschte Einstellung verwendet – und Sie sollten diese auch nicht selbstständig anpassen, denn dann findet der Benutzer möglicherweise an anderer Stelle nicht mehr das gewohnte Verhalten vor.

Also fügen Sie ein paar Zeilen zur Suchfunktion hinzu, die dafür sorgen, dass sich diese die Cursorposition nach der Eingabe eines Zeichens merkt und diese unabhängig von der aktuellen Einstellung der Option Cursorverhalten bei Eintritt in Feld wiederherstellt.

Außerdem verlor das Textfeld den Fokus, wenn es als Text nur noch eine leere Zeichenkette anzeigte – nach dem Zurücksetzen des Filters sollte man also noch den Fokus auf das Suchfeld zurücksetzen:

Private Sub txtSuche_Change()
    Dim strFilter As String
    Dim intStart As Integer
    intStart = Me!txtSuche.SelStart
    If Not Len(Me!txtSuche.Text) = 0 Then
        strFilter = "Artikelname LIKE ''" & Me!txtSuche.Text & "*''"
        Me.Filter = strFilter
        Me.FilterOn = True
        Me!txtSuche.SelStart = intStart
    Else
        Me.Filter = ""
        Me.FilterOn = False
        Me!txtSuche.SetFocus
    End If
End Sub

Diese Prozedur lässt sich nicht nur für Formulare in der Endlosansicht, sondern auch für solche in der Formularansicht einsetzen.

Schnellsuche in Datenblättern

In der Datenblattansicht sind natürlich kleine änderungen nötig. Formulare in der Datenblattansicht zeigen nur die Daten an und keine weiteren Steuerelemente wie Suchfelder oder OK-Schaltflächen.

Dazu müssen Sie ein Hauptformular anlegen und darin zumindest das Suchfeld und das Unterformular in der Datenblattansicht anzeigen. Dies sieht im Entwurf wie in Abb. 4 aus (siehe frmSchnellsucheDatenblatt und sfmSchnellsucheDatenblatt).

pic004.png

Abb. 4: Entwurf des Suchformulars für Datenblätter

Die Prozedur, die durch das Eingeben eines Zeichens in das Textfeld txtSuche ausgelöst wird, sieht in diesem Fall wie in Listing 1 aus. Der erste wesentliche Unterschied ist der geänderte Bezug auf das zu filternde Formular (hier Me!sfmSchnellsucheDatenblatt.Form). Der zweite ist, dass das Suchfeld beim Einstellen des Filters nicht den Fokus verliert und so einige Zeilen eingespart werden können.

Listing 1: Code zum Aktualisieren des Filters auf Basis des Suchbegriffs

Private Sub txtSuche_Change()
    Dim strFilter As String
    If Not Len(Me!txtSuche.Text) = 0 Then
        strFilter = "Artikelname LIKE ''" & Me!txtSuche.Text & "*''"
        Me!sfmSchnellsucheDatenblatt.Form.Filter = strFilter
        Me!sfmSchnellsucheDatenblatt.Form.FilterOn = True
    Else
        Me!sfmSchnellsucheDatenblatt.Form.Filter = ""
        Me!sfmSchnellsucheDatenblatt.Form.FilterOn = False
    End If
End Sub

Variationen der Schnellsuche

Nun möchten Sie eine Suche wie diese gegebenenfalls in mehreren Formularen einsetzen und dabei auch noch Varianten einbauen. Diese könnten so aussehen:

  • Sie möchten mit einem Suchfeld gleich mehrere Felder der Datenherkunft durchsuchen, also beispielsweise Vorname, Nachname und Firma eines Kunden. In diesem Fall sollen die einzelnen Filterkriterien mit dem Oder-Operator verknüpft werden.
  • Sie möchten mehrere Suchfelder einsetzen, um gezielt Felder wie Vorname, Nachname oder Firma zu durchsuchen. In diesem Fall ist der Und-Operator zur Verknüpfung der einzelnen Filterkriterien zu verwenden.

Beim Einsatz in mehreren Formularen einer Anwendungen müssten Sie gleichartig aufgebauten Code mehrfach verwenden. Günstiger wäre es, wenn man die benötigten Funktionen an einem einzigen Ort unterbringen könnte und im jeweiligen Formular nur noch die Such-Steuerelemente unterbringt und die Einstellungen für die gewünschte Suchfunktion vornimmt.

Einsatz der Schnellsuche

Bevor wir auf die technischen Details der nachfolgend beschriebenen Lösung eingehen, schauen wir uns die Funktionsweise und die Konfiguration an. Dabei gibt es die folgenden Varianten:

  • ein Suchfeld soll ein Feld filtern (zwei Möglichkeiten),
  • ein Suchfeld soll mehrere Felder filtern oder
  • mehrere Suchfelder sollen jeweils ein Feld filtern.

Bei allen Konfigurationen sind die folgenden Schritte nötig:

  • Die beiden Klassen clsFastSearch und clsFastSearchField müssen in die Zieldatenbank importiert werden.
  • Im Formular, dass das Textfeld zur Eingabe des Suchbegriffes enthält, wird eine Beim Laden-Ereignisprozedur angelegt, welche die Suche aktiviert und konfiguriert.
  • Das Klassenmodul des Hauptformulars enthält die folgende Deklaration:

Dim objFastsearch As clsFastSearch

  • Die zu durchsuchenden Felder können sich im gleichen Formular oder auch in einem Unterformular befinden.
  • Sie können eine Schaltfläche hinzufügen, die alle Suchfelder leert und den Filter zurücksetzt.

Ein Suchfeld filtert ein Feld, Variante I

Dieses Beispiel finden Sie im Formular frmEinSuchfeldEinErgebnisfeldOder. Die Eingabe von Text in das Textfeld txtSuche soll die im Endlosformular angezeigten Datensätze nach dem Artikelnamen filtern. Dazu fügen Sie die folgenden Prozedur für das Ereignis Beim Laden des Formulars hinzu:

Private Sub Form_Load()
    Set objFastsearch = New clsFastSearch
    With objFastsearch
        Set .Resultform = Me
        .AddSearchField Me!txtSuche
        .AddResultField "Artikelname"
    End With
End Sub

Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access im Unternehmen:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 1.000 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar