Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Achtung: Dies ist nicht der vollständige Artikel, sondern nur ein paar Seiten davon. Wenn Sie hier nicht erfahren, was Sie wissen möchten, finden Sie am Ende Informationen darüber, wie Sie den ganzen Artikel lesen können.

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 4/2011.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

Zusammenfassung

Entwickeln Sie eine Klasse, mit der Sie Formularen schnell eine flexible Schnellsuche hinzufügen können.

Techniken

Formulare, VBA

Voraussetzungen

Access 2000 und höher

Beispieldateien

SchnelleSucheMitKlasse.mdb

Shortlink

www.access-im-unternehmen.de/784

Schnelle Suche mit Klasse

André Minhorst, Duisburg

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

Die Prozedur erzeugt zunächst eine Instanz der Klasse clsFastSearch. Dann weist sie ihren Eigenschaften einige Werte zu:

  • Resultform erwartet einen Verweis auf das Formular, dass die zu filternden Datensätze anzeigt. Dies kann das gleiche Formular sein wie in diesem Fall oder auch ein Unterformular. In diesem Fall würde man einen Verweis wie Me!sfmSchnellsuche.Form übergeben.
  • AddSearchField fügt einen Verweis auf das Textfeld hinzu, in das der Suchbegriff eingegeben werden soll.
  • AddResultfield erwartet die Angabe des Feldnamens der zu filternden Datensätze, der in das Filterkriterium einbezogen werden soll.

Ein Suchfeld filtert ein Feld, Variante I

Sie haben das Ende des frei verfügbaren Teils des Artikels erreicht. Lesen Sie weiter, um zu erfahren, wie Sie den vollständigen Artikel lesen und auf viele hundert weitere Artikel zugreifen können.

Sind Sie Abonnent?Jetzt einloggen ...
 

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

© 2003-2015 André Minhorst Alle Rechte vorbehalten.