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.
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 ““
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).
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.
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.
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.
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:
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.
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.
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.
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