Mehrere Felder gleichzeitig durchsuchen

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Normalerweise legen ein Textfeld an, in das Sie einen Suchbegriff eingeben und die Daten dann in einem oder mehreren Feldern nach diesem Suchbegriff durchsuchen. Oder Sie haben mehrere Suchfelder etwa für Vorname, Nachname et cetera. Dieser Beitrag stellt ein Suchsteuerelement vor, mit dem Sie gezielt nach den Inhalten verschiedener Felder gleichzeitig suchen können. Dabei gibt es mehrere Vorlagen, die vorab festgelegt werden und die der Benutzer dann einstellt, um die Suchbegriffe einzugeben.

Vorbereitung

Als Vorbereitung statten wir eine Beispieldatenbank mit den Tabellen der Datenbank Suedsturm aus, von der wir vor allem die Tabelle tblKunden benötigen.

Danach erstellen wir ein Unterformular namens sfmKunden, dessen Eigenschaften Datensatzquelle wir mit der Tabelle tblKunden füllen. Danach ziehen wir alle Felder dieser Tabelle aus der Feldliste in den Detailbereich der Entwurfsansicht. Stellen Sie die Eigenschaft Standardansicht auf den Wert Datenblatt ein und speichern und schließen Sie das Formular.

Anschließend erstellen wir ein weiteres Formular namens frmKundenEinfacheSuche. Diesem fügen wir ein Kombinationsfeld namens cboEinfacheSuche hinzu. Darunter fügen wir das Unterformular ein, indem wir das Formular sfmKunden aus dem Navigationsbereich in den Formularentwurf ziehen. Für dieses Steuer-element stellen wir die beiden Eigenschaften Horizontaler Anker und Vertikaler Anker auf den Wert Beide ein. Das Ergebnis sieht wie in Bild 1 aus.

Suchkombinationsfeld und Unterformular

Bild 1: Suchkombinationsfeld und Unterformular

Einfache Suchfunktion

Zum Warmwerden bauen wir eine einfache Suchfunktion ein, die nur die Datensätze des Feldes Firma nach dem eingegebenen Begriff durchsucht. Diese soll durch das Betätigen der Eingabetaste nach der Eingabe des Suchbegriffs beziehungsweise beim Verlassen des Kombinationsfeldes cboEinfacheSuche ausgelöst werden. Dafür ist das Ereignis Nach Aktualisierung verantwortlich, für das wir die folgende Ereignisprozedur hinterlegen:

Private Sub cboEinfacheSuche_AfterUpdate()
     Dim strFilter As String
     Dim strVergleichsausdruck As String
     strVergleichsausdruck = Nz(Me!cboEinfacheSuche, "")
     If Len(strVergleichsausdruck) > 0 Then
         strFilter = "Firma LIKE ''''" _
             & strVergleichsausdruck & "''''"
     End If
     With Me!sfmKunden.Form
         .Filter = strFilter
         .FilterOn = True
     End With
End Sub

Diese einfache Suche liest den Inhalt des Kombinationsfeldes in die Variable strVergleichs-ausdruck ein, wobei der Benutzer Platzhalter wie das Sternchen (*) selbst eingeben muss. Dann prüft die Prozedur, ob die Länge des in strVergleichsausdruck enthaltenen Strings größer als 0 ist. Falls ja, wird dieser zu einem Filterausdruck wie Firma LIKE ”””” zusammengesetzt, wobei dem eingegebenen Ausdruck entspricht. Anderenfalls wird der Filterausdruck in strFilter gar nicht gefüllt. In beiden Fällen wird der Inhalt von strFilter der Eigenschaft Filter des Form-Objekts des Unterformulars zugewiesen und die Eigenschaft FilterOn auf True eingestellt. Das Ergebnis etwa nach Eingabe des Ausdrucks B* sieht wie in Bild 2 aus. Das Leeren des Kombinationsfeldes und das Bestätigen dieser Eingabe zeigt wieder alle Einträge der Datensatzquelle im Unterformular an.

Die einfache Suche in Aktion

Bild 2: Die einfache Suche in Aktion

Zwei Vergleichsausdrücke für zwei Felder gleichzeitig

Nun wollen wir uns dem gewünschten Ergebnis annähern. Wir wollen ja Vergleichsausdrücke für mehrere Felder gleichzeitig eingeben können. Dazu fügen wir dem Formular ein weiteres Kombinationsfeld namens cboFirmaUndKontaktpersonFiltern hinzu.

Das Ergebnis nun soll sein, dass wir zwei durch Komma getrennte Vergleichswerte für das Feld Firma und das Feld Kontaktperson eingeben können und dass die beiden Felder dann nach diesen beiden Ausdrücken gefiltert werden. Das Ergebnis soll dann etwa wie in aussehen, wo wir alle Kunden ermitteln wollen, bei denen sowohl die Firma als auch der Name der Kontaktperson mit A beginnt (siehe Bild 3).

Suche nach zwei Begriffen in zwei Feldern

Bild 3: Suche nach zwei Begriffen in zwei Feldern

Wie sieht nun die Prozedur aus, die durch das Ereignis Nach Aktualisierung des Kombinationsfeldes cboFirmaUndKontaktpersonFiltern ausgelöst wird Diese beginnt ähnlich wie die vorherige Prozedur – mit der Ausnahme, dass wir ein paar weitere Variablen deklarieren:

Private Sub cboFirmaUndKontaktpersonFiltern_AfterUpdate()
     Dim strFilter As String
     Dim strVergleichsausdruck As String
     Dim strFirma As String
     Dim strKontaktperson As String
     strVergleichsausdruck =  Nz(Me!cboFirmaUndKontaktpersonFiltern, "")

Enthält die Variable strVergleichsausdruck einen Wert, weisen wir der Variablen strFirma den Teil aus strVergleichsausdruck bis zum ersten Leerzeichen zu und stellen den ersten Teil des Filterausdrucks in strFilter zusammen:

     If Not Len(strVergleichsausdruck) = 0 Then
         strFirma = Split(strVergleichsausdruck, " ")(0)
         strFilter = "Firma LIKE ''''" & strFirma & "''''"

Dann prüfen wir in einer If-Bedingung, ob strVergleichsausdruck noch einen zweiten Vergleichswert enthält. Dazu schauen wir, ob sich darin ein Leerzeichen befindet. Ist das der Fall, können wir auf den zweiten Wert des mit der Split-Funktion ermittelten Arrays zugreifen und diesen in der Variablen strKontaktperson speichern:

         If InStr(1, strVergleichsausdruck, " ") > 0 Then
             strKontaktperson =  Split(strVergleichsausdruck, " ")(1)
             strFilter = strFilter & " AND Kontaktperson  LIKE ''''" & strKontaktperson & "''''"
         End If
     End If

Danach aktivieren wir wie gehabt den Filter für diesen Filterausdruck:

     With Me!sfmKunden.Form
         .Filter = strFilter
         .FilterOn = True
     End With
End Sub

Nun weiß der Benutzer im Gegensatz zu uns allerdings nicht, wie man die Suchbegriffe in das Textfeld eingeben muss, damit es das gewünschte Ergebnis liefert. Deshalb fügen wir nun eine Vorlage zum Kombinationsfeld hinzu, anhand derer der Benutzer erkennen kann, welche Daten er dort eingeben kann. Dazu stellen wir das Kombinationsfeld mit dem Wert Wertliste für die Eigenschaft Herkunftsart auf die Anzeige einer Wertliste um. Diese geben wir wie folgt für die Eigenschaft Datensatzherkunft an:

"[Firma] [Ansprechpartner]"

Damit das Kombinationsfeld diesen Eintrag nun auch anzeigt, wählen wir gleich beim Laden des Formulars den ersten Eintrag des Kombinationsfeldes aus. Dazu hinterlegen wir die folgende Anweisung für das Ereignis Beim Laden des Formulars:

Private Sub Form_Load()
     Me!cboFirmaUndKontaktpersonFiltern = _
         Me!cboFirmaUndKontaktpersonFiltern.ItemData(0)
End Sub

Wenn der Benutzer den Fokus auf das Kombinationsfeld verschiebt, soll der Inhalt komplett angezeigt werden. Auf diese Weise kann der Benutzer dann gleich mit der Eingabe des Suchbegriffs beziehungsweise der Suchbegriffe beginnen. Dazu stellen wir den Wert der Eigenschaft SelStart des Kombinationsfeldes auf 0 ein und den Wert der Eigenschaft SelLength auf 999. Das erledigen wir in der Ereignisprozedur, die durch das Ereignis Bei Fokuserhalt des Kombinationsfeldes ausgelöst wird:

