Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

etwas kompliziertere (?) Filterfunktion

Begonnen von ellinho, April 27, 2015, 17:37:29

⏪ vorheriges - nächstes ⏩

ellinho

Hallo.

Ja. Ich denke auch. Der Aufbau macht mir bezüglich der Syntax nur zu schaffen.

MaggieMay

Ich habe hier mal eine Vorlage für dich:
Dim lngVon As Long, lngBis As Long     
lngVon = CLng(DateValue(Me!cbo_Monat.Column(1)))   
lngBis = CLng(DateValue(Me!cbo_Monat.Column(2)))
strFilter = "Personalnummer=" & Me!cbo_Mitarbeiter & " And " & _
                "(DatumVon < " & lngVon & " And DatumBis > " & lngBis & ") OR " & _
                "(DatumVon >=" & lngVon & " And DatumBis <=" & lngBis & ") OR " & _
                "(DatumVon <=" & lngBis & " AND DatumBis >=" & lngBis & ")"


wobei vorausgesetzt wird, dass im Kombi-Mitarbeiter die ID (wieder) an erster Stelle steht und die gebundene Spalte ist. Die Sichtbarkeit der Spalten wird über die Spaltenbreiten geregelt.

Du kannst dir die verschiedenen Möglichkeiten mit Hilfe eines Zeitstrahls recht gut veranschaulichen.
|-----------------------------------------------------------|     Monats-umschließender Zeitbereich
|----------|           |------------|             |--------------|     weitere Möglichkeiten
      |------------------ Monat X ---------------------|           Vergleichszeitraum
Freundliche Grüße
MaggieMay

ellinho

Hallo.
Danke schon mal vorab für Deine Hilfe.
Ich werde es morgen mal in Ruhe ausprobieren. Es sieht vom Code her aber auf jeden Fall schon mal so aus, als könnte es so klappen.  :D
Vielen Dank !!!

Viele Grüße
ellinho

Josef P.

#18
Hallo!

Falls es darum geht, sich überschneidende Bereiche zu finden, sollte auch folgendes funktionieren:

Prinzip:
StartDatum <= DatumBis AND EndeDatum >= DatumVon

Grundsätzlicher Tipp zum Konvertieren eines Datumswertes in SQL-Text.
Verzichtet auf die CLng-Konvertierung. Wenn man einmal auf ein DBMS mit ODBC-verknüpften Tabellen umsteigt, kann das falsche Werte liefer, da z. B. 0 ein im Jet-System ein anderes Datum als in MSSQL-DBMS darstellt.
Datum als richtiges Datum (mit #-Eingrenzung) formatiert wird dagegen immer richtige über ODBC an das jeweilige DBMS weitergegeben.

Natürlich kann man die CLng-Konvertierung lassen, wenn man ausschließlich Jet verwendet. Ich halte es nur für keinen besonderen Aufwand, gleich in einen kompatiblen Text zu formatieren - vor allem, da man solche Konvertierungen in ein paar Hilfsfunktionen unterbringen kann.

Beispiel-Code:
strFilter = "Personalnummer=" & SqlTools.NumberToSqlText(Me!cbo_Mitarbeiter) & " And " & _
            "DatumVon <= " & SqlTools.DateToSqlText(datEnde)) & " And " & _
            "DatumBis >=" & SqlTools.DateToSqlText(datStart)


mfg
Josef

ellinho

Hallo.
Habe das
ZitatDim lngVon As Long, lngBis As Long     
lngVon = CLng(DateValue(Me!cbo_Monat.Column(1)))   
lngBis = CLng(DateValue(Me!cbo_Monat.Column(2)))
strFilter = "Personalnummer=" & Me!cbo_Mitarbeiter & " And " & _
                "(DatumVon < " & lngVon & " And DatumBis > " & lngBis & ") OR " & _
                "(DatumVon >=" & lngVon & " And DatumBis <=" & lngBis & ") OR " & _
                "(DatumVon <=" & lngBis & " AND DatumBis >=" & lngBis & ")"
mal ausprobiert. Vielen Dank erst mal für die Idee.
Leider "fange" ich damit noch nicht alle Datensätze. Wenn ein monatsübergreifender Zeitraum vorliegt, soll der selbe Datensatz bei Auswahl des einen sowie des anderen Monats angezeigt werden.

