Home > Artikel > Ausgabe 5/2013 > Filterkriterien für Formulare, Teil II

Filterkriterien für Formulare, Teil II

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Was helfen Artikel-, Kunden-, Bestell- und sonstige Daten, wenn Sie diese zwar schön in einem Formular darstellen, aber diese nicht entsprechend filtern können? In diesem Artikel zeigen wir Ihnen, wie Sie verschiedene individuelle Filterkriterien mithilfe entsprechender Steuerelemente im Formular festlegen können. Damit filtern Sie dann die in einem Unterformular enthaltenen Daten – in diesem Fall Artikelstammdaten.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1305_FilterkriterienFuerFormulare.mdb.

Filtern nach Zahlenfeldern

Für das Filtern nach Zahlen haben wir der Übersichtlichkeit halber ein neues Formular samt Unterformular angelegt. Diese heißen frmArtikelFilternZahl und sfmArtikelFilternZahl.

Die Schaltfläche zum Leeren des Filters haben wir gegenüber dem vorherigen Beispiel beibehalten (siehe Bild 1). Lediglich die dadurch ausgelöste Prozedur referenziert hier ein anderes Unterformular (siehe Listing 1).

Neues Formular für die Beispiele zum Filtern von Datensätzen nach Zahlenwerten

Bild 1: Neues Formular für die Beispiele zum Filtern von Datensätzen nach Zahlenwerten

Das erste Suchfeld soll den Inhalt des Feldes Lagerbestand untersuchen und genau passende Datensätze zurückliefern. Wenn der Benutzer also beispielsweise den Wert 0 einträgt und die Eingabetaste betätigt, sollen nur die aufgebrauchten Artikel erscheinen (siehe Bild 2). Dies erledigen Sie mit der Ereignisprozedur aus Listing 2.

Filtern nach dem Lagerbestand

Bild 2: Filtern nach dem Lagerbestand

Zahlenbereiche untersuchen

Im zweiten Beispiel wollen wir alle Artikel finden, deren Einzelpreis in einem bestimmten Bereich liegt – also etwa über 10 Euro, unter 20 Euro oder zwischen 5 und 15 Euro.

Dazu richten Sie zwei Textfelder namens txtPreisMin und txtPreisMax ein.

Außerdem soll der Benutzer die Suche durch einen Mausklick auf eine Schaltfläche starten können – diese heißt cmdPreisbereiche (siehe Bild 3).

Filtern nach Mindest- und Höchstpreis

Bild 3: Filtern nach Mindest- und Höchstpreis

Die Schaltfläche erhält eine Ereignisprozedur, die zunächst nur vollständige Angaben verarbeiten soll, also die Angabe sowohl des minimalen als auch des maximalen Preises.

Die Ereignisprozedur sieht wie in Listing 3 aus. Sie setzt zunächst ein Filterkriterium zusammen, dass für die Angaben aus Bild 4 etwa so aussieht:

Preisfilter im Einsatz

Bild 4: Preisfilter im Einsatz

Einzelpreis BETWEEN 10 AND 12

Am Ergebnis können Sie gleich ablesen, dass BETWEEN 10 AND 12 auch alle Datensätze liefert, deren Wert im Feld Einzelpreis genau 10 oder 12 beträgt.

Nun wäre es noch praktisch, wenn der Benutzer nur das erste Textfeld füllen könnte, wenn er alle Artikel mit Einzelpreisen über dem angegebenen Wert erhalten möchte – ohne Obergrenze. Oder er nutzt das zweite Textfeld, um nur die Obergrenze zu definieren. Wenn Sie dies mit der vorhandenen Prozedur ausprobieren, erhalten Sie die Fehlermeldung aus Bild 5.

Fehler beim Auslassen eines Parameters

Bild 5: Fehler beim Auslassen eines Parameters

Dem schaffen wir durch die Änderung aus Listing 4 bei der Zusammenstellung des Filterkriteriums Abhilfe.

Private Sub cmdPreisbereiche_Click()

     Dim strFilter As String

     If Not IsNull(Me!txtPreisMin) Then

         strFilter = " AND Einzelpreis >= " & Me!txtPreisMin

     End If

     If Not IsNull(Me!txtPreisMax) Then

         strFilter = strFilter _

             & " AND Einzelpreis <= " & Me!txtPreisMax

     End If

     If Len(strFilter) > 0 Then

         strFilter = Mid(strFilter, 5)

     End If

     Me!sfmArtikelFilternZahl.Form.Filter = strFilter

     Me!sfmArtikelFilternZahl.Form.FilterOn = True

End Sub

Listing 4: Nach Preisbereichen filtern, detaillierte Fassung

Die erste If...Then-Bedingung prüft, ob txtPreisMin einen Wert enthält. In diesem Fall trägt Sie einen Ausdruck wie AND Einzelpreis >= 10 in die Variable strFilter ein.

Beim Textfeld txtPreisMax läuft es ähnlich. Der Ausdruck (etwa AND Einzelpreis <= 20) wird allerdings an den bereits bestehenden Ausdruck in der Variablen strFilter angehängt. Auf diese Weise kann strFilter nun beispielsweise folgende Ausdrücke enthalten:

  • Nur txtPreisMin gefüllt: AND Einzelpreis >= 10
  • Nur txtPreisMax gefüllt: AND Einzelpreis <= 12
  • Beide gefüllt: AND Einzelpreis >= 10 AND Einzelpreis <= 12

Der Ausdruck beginnt also immer mit dem Schlüsselwort AND, was bei direkter Zuweisung einen Fehler auslösen würde. Nur wenn der Benutzer keines der beiden Felder füllt, bleibt die Variable strFilter komplett leer.

Enthält strFilter jedoch einen Wert, soll das führende AND entfernt werden.

Dazu prüft die Prozedur, ob die Länge von strFilter größer als 0 ist und übernimmt den Inhalt von strFilter ab dem fünften Zeichen:

If Len(strFilter) > 0 Then

     strFilter = Mid(strFilter, 5)

End If

Der resultierende Filterausdruck sieht dann etwa so aus:

Einzelpreis >= 10 AND Einzelpreis <= 12

Dies entspricht prinzipiell dem weiter oben verwendeten IN...BETWEEN...-Ausdruck.

Behandlung von Dezimalzahlen

Wenn der Benutzer eine Zahl mit dem in Deutschland üblichen Dezimaltrennzeichen eingibt – also dem Komma –, liefert unsere Prozedur einen Fehler (siehe Bild 6). Dies liegt daran, dass ein Ausdruck wie 10,5 direkt in das SQL-Filterkriterium übertragen wird.

Fehler bei falschem Dezimaltrennzeichen

Bild 6: Fehler bei falschem Dezimaltrennzeichen

Dieses sieht dann wie folgt aus:

Einzelpreis >= 10,5

In SQL-Ausdrücken wird das Komma jedoch als Aufzählungszeicheninterpretiert, was den entsprechenden Fehler auslöst.

Damit der Ausdruck funktioniert, müssen wir das Komma durch einen Punkt ersetzen. Dazu verwenden wir die Replace-Funktion wie in der Prozedur aus Listing 5.

Private Sub cmdPreisMitKomma_Click()

     Dim strFilter As String

     strFilter = "Einzelpreis >= " _

         & Replace(Me!txtPreisMitKomma, ",", ".")

     Me!sfmArtikelFilternZahl.Form.Filter = strFilter

     Me!sfmArtikelFilternZahl.Form.FilterOn = True

End Sub

Listing 5: Nach größeren oder gleichen Preisen suchen

Die Replace-Funktion nimmt sich den Inhalt des Textfeldes vor und ersetzt alle Vorkommen des Komma-Zeichens durch einen Punkt.

Zahlenfelder wie Texte filtern

Gelegentlich möchte man in Zahlen genauso wie in Texten suchen – beispielsweise um alle Artikelnummern zu ermitteln, die mit einer bestimmten Zahl beginnen. Dies sieht im Ergebnis beispielsweise wie in Bild 7 aus.

Suche nach Zahlen, die mit einer bestimmten Ziffer beginnen

Bild 7: Suche nach Zahlen, die mit einer bestimmten Ziffer beginnen

Gibt der Benutzer etwa den Suchausdruck 7 ein, soll das Datenblatt alle Artikel anzeigen, deren Artikelnummer mit 7 beginnen.

Dies erreichen mit dem Textfeld txtArtikelnummer und dem Ereignis Bei Änderung, für das Sie die Ereignisprozedur aus Listing 6 hinterlegen.

Private Sub txtArtikelnummer_Change()

     Dim strFilter As String

     strFilter = "ArtikelID LIKE '" _

         & Me!txtArtikelnummer.Text & "*'"

     Me!sfmArtikelFilternZahl.Form.Filter = strFilter

     Me!sfmArtikelFilternZahl.Form.FilterOn = True

End Sub

Listing 6: Filter nach Ändern des Vergleichswertes anpassen

Die Prozedur ermittelt bei jeder Änderung des Inhalts mit der Eigenschaft Text den aktuell im Textfeld angezeigten Ausdruck und stellt ein entsprechendes Kriterium zusammen.

Damit alle Artikel ausgegeben werden, deren Artikelnummer mit dem Suchkriterium beginnt, enthält der Suchausdruck noch das Sternchen (*) als Platzhalter. Der Suchausdruck sieht beispielsweise so aus:

ArtikelID LIKE '7*'

Filtern nach Datumsfeldern

Wenn Sie ein Formular nach dem Wert eines Datumsfeldes filtern möchten, müssen Sie vor allem die Speicherung von Datumsfeldern in Access kennen. Datumsangaben werden hier nämlich intern als Double-Werte gespeichert.

Die Zahl vor dem Komma entspricht dabei der Anzahl der Tage seit dem 31.12.1899, die Zahl hinter dem Komma der Uhrzeit.

Dabei entspricht etwa 0 der Uhrzeit 0 Uhr, 0,5 entspricht 12 Uhr und 0,75 der Uhrzeit 18 Uhr.

Wenn Sie nun eine Datumsangabe wie 1.1.2013, 12:00 Uhr mit dem Datum 1.1.2013 vergleichen, liefert dies keine Übereinstimmung, denn: Der 1.1.2013 um 12:00 hat den Wert 41275,5, der 1.1.2013 ohne Angabe einer Uhrzeit hat den Wert 41275.

Wenn Sie also alle Datumsangaben erhalten möchten, die auf einen bestimmten Tag fallen, muss dieser Wert größer gleich dem Datum ohne Uhrzeit und kleiner als das Datum des folgenden Tages sein – zum Beispiel so:

1.1.2013 <= x < 2.1.2013

x entspricht dann in jedem Fall dem Datum 1.1.2013 – egal, ob es noch eine Uhrzeit beziehungsweise eine oder mehrere Nachkommastellen enthält oder nicht.

SQL-Datum

Die zweite Besonderheit ist die Zusammensetzung von SQL-kompatiblen Vergleichsausdrücken mit Datumswerten. Das Datum darf nämlich nicht in einem beliebigen Format übergeben werden, wie folgendes Beispiel zeigen wird. Im Formular frmBestellungenFiltern aus Bild 8 löst das Aktualisieren des Textfeldes txtBestelldatumFilter die Ereignisprozedur aus Listing 7 aus.

Syntaxfehler bei der einfachen Datumsübergabe

Bild 8: Syntaxfehler bei der einfachen Datumsübergabe

Es erscheint die Fehlermeldung aus der Abbildung. Der Grund ist einfach: Access-SQL kommt dem Vergleichsausdruck nicht zurecht, denn das Datum sieht wie eine Zahl aus.

Es gibt nur zwei Arten, einen Vergleichsausdruck nicht als Zahl darzustellen: nämlich durch Einfassen in Anführungszeichen (Vergleich mit Zeichenketten) oder durch Einfassen in das Raute-Zeichen (#).

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!