User Tools

Site Tools


vba:lib:sqlfilter

[VBA] SQL Filterstrings

SQL-Filterstrings erstellen ohne grosse Schlaufen und ohne sich um Formatierungen kümmern zu müssen. Das ist das Ziel der Funktion filByArray(). Die weiteren Funktionen sind nur Aliase dazu um häufig wiederkehrende Fälle vereinfacht abzudecken

lib_sqlfilter.bas

Beispiele zur Anwendung

'Bei der Funmtkion DLOOKUP mittels Filterstringfunktion filEq() Das Datum der ID 3 auslesen
? DLOOKUP("f_date", "my_table", filEq("id", 3))
14.03.2014 00:03:00 
 
'Auszählen, wie viele Zeilen im Feld f_string leer (Null/""/"  ") sind
? DCOUNT("*", "my_table", filEq("f_string"))
 3 

Angewandt

Man kennt das. Man hat ein Filterformular mitmehreren Feldern. Je nachdem, was grad alles asugewählt wurde, muss das SQL zusammengestellt werden.

Ich habe ein Formular mit den folgenden Feldern

  • dtpFrom: DatePicker mit Checkbox
  • dtpTo: DatePicker mit Checkbox
  • txtId: Textfeld
  • txtLikeName: Textfeld

Das WHERE ist: Datum UND (id oder name)

Private Sub cmdRun_Click()
    Dim sql As String
 
    'filBetween gibt bei 2 Null-Parameter "TRUE" zurück, da man keine Eingrenzung macht
    'filAnd & filOr geben jeweils bei mehreren Values AND/OR,bei einem nur den Value und bei nix "" zurück
    'filEq würde bei null '[FELD] IS NULL' zurückgeben. Darum wird dieser vorher getestet
    sql = filAnd( _
            filBetween("f_date", Me.dtpFrom, Me.dtpTo, ftDate), _
            filOr( _
                IIf(IsNull(Me.txtId), Null, filEq("id", Me.txtId)), _
                IIf(IsNull(Me.txtLikeName), Null, filEq("f_name", "*" & Me.txtLikeName & "*")) _
            ) _
        )
 
    sql = "SELECT * FROM [my_table] WHERE " & sql
 
    'Und anwenden
    Debug.Print sql
    MsgBox sql
 
End Sub

Einige Auswertungen

-- Keinen Filter
SELECT * FROM [my_table] WHERE TRUE
-- Nur ID
SELECT * FROM [my_table] WHERE (TRUE AND [id] = 13)
-- ID und Name
SELECT * FROM [my_table] WHERE (TRUE AND ([id] = 13 OR [f_name] LIKE "*test*"))
-- Nur Name
SELECT * FROM [my_table] WHERE (TRUE AND [f_name] LIKE "*test*")
-- Nur From
SELECT * FROM [my_table] WHERE [f_date] >= #05/06/2014#
-- From + To
SELECT * FROM [my_table] WHERE ([f_date] BETWEEN #05/06/2014# AND #05/28/2014#)
-- Nur To
SELECT * FROM [my_table] WHERE [f_date] <= #05/28/2014#
-- To und Name
SELECT * FROM [my_table] WHERE ([f_date] <= #05/28/2014# AND [f_name] LIKE "*test*")
-- To, Id und Name
SELECT * FROM [my_table] WHERE ([f_date] <= #05/28/2014# AND ([id] = 13 OR [f_name] LIKE "*test*"))
-- Und alle Felder befüllt
SELECT * FROM [my_table] WHERE (([f_date] BETWEEN #05/06/2014# AND #05/28/2014#) AND ([id] = 13 OR [f_name] LIKE "*test*"))

Beispiele zu den Funktionen

filEq()

Ein einfacher Equal Filter, der sich den Werten anpasst

'Vergleich mit einem Datum
?filEq("until", now)
[until] = #05/14/2014 12:13:02#
 
'Eine Zahl vergleichen
?filEq("id", 123)
[id] = 123
 
'Feld name soll Hans heissen
?filEq("name", "Hans")
[name] LIKE "Hans"
 
'Mit Angabe des Tabellenalias
?filEq("tabelle.name", "Hans")
[tabelle].[name] LIKE "Hans"
 
'Prüfen ob das Feld Leer, Null oder Leerstrings sind
?filEq("name")
TRIM(NZ([name])) = ""
 
'Auf Null prüfen
?filEq("name", null)
[name] IS NULL
 
'Auf mehrere Werte prüfen. Der erste Eintrag gibt den Datentyp vor
?filEq("id", 123, 456, 789)
[id] IN (123, 456, 789)

filNe()

Negative Version vom Equal-Filter

?filNe("tabelle.name", "Hans")
NOT [tabelle].[name] LIKE "Hans"
 
?filNe("name")
NOT TRIM(NZ([name])) = ""
TRIM(NZ([name])) = ""

filFld()

Einen Vergleich zwieschen 2 Feldern

?filfld("a.id", "b!id")
[a].[id] = [b].[id]
 
?filfld("a.id", "b!id", finot)
NOT [a].[id] = [b].[id]
 
?filfld("a.id", "b!id", fiCompGt+finot)
NOT [a].[id] > [b].[id]

filBetween()

?filBetween("id", 5, 13)
([id] BETWEEN 5 AND 13)
 
?filBetween("id", 5, 13, fiCompBetweenVB)
(5 <= [id] AND [id] <= 13)
 
'Between mit nur einem gültigen Argument
?filBetween("a.f_date", now, null)
[a].[f_date] = #05/14/2014 15:05:44#

filAnd(), filOr()

Zwei Funktionen um schnell eine AND/OR Struktur zu erstellen

?filOr(filAnd(filNe("f_name", null), filNe("id", null)), filBetween("f_date", now-1, now))
(([f_name] NOT IS NULL AND [id] NOT IS NULL) OR ([f_date] BETWEEN #05/13/2014 14:04:04# AND #05/14/2014 14:04:04#))

fil()

Der flexible Filter, mit dem man diverse Kombinationen ausführen kann

'Datumfeld Grösser als Jetzt
?fil("f_date", fiCompGt, now)
[f_date] > #05/14/2014 14:06:22#
 
'dieses mal mit Grösser-Gleich und nur auf das Datum beschränkt
?fil("f_date", fiCompGe + fiTypeDate, now)
[f_date] >= #05/14/2014#
 
'Mal als Stringvergleich mit
?fil("f_date_string", fiCompEq + finot + fiTypeString, now)
NOT [f_date_string] = "14.05.2014 14:10:39"
 
'Und noch ein Beispiel mit IN()
?fil("table.id", fiCompEq, 1,2,3)
[table].[id] = 1
?fil("table.id", fiAutomatic, 1,2,3)
[table].[id] IN (1, 2, 3)
vba/lib/sqlfilter.txt · Last modified: 14.05.2014 16:56:00 by yaslaw