Private Sub cboFirmaUndKontaktpersonFiltern_GotFocus()
     Me!cboFirmaUndKontaktpersonFiltern.SelStart = 0
     Me!cboFirmaUndKontaktpersonFiltern.SelLength = 999
End Sub

Das Ergebnis beim Anzeigen des Formulars sieht nun wie in Bild 4 aus.

Anzeige des Schemas für den Suchbegriff

Bild 4: Anzeige des Schemas für den Suchbegriff

Wenn wir nun die zwei gewünschten Suchbegriffe eingeben, erhalten wir das gleiche Ergebnis wie im vorherigen Beispiel.

Verschiedene Kombinationen für Suchbegriffe

Nun möchte der Benutzer sicher nicht nur nach der Kombination aus Firma und Kontaktperson suchen, sondern vielleicht auch einmal nach Kunden-Code und Firma oder Kunden-Code und Kontaktperson. Damit wird die Lösung nun interessant, denn wir müssen uns überlegen, wie wir mehrere Varianten behandeln.

Die grundlegende Idee ist, dass wir die verschiedenen Kombinationen alle im Kombinationsfeld zur Auswahl anbieten und dass der gewünschte Eintrag einfach per Nach oben– und Nach unten-Taste angesteuert werden kann. Außerdem wollen wir nicht für jede neue Kombination die Eigenschaft Datensatzherkunft des Kombinationsfeldes ändern und schon gar nicht jedes Mal den Code für die neue Kombination anpassen.

Also überlegen wir uns, wie wir das Ganze etwas flexibler handhaben können. Die erste Idee ist, die verschiedenen Kombinationen plus die beteiligten Felder in einer Tabelle zu hinterlegen, aus der das Kombinationsfeld dann seine Daten zur Auswahl bezieht.

Diese Tabelle könnte im Entwurf etwa wie in Bild 5 aussehen.

Entwurf der Tabelle für die Kombinationen

Bild 5: Entwurf der Tabelle für die Kombinationen

Das Feld Kombination nimmt den anzuzeigenden Platzhalter an, also etwa [Firma] [Kontaktperson]. Die Felder Feld1, Feld2 und Feld3 nehmen die einzelnen Namen der Felder, die durchsucht werden sollen, auf. Damit ist auch klar, dass wir die Anzahl der zu durchsuchenden Felder auf drei begrenzen wollen.

Das Feld Formularname soll den Namen des Formulars aufnehmen, in dem diese Kombination zum Einsatz kommt. Auf diese Weise können wir Kombinationen für verschiedene Formulare speichern. Für die beiden Felder Kombination und Formularname haben wir einen eindeutigen, zusammengesetzten Index hinterlegt, damit jede Kombination nur einmal je Formular angezeigt werden kann.

Wir hinterlegen zunächst einige Kombinationen wie in Bild 6 in der Tabelle tblKombinationen.

Beispielkombinationen in der Tabelle tblKombinationen

Bild 6: Beispielkombinationen in der Tabelle tblKombinationen

Kombinationen im Kombinationsfeld anzeigen

Nun fügen wir dem Formular ein neues Kombinationsfeld namens cboSuchkombinationen hinzu.

Diese verwendet als Herkunftstyp wieder Tabelle/Abfrage und zwar eine Abfrage, die wie in Bild 7 aussieht und alle Felder der Tabelle tblKombinationen enthält. Für das Feld Kombination legen wir eine aufsteigende Reihenfolge fest, für das Feld Formularname den Namen unseres Formulars als Parameter. Wir wollen wieder in der Ereignisprozedur für das Ereignis Beim Laden des Formulars das Kombinationsfeld auf den ersten Eintrag einstellen:

Datensatzherkunft des Formulars zur Eingabe der Suchkombinationen

Bild 7: Datensatzherkunft des Formulars zur Eingabe der Suchkombinationen

Private Sub Form_Load()
     Me!cboSuchkombinationen = _
         Me!cboSuchkombinationen.ItemData(0)
End Sub

Wenn wir das Formular nun öffnen und das Kombinationsfeld aufklappen, sieht dies wie in Bild 8 aus.

Kombinationsfeld mit Suchkombinationen

Bild 8: Kombinationsfeld mit Suchkombinationen

Wir wollen nun zunächst die Auswahl nur über das Aufklappen uns Selektieren eines Eintrags erledigen – um das Auswählen mit der Nach oben– und der Nach unten-Taste kümmern wir uns später.

Das erste Problem, dem wir uns ausgesetzt sehen, ist die Meldung, die beim Eingeben eines neuen Wertes in das Kombinationsfeld erscheint und die wie in Bild 9 aussieht.

Meldung nach Bestätigung der Eingabe des Suchbegriffs

Bild 9: Meldung nach Bestätigung der Eingabe des Suchbegriffs

Die Meldung ist logisch: Wenn wir in ein Kombinationsfeld, das an eine Datensatzherkunft gebunden ist, einen neuen Wert eingeben und die Eingabe abschließen, prüft Access, ob der eingegebene Eintrag bereits vorhanden ist.

Um diese Meldung zu umgehen, nutzen wir das Ereignis Bei nicht in Liste. Hier wollen wir einfach dafür sorgen, dass die Meldung nicht angezeigt wird, was wir durch Einstellen des Wertes acDataErrAdded für den Parameter Response erledigen:

Private Sub cboSuchkombinationen_NotInList( _
          NewData As String, Response As Integer)
     Response = acDataErrAdded
End Sub

Dies führt aber auch nicht zu einem zufriedenstellenden Ergebnis, wie Bild 10 zeigt – wir können keinen neuen Wert eingeben und das Kombinationsfeld verlassen.

Der neue Eintrag kann nicht ohne weiteres eingegeben werden.

Bild 10: Der neue Eintrag kann nicht ohne weiteres eingegeben werden.

Inhalt der Tabelle tblKombinationen in Wertliste einlesen

Beim vorherigen Beispiel, bei dem wir die Vorlage für die Suche als Element einer Wertliste zum Kombinationsfeld hinzugefügt haben, war dies jedoch problemlos möglich. Also kehren wir doch zum Ansatz mit der Wertliste zurück. Allerdings füllen wir diese Wertliste beim Anzeigen des Formulars per VBA-Code. Zunächst stellen wir jedoch den Wert der Eigenschaft Herkunftsart wieder auf Wertliste ein. Danach erweitern wir die Ereignisprozedur, die durch das Ereignis Beim Laden des Formulars ausgelöst wird, wie in Listing 1. Hier erstellen wir einen Verweis auf das aktuelle Database-Objekt und öffnen ein Recordset auf Basis der Tabelle tblKombinationen, wobei wir wieder nur die Einträge berücksichtigen, die zum aktuell geöffneten Formular gehören. Dann durchlaufen wir alle Datensätze dieses Recordsets und fügen für jeden durch Semikola separiert die Werte der Felder KombinationID, Kombination, Feld1, Feld2 und Feld3 hinzu. Falls die Zeichenkette nicht leer ist, schneiden wir dann das führende Semikolon ab, sodass eine Zeichenkette wie folgt entsteht:

Private Sub Form_Load()
     Dim db As DAO.Database
     Dim rst As DAO.Recordset
     Dim strRowSource As String
     Set db = CurrentDb
     Set rst = db.OpenRecordset("SELECT * FROM tblKombinationen WHERE Formularname = ''''" & Me.Name _
          & "'''' ORDER BY Kombination", dbOpenDynaset)
     Do While Not rst.EOF
         strRowSource = strRowSource & ";" & rst!KombinationID
         strRowSource = strRowSource & ";" & rst!Kombination
         strRowSource = strRowSource & ";" & rst!Feld1
         strRowSource = strRowSource & ";" & rst!Feld2
         strRowSource = strRowSource & ";" & rst!Feld3
         rst.MoveNext
     Loop
     If Len(strRowSource) > 0 Then
         strRowSource = Mid(strRowSource, 2)
     End If
     Me!cboSuchkombinationen.RowSource = strRowSource
     Me!cboFirmaUndKontaktpersonFiltern = Me!cboFirmaUndKontaktpersonFiltern.ItemData(0)
     Me!cboSuchkombinationen = Me!cboSuchkombinationen.ItemData(0)
End Sub

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar