Lookupkombinationsfelder nach Texten filtern

Bild 1: Aufbau des Beispielformulars

Wenn Sie die Datensätze eines Unterformulars in der Datenblattansicht filtern wollen, gelingt die Eingabe in Text-, Zahlen- und Datumsfelder recht einfach. Wenn Sie jedoch ein Suchfeld für die Werte eines Lookup-Kombinationsfeldes programmieren wollen, stoßen Sie schnell an die Grenzen. Sie können die Feldinhalte nämlich nicht einfach mit den in den Feldern angezeigten Werten vergleichen, denn diese stammen ja aus den Lookup-Tabellen, mit denen solche Steuerelemente gefüllt werden. Dieser Beitrag zeigt, wie auch das Filtern nach den Werten in Kombinationsfeldern zum Kinderspiel wird.

Als Erstes zeigen wir Ihnen, wie es nicht gelingt und was somit das Problem beim Filtern nach den Inhalten von Lookup-Kombinationsfeldern ist. In unserem Beispielformular haben wir ein Textfeld zur Eingabe des Suchbegriffs, eine Suchen-Schaltfläche namens cmdSuchen sowie ein Unterformular namens sfmArtikel_Lookupfilter angelegt (s. Bild 1).

Aufbau des Beispielformulars

Bild 1: Aufbau des Beispielformulars

In einem ersten, naiven Ansatz wollen wir die Suche wie für ein normales Feld des Datentyps String durchführen. Die dazugehörige Prozedur sieht dann wie in Listing 1 aus.

Private Sub cmdSuchen_Click()
     Dim strLieferant As String
     strLieferant = Me!txtLieferant
     Me!sfmArtikel_Lookupfilter.Form.Filter = "LieferantID LIKE ''" & strLieferant & "''"
     Me!sfmArtikel_Lookupfilter.Form.FilterOn = True
End Sub

Listing 1: Erster Ansatz zum Filtern der angezeigten Werte im Kombinationsfeld

Das Ergebnis sieht wie in Bild 2 aus: Es liefert keinerlei Datensätze, obwohl das Kombinationsfeld doch einige Werte anzeigt, die mit dem Suchbegriff E* beginnen. Eine Analyse des resultierenden Filterausdrucks lässt eine Vorahnung aufkommen. Das Feld LieferantID enthält doch nur Zahlenwerte

Erster, erfolgloser Anlauf

Bild 2: Erster, erfolgloser Anlauf

LieferantID LIKE ''E*''

Es ist also klar: Auch, wenn das Kombinationsfeld die Hersteller anzeigt, sind dies nicht die Werte des an das Steuerelement gebundenen Feldes LieferantID. Lieferant-ID gibt lediglich an, mit welchem Datensatz der Tabelle tblLieferanten der aktuelle Datensatz der Tabelle tblArtikel verknüpft ist. Das Feld enthält also, wenn wie in diesem Fall referenzielle Integrität definiert ist, mit Sicherheit nur Zahlenwerte.

Sie könnten nun den Wert 1 als Suchbegriff in das Textfeld txtFirma eingeben. Das Ergebnis wäre für den Benutzer eher noch verwirrender als das vorherige: Es erscheinen nämlich alle Datensätze mit dem Lieferanten Exotic Liquids.

Dieser hat wiederum, wie Sie vielleicht erahnen, den Wert 1 im Feld LieferantID der Tabelle tblLieferanten, also zeigt das Unterformular nach dem Filtern alle Datensätze der Tabelle tblArtikel an, die diesem Lieferanten zugeordnet sind.

Noch verwirrender wird es, wenn Sie beispielsweise den Wert 1* eingeben. Dann erscheint das Ergebnis aus Bild 3.

Alle Artikel, die zu einem Lieferanten gehören, der mit einer LieferantID wie 1* beginnt

Bild 3: Alle Artikel, die zu einem Lieferanten gehören, der mit einer LieferantID wie 1* beginnt

Der Benutzer würde dies nun gar nicht mehr einordnen können, aber wir wissen: Das sind alle Artikel, deren Feld Lieferant-ID einen Wert enthält, der mit 1 beginnt.

Filtern nach dem angezeigten Wert

Damit wenden wir uns dem eigentlichen Ziel dieses Beitrags zu: Wir wollen ja nicht nach den Fremdschlüsselwerten filtern, sondern nach dem Wert, der im Kombinationsfeld angezeigt wird. Hier gibt es verschiedene Ansätze, die wir uns nun ansehen.

Im Grunde ist es ganz einfach: Wir müssen lediglich die Abfrage in der Ereignisprozedur der Schaltfläche cmdSuchen anpassen, um das Ergebnis aus Bild 4 zu erhalten! Die entsprechende Zeile sieht dann wie folgt aus:

Diese Artikel wollen wir sehen.

Bild 4: Diese Artikel wollen wir sehen.

Me!sfmArtikel_Lookupfilter.Form.Filter = _
    & "LieferantID IN (SELECT LieferantID FROM tblLieferanten WHERE Firma LIKE ''" & strLieferant & "'')"

Der nackte SQL-Ausdruck etwa nach Eingabe des Suchausdrucks E* sieht wie folgt aus:

LieferantID IN (
     SELECT LieferantID 
     FROM tblLieferanten 
     WHERE Firma LIKE ''E*''
)

Was bedeutet das nun Wir verwenden hier immer noch das Feld LieferantID als Vergleichsfeld. Allerdings unterscheidet sich der Rest gravierend von der vorherigen Version.

Der erste Unterschied ist, dass wir nicht den Operator LIKE (oder auch das Gleichheitszeichen) verwenden, sondern den IN-Operator.

Dieser erwartet eine Menge von einem oder mehreren Vergleichswerten, die immer in Klammern angegeben werden müssen. Die Vergleichswerte können als kommaseparierte Liste angegeben werden, also etwa so:

IN (1, 2, 3)

In diesem Fall ist die Menge der Vergleichswerte jedoch dynamisch und von den Werten der Tabelle tblLieferanten abhängig, daher nutzen wir in Klammern eine SELECT-Abfrage:

SELECT LieferantID FROM tblLieferanten WHERE Firma LIKE ''E*''

Die Abfrage liefert alle Werte des Feldes LieferantID der Tabelle tblLieferanten, deren Feld Firma mit dem Buchstaben E beginnt (LIKE E*) – hier steckt also nun ein weiterer Vergleichsoperator, der diesmal festlegt, mit welchem Suchbegriff die im Kombinationsfeld angezeigten Werte verglichen werden sollen.

Dies ist die einfachste Lösung, um ein Lookup-Kombinationsfeld nach den angezeigten Werten zu filtern.

Variante mit erweiterter Datenherkunft

Die zweite Variante setzt ein wenig Vorarbeit voraus, dafür ist die Gestaltung des Filter-Kriteriums wesentlich einfacher. Wir verwenden hier im Formular frmArtikel_Look-upfilter_II die Abfrage aus Bild 5 als Datenherkunft des Unterformulars.

Erweiterte Datenherkunft des Formulars

Bild 5: Erweiterte Datenherkunft des Formulars

Der Unterschied zum Einsatz der reinen Tabelle tblArtikel ist, dass wir die Tabelle tblLieferanten noch hinzugefügt und aus dieser Tabelle das Feld Firma in das Entwurfsraster gezogen haben.

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

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar