FilterStringBuilder & Co.

Diskussionen über den Quellcode (Module, Klassenstruktur, Schnittstellen u.s.w.) der Access Code Library

FilterStringBuilder & Co.

Beitragvon Josef Pötzl » Di 28. Jan 2014, 11:39

Hallo!

Falls mal jemand Lust hat, ein paar Klassen zu testen: in der Codelib gibt es nun eine Klassenstruktur zum Erstellen von Filterbedingungen.

SqlTools (Klasse): umgestaltetes SqlTools.bas-Codemodul, damit mehrere SQL-Dialekte parallel verwenden werden können. (Attribute VB_PredeclaredId = True ist gesetzt - damit ist immer eine Standardinstanz verfügbar. Der Import ohne ACLibImportWizard oder ACLibFilterFormWizard muss über Datei-Import erfolgen, damit dieses Attribut gesetzt wird. Beim Einfügen des Codes in eine leere Klasse muss man das selbst einstellen, falls man es nutzen will.)

FilterStringBuilder: Filterausdruck als String erzeugen.

FilterControlManager: Filterausdruck direkt aus Formular-Steuerelementen erstellen

Beispiel-DB: FilterStringBuilderBsp

Zum Einfügen in eine Anwendung gibt es das Add-In: ACLibFilterFormWizard

BTW: Wenn das Interface für die Access-Klassenstruktur einigermaßen steht, möchte ich die Funktionaltät in der DotNetLib abbilden und mit den AccessCodeLib.Data.SqlTools kombinieren.


Mögliche Varianten:
Stufe 1: nur Datentyp in Sql-tauglichen Text umwandeln.
Code: Alles auswählen
SqlText = "TextDatenfeld like " & SqlTools.TextToSqlText("ab'de*")
' oder
SqlText = "DatumsDatenfeld = " & SqlTools.DateToSqlText(Date)
' oder
SqlText = "ZahlenDatenfeld = " & SqlTools.NumberToSqlText(1.234)

Anm.: Die SqlTools-Standardinstanz muss vor der ersten Verwendung an den benötigten SQL-Dialekt angepasst oder innerhalb der Klasse die Konfigurations-Konstanten eingestellt werden.

Stufe 2: BuildCriteria verwenden
Code: Alles auswählen
SqlText = SqlTools.BuildCriteria("TextDatenfeld", SQL_Text, SQL_Like, "ab'de*")
' oder
SqlText = SqlTools.BuildCriteria("DatumsDatenfeld", SQL_Date, SQL_Equal, Date)
' oder
SqlText = SqlTools.BuildCriteria("ZahlenDatenfeld", SQL_Numeric, SQL_Equal, 1.234)


Stufe 3: Zusammengesetzten SQL-Filter-Ausdruck mit FilterStringBuilder erstellen:
Code: Alles auswählen
With New FilterStringBuilder
   .Add "TextDatenfeld", SQL_Text, SQL_Like, "ab'de*"
   .Add "DatumsDatenfeld", SQL_Date, SQL_Equal, Date
   .Add "ZahlenDatenfeld", SQL_Numeric, SQL_Equal, 1.234
   SqlText = .ToString(SQL_And)
End With


Stufe 4: Die Filtersteuerung in einem Formular an den FilterControlManager abgeben.
Code: Alles auswählen
Private WithEvents m_FilterControlManager As FilterControlManager
[...]
Private Sub InitFilterControls()
   With m_FilterControlManager.FilterControls
      .Add "TextDatenfeld", SQL_Text, SQL_Like, Me.txtFilterControlTextDatenfeld
      .Add "DatumsDatenfeld", SQL_Date, SQL_Equal, Me.txtFilterControlDatumsDatenfeld
      .Add "ZahlenDatenfeld", SQL_Numeric, SQL_Equal, Me.txtFilterControlZahlenDatenfeld
   End With
End Sub
 

mfg
Josef
Josef Pötzl
Moderator
 
Beiträge: 731
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: FilterStringBuilder & Co.

Beitragvon Josef Pötzl » Di 11. Feb 2014, 12:57

Mögliche Varianten mit SqlTools.BuildCriteria

Equal & Co. ... =, >, <
Code: Alles auswählen
     ' F = 'abc'
     Sql = .BuildCriteria("F", SQL_Text, SQL_Equal, "abc")
     ' F <= 123
     Sql = .BuildCriteria("F", SQL_Numeric, SQL_Equal + SQL_LessThan, 123)
     ' F >= #2014-01-01#
     Sql = .BuildCriteria("F", SQL_Date, SQL_Equal + SQL_GreaterThan, #1/1/2014#)
   
     ' Spezialfälle:
     ' <= + SQL_Add_WildCardSuffix zum Kennzeichnen des "ganzen Tages" obwohl nur Datum ohne Uhrzeit übergeben wird
     ' F <= #2013-12-31*#  =>  F < #2014-01-01
     Sql = .BuildCriteria("F", SQL_Date, SQL_Equal + SQL_LessThan + SQL_Add_WildCardSuffix, #12/31/2013#)

Like
Code: Alles auswählen
     ' F like 'abc*'
     Sql = .BuildCriteria("F", SQL_Text, SQL_Like + SQL_Add_WildCardSuffix, "abc")
     ' F like '*abc*'
     Sql = .BuildCriteria("F", SQL_Text, SQL_Like + SQL_Add_WildCardSuffix + SQL_Add_WildCardPrefix, "abc")

Between
Code: Alles auswählen
     ' F Between 123 And 456
     Sql = .BuildCriteria("F", SQL_Numeric, SQL_Between, 123, 456)

     ' F Between #2014-01-01# And #2014-01-31#
     Sql = .BuildCriteria("F", SQL_Date, SQL_Between, #1/1/2014#, #1/31/2014#)

     ' Spezialfälle:
     ' SQL_Between + SQL_Add_WildCardSuffix zum Kennzeichnen des "ganzen Tages"
     ' F Between #2013-01-01# And #2013-12-31*# =>  F >= #2013-01-01# And F < #2014-01-01#
     Sql = .BuildCriteria("F", SQL_Date, SQL_Between + SQL_Add_WildCardSuffix, #1/1/2013#, #12/31/2013#)

Or ... mehrere Werte auf das gleiche Datenfeld
Code: Alles auswählen
     ' F like 'a*' Or F like 'c*' Or F like 'e*'
     Sql = .BuildCriteria("F", SQL_Text, SQL_Like + SQL_Add_WildCardSuffix, Array("a", "c", "e"))
     ' F = 123 Or F = 456 Or F = 789  (Anm.: diese Variante könnte man eventuell auch als In(..)-Statement darstellen.)
     Sql = .BuildCriteria("F", SQL_Numeric, SQL_Equal, Array(123, 456, 789))
     

In(...)
Code: Alles auswählen
     ' F In (123,456,789)
     Sql = .BuildCriteria("F", SQL_Numeric, SQL_In, Array(123, 456, 789))
     ' F In ('a','b','c')
     Sql = .BuildCriteria("F", SQL_Text, SQL_In, Array("a", "b", "c"))


Was fehlt noch?
Josef Pötzl
Moderator
 
Beiträge: 731
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: FilterStringBuilder & Co.

Beitragvon Josef Pötzl » Fr 15. Mai 2015, 21:46

Update: SqlTools.cls und FilterStringBuilder.cls sind nun im trunk enthalten und somit die Schnittstelle fixiert.
Josef Pötzl
Moderator
 
Beiträge: 731
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: FilterStringBuilder & Co.

Beitragvon Josef Pötzl » Sa 26. Sep 2015, 18:17

Nächste Ausbaustufe: .net-dll

NetLibFilterStringBuilderBsp.zip
(132.91 KiB) 366-mal heruntergeladen


Anm.:
Vor der ersten Verwendung/Test bitte das Formular "DotNetLibRepair" öffnen. Dann werden die notwendigen dll-Dateien aus der Tabelle usys_AppFiles exportiert und die Verweise angepasst.
Die Beispiel-DB ist noch nicht vollständig umgestellt, da der FilterControlManager noch nicht in .net implementiert wurde.

Der .net-ConditionStringBuilder entspricht ungefähr dem VBA-FilterStringBuilder.

Änderung in der Schnittstelle:
VBA / FilterStringBuilder:
Code: Alles auswählen
Public Sub Add(ByVal FieldName As String, ByVal FieldDataType As SqlFieldDataType, _
               ByVal RelationalOperator As SqlRelationalOperators, _
               ByVal Value As Variant, _
      Optional ByVal Value2 As Variant = Null, _
      Optional ByVal IgnoreValue As Variant = Null)


Value2 wird nur für Between benötigt.
Diesen Parameter entfernte ich in der .net-Variante und verwende stattdessen eine Array-Übergabe mit 2 Werten.

Anwendungsbeispiel:
FilterStringBuilder (VBA-Klasse):
Code: Alles auswählen
.Add "NumericField", SQL_Numeric, SQL_Between, 133.45, 456


ConditionSTringBuilder (.net-Klasse):
Code: Alles auswählen
.Add "NumericField", FieldDataType_Numeric, SQL_Between, Array(133.45, 456)


Grund für diese Änderung: ich wollte nur für den Beetween-Operator keinen Parameter mitziehen, der sonst nie benötigt wird.
Allerdings werde ich in der .net-Klasse noch eine Methode AddBetween anfügen, damit man auf das Array verzichten kann.
=>
Code: Alles auswählen
.AddBetween "NumericField", FieldDataType_Numeric, 133.45, 456
Josef Pötzl
Moderator
 
Beiträge: 731
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: FilterStringBuilder & Co.

Beitragvon Andreas Vogt » So 27. Sep 2015, 10:31

Hallo,
gebe ich bei Z3 von 3 bis 2 ein, was ja imho unsinnig ist, kommt im Formular frm_CreateFilterString Z3 Between 3 And 2 raus,
während im Formular frm_CreateFilterStringFilterControls Z3 Between 2 And 3 raus kommt.

Andreas
Andreas Vogt
Entwickler
 
Beiträge: 151
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: FilterStringBuilder & Co.

Beitragvon Josef Pötzl » Mo 28. Sep 2015, 08:46

Hallo!

Das ist ein Fehler im Formular. ;)
statt
Code: Alles auswählen
.Add "Z3", SQL_Numeric, SQL_Between, Me.txtFilterZB2, Me.txtFilterZB1

sollte stehen:
Code: Alles auswählen
.Add "Z3", SQL_Numeric, SQL_Between, Me.txtFilterZB1, Me.txtFilterZB2


Aber daraus abgeleitet eine Frage:
Sollte man die Werte vertauschen, damit ein auswertbarer Between-Ausdruck entsteht?

Welche Variante ist besser?
Das Between-Statement so erzeugen, wie es vom Anwendungsersteller bzw. Anwender eingegeben wird oder die Werte vertauschen, damit nicht between 3 and 2 entsteht?

LG
Josef
Josef Pötzl
Moderator
 
Beiträge: 731
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: FilterStringBuilder & Co.

Beitragvon Andreas Vogt » Mo 28. Sep 2015, 13:13

Hallo,
die Parameter können ja nicht nur aus "Handeingabe" stammen sondern auch z.B. aus Berechnung stammen.
Ich finde schon die Funktion sollte so arbeiten mit den Parametern wie übergeben. Wenn von 3 bis 2 raus kommt ist die Ergebnismenge halt 0.

Andreas
Andreas Vogt
Entwickler
 
Beiträge: 151
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: FilterStringBuilder & Co.

Beitragvon Josef Pötzl » Mo 28. Sep 2015, 17:33

Hallo!
Ich finde schon die Funktion sollte so arbeiten mit den Parametern wie übergeben.

Ich sehe das genau so, weil damit das vom Anwendungsersteller zu erwartende Verhalten bleibt.

Anm.:
Neue Beispiel-DB:
NetLibFilterStringBuilderBsp.zip
(132.91 KiB) 345-mal heruntergeladen

... nun arbeiten die FilterControl-Klassen auch mit der .net-Bibliothek.

LG
Josef
Josef Pötzl
Moderator
 
Beiträge: 731
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: FilterStringBuilder & Co.

Beitragvon Josef Pötzl » Sa 10. Okt 2015, 14:52

Eine neue Version des ACLib-FilterForm-Wizard ist verfügbar.

Neu: Der Code for das Filterformular enthält nun alles, was man zum filtern benötigt. Anpassen ist nur noch für spezielle Filterbedingungen notwendig.

LG
Josef
Josef Pötzl
Moderator
 
Beiträge: 731
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Re: FilterStringBuilder & Co.

Beitragvon Josef Pötzl » Di 20. Okt 2015, 13:38

Nächstes Feature: Filterbedingungen gruppieren (z. B. für Or-Gruppe)

Beispiel:
Code: Alles auswählen
With New FilterStringBuilder

   Set .SqlTool = SqlTools.NewInstance("\#yyyy-mm-dd\#", "True", "*")

   .Add "F1", SQL_Numeric, SQL_Equal, 1
   
   With .NewConditionGroup(SQL_Or)
      .Add "F2a", SQL_Text, SQL_Like + SQL_Add_WildCardSuffix, "a"
      .Add "F2b", SQL_Text, SQL_Like + SQL_Add_WildCardSuffix, "a"
      .Add "F2c", SQL_Text, SQL_Like + SQL_Add_WildCardSuffix, "a"
   End With

   With .NewConditionGroup(SQL_Or)
      .Add "F3a", SQL_Boolean, SQL_Equal, True
      .Add "F3b", SQL_Boolean, SQL_Equal, True
      .Add "F3c", SQL_Boolean, SQL_Equal, True
   End With

   Debug.Print .ToString(SQL_And)

End With


Ergebnis:
((F1 = 1)) And ((F2a Like 'a*') Or (F2b Like 'a*') Or (F2c Like 'a*')) And ((F3a = True) Or (F3b = True) Or (F3c = True))
Josef Pötzl
Moderator
 
Beiträge: 731
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2010 (2013)

Nächste

Zurück zu Quellcode

cron