Ich habe es auch mal mit Datepart probiert. Allerdings war Deine Funktion da schon weiter, denn bei Datepart wird mir überhaupt nichts angezeigt. Mit der Datepart-Funktion käme ich mit einer Datumsspalte im Auswahlkombi aus. Hier mal mein Code :
ZitatDim KombiMon As Variant, KombiJahr As Variant, DatumvonMon As Variant, DatumvonJahr As Variant, DatumbisMon As Variant, DatumbisJahr As Variant
KombiMon = DatePart("m", Me!cbo_Monat.Column(1))
KombiJahr = DatePart("yyyy", Me!cbo_Monat.Column(1))
DatumvonMon = DatePart("m", Datumvon)
DatumvonJahr = DatePart("yyyy", Datumvon)
DatumbisMon = DatePart("m", Datumbis)
DatumbisJahr = DatePart("yyyy", Datumbis)

    strFilter = "Personalnummer=" & Me!cbo_Mitarbeiter.Column(0) & " And " & DatumvonMon & " = " & KombiMon & " AND " & DatumvonJahr & " = " & KombiJahr & " OR Personalnummer=" & Me!cbo_Mitarbeiter.Column(0) & " And " & DatumbisMon & " = " & KombiMon & " AND " & DatumbisJahr & " = " & KombiJahr
So bekomme ich nur leider gar keinen Datensatz angezeigt. Gibt es noch eine andere Datumsfunktion, die man nehmen könnte?
Viele Grüße
ellinho

MaggieMay

Hi,
ZitatLeider "fange" ich damit noch nicht alle Datensätze.
kann ich mir nicht vorstellen, alle möglichen Varianten werden doch damit abgedeckt.

Aber hast du auch den Vorschlag von Josef schon ausprobiert, der ist ja noch viel einfacher.
Freundliche Grüße
MaggieMay

ellinho

Hi.
Hab den "Fehler" gefunden :
ZitatDim lngVon As Long, lngBis As Long     
lngVon = CLng(DateValue(Me!cbo_Monat.Column(1)))   
lngBis = CLng(DateValue(Me!cbo_Monat.Column(2)))
strFilter = "Personalnummer=" & Me!cbo_Mitarbeiter & " And " & _
                "(DatumVon < " & lngVon & " And DatumBis > " & lngBis & ") OR " & _
                "(DatumVon >=" & lngVon & " And DatumBis <=" & lngBis & ") OR " & _
                "(DatumVon <=" & lngBis & " AND DatumBis >=" & lngBis & ")"
Statt der letzten Variable "IngBis" musste ich "IngVon" einsetzen. Damit werden nun alle Datensätze wie gewünscht gefiltert. Vielen vielen Dank nochmal ! :)

Josef P.

#22
Hallo!

Wenn du mit der gezeigten SQL-Bedingung alle Datensätze erhältst, ist das ein wenig Zufall. ;-)

Beispiel:
lngVon = Clng(#2/1/2015#) '01.02.2015
lngBis = Clng(#2/28/2015#) '28.02.2015
Anm.: die CLng-Konvertierung lasse ich so wie sie ist, auch wenn ich das persönlich als "unsauber" betrachte.

DatumVon = 01.01.2015
DatumBis = 05.02.2015
=>
DatumVon < lngVon .. OK
DatumBis > lngBis .. Falsch

DatumVon >= lngVon .. Falsch
DatumBis <= lngBis .. OK

DatumVon <= lngBis .. OK
DatumBis >= lngBis .. Falsch

Wenn du die gezeigte Or-Variante überprüfen lassen willst, musst du im Prinzip folgende Fälle berücksichtigen:
1. Von liegt vor dem Start des Vergleichszeitraums + Bis liegt nach dem Start
2. Bis liegt nach dem Ende des Vergleichszeitraums + Von liegt vor dem Ende
3. Vor und Bis liegt innerhalb des Vergleichszeitraums

=>
strFilter = "Personalnummer=" & Me!cbo_Mitarbeiter & " And (" & _
                "(DatumVon <= " & lngVon & " And DatumBis >= " & lngVon & ") OR " & _
                "(DatumVon <=" & lngBis & " And DatumBis >=" & lngBis & ") OR " & _
                "(DatumVon >=" & lngVon & " AND DatumBis <=" & lngBis & "))"



Ich würde die Variante nehmen, die nur prüft, ob
Bis nach dem Start des Vergleichtszeitraums liegt und Von vor dem Ende des Vergleichszeitraums. ;)
strFilter = "Personalnummer=" & Me!cbo_Mitarbeiter & " And " & _
                "DatumVon <= " & lngBis & " And DatumBis >= " & lngVon


.. ergibt die gleichen Treffer, ist aber irgendwie übersichtlicher.
Anm.: Falls in den Datumswerte auch Uhrzeiten enthalten sind, müsste der Bis-Vergleichsdatsumswert (ohne Uhrzeit) um 1 Tag erhöht und dafür nur mit < statt <= verglichen werden.

Zur graphischen Überprüfung der Logik:


mfg
Josef