This is an old revision of the document!
Häufig hat man mehrere Filterfelder in einem Formularkopf definiert. Je nachdem was alles ausgefüllt ist, ist der Filter Komplexer oder nicht. Auf alle Fälle muss es sehr flexibel sein. Hier einige Anregungen.
Grundsätzlich sollte nie ein Filtererstellungscode direkt hinter einen Event eines Controls geschrieben werden. Immer in eine eigene Sub, die dann von mehreren Orten aufgerufen werden kann.
Als Beispiel nehmen wir ein Formular mit 3 Filter. 1) Ein Textfeld für die Adresse:
Formularfeld: txtAddress Tabellenfeld: address DataType: String
2) Eien Combobox. Inkl. einem Eintrag “-1” und der Beschriftung “ALL” Formularfeld: cbxAddressType
Tabellenfeld: addressTypeId DataType: Long
3) 2 Datumsfelder für ein Between
Formularfeld: dtFrom, dtTo Tabellenfeld: createDate DataType: Date
Ich persönlich mag den gar nicht. Aber man sieht ihn häufig. Alle Strings einfach zusammensetzen und dann schauen, ob am Ende vom String noch ein “ AND ” steht. Dieses dann abschneiden
Privat Sub createFilter() Dim flt As String If NZ(me!txtAddress) <> "" Then flt = "address LIKE '" & me!txtAddress & "' AND " End If If NZ(me!cbxAddressType, -1) > -1 Then flt = "addressTypeId = " & me!cbxAddressType & " AND " End If If Not IsNull(Me!dtFrom) And Not IsNull(Me.dtTo) Then flt = ftl & "createDate BETWEEN " & format(me!dtFrom, "\#MM-DD-YYYY\#") & " AND " & format(me!dtTo, "\#MM-DD-YYYY\#") End If 'ggf das " AND " am Ende Abschneiden If right(flt, 5) = " AND " Then flt = left(flt, len(flt) - 5) End If 'Filter setzen' If len(flt) > 0 Then Me.Filter = flt Me.FilterOn = True Else Me.Filter = Empty Me.FilterOn = False End If End Sub
Der Umweg über einen Array finde ich persönlich schöner.
Privat Sub createFilter() Dim flt() as String Dim i As Long: i = -1 If NZ(me!txtAddress) <> "" Then i = i + 1: Redim Preserve flt(i) flt(i) = "address LIKE '" & me!txtAddress & "'" End If If NZ(me!cbxAddressType, -1) > -1 Then i = i + 1: Redim Preserve flt(i) v = "addressTypeId = " & me!cbxAddressType End If If Not IsNull(Me!dtFrom) And Not IsNull(Me.dtTo) Then i = i + 1: Redim Preserve flt(i) v = ftl & "createDate BETWEEN " & format(me!dtFrom, "\#MM-DD-YYYY\#") & " AND " & format(me!dtTo, "\#MM-DD-YYYY\#") End If 'Fitler setzen If i > -1 Then Me.Filter = join(flt, " AND ") Me.FilterOn = True Else Me.Filter = Empty Me.FilterOn = False End If End Sub
Und um es möglichst einfach zuhalten, hatte ich mal den [VBA] YFilter programmiert. Damit lassens ich Filter relativ einfach erstellen
Privat Sub createFilter() Dim flt As YFilter Set flt = YFilter.createAnd If NZ(me!txtAddress) <> "" Then flt.addNewFilter("address", me!txtAddress, eftLike) If NZ(me!cbxAddressType, -1) > -1 Then flt.addNewFilter("addressTypeId", me!cbxAddressType) If Not IsNull(Me!dtFrom) And Not IsNull(Me.dtTo) Then flt.addNewFilter("createDate", array(me!dtFrom, me!dtTo)) Me.Filter = flt.filterText Me.FilterOn = flt.isActive End Sub