Juli 02, 2022, 19:07:38

Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!


Filtern eines Formulars mit Datumsvergleich in VBA

Begonnen von Umbauwfb, April 12, 2022, 11:51:01

⏪ vorheriges - nächstes ⏩

Umbauwfb

Hallo,

ich verzweifele mal wieder an einem SQL-Befehl...
Die auskommentierten Stellen sind unterschiedlichste Versuche...
Das Formular soll anhand verschiedener Case n in Bezug auf [DatumFertigSoll] gefiltert werden.

Insgesamt habe ich in der Optionsgruppe 5 Fälle...
wenn ich bei Case 1 den Fuß auf den Boden bekomme, kann ich die anderen 4 Fälle hoffentlich regeln...

Kann sich das bitte mal jemand anschauen

Vielen Dank
Harry

'*********Optionsgruppe Filter Termine bis...**********

Private Sub ogrTermineBis_AfterUpdate()
'    Dim sql As String
   
    Dim vFertigSollJahr As Date
   
'    vFertigSollJahr = Nz(DateValue([DatumFertigSoll]), 1 / 1 / 1900)
    vFertigSollJahr = DateValue([DatumFertigSoll])  '[DatumFertigSoll] kann auch Zeit beinhalten
     
    Dim dDate As Date
    Select Case ogrTermineBis
        Case 1      'ALLE anzeigen
            dDate = "1/1/1900"
           
'       Case 2      'Alle Termine bis einschließlich Heute
       
'        sql = sql & " SELECT * "
'        sql = sql & " FROM TaskFilterQ "
'        sql = sql & " WHERE vFertigSollJahr <= '" & Date & "'"
'        Me.Requery
''        sql = sql & " OR & vFertigSollValue = """
       
    End Select
    Me.Filter = "#vFertigSollJahr#>=#" & dDate & "#"        'Was stimmt hier nicht???
    Me.FilterOn = True
    Me.Requery
End Sub



Beaker s.a.

Hallo Harry,
Debug.Printkennst du?
Falls nicht, ist vielleicht dieses AddIn was für dich. Da wird
in der Installationsanleitung zuerst beschrieben, wie man SQL-
bzw. Filterstrings manuell analysiert. Nach der Installation
gibt es dann zwei zusätzliche Methoden, die ein Formular öffnen,
das Möglichkeiten zum Testen bereitstellt.

gruss ekkehard
--
Beaker s.a., der lieber an seinem eigenen Projekt arbeiten würde/sollte, aber irgendwie immer gerne seinen Senf dazu gibt ;-)
S.M.I².L.E.

ebs17

Zitatich verzweifele
Erster Tipp: Schlampigkeit raus, Präzision und Exaktheit hinein!!
Vor Try&Error etwas Wissen und gezielte Überlegung einbringen.

Dim dDate As Date  ' Date ist nicht Text!
dDate = "1/1/1900"
dDate = #1/1/1900#

Select Case ogrTermineBis
    Case 1      'ALLE anzeigen
        Me.Filter = "True"
    Case 2      'Alle Termine bis einschließlich Heute
        Me.Filter = "vFertigSollValue < Date() + 1"
End Select
Me.FilterOn = True
Mit freundlichem Glück Auf!

Eberhard

PhilS

Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

PhilS

Zitat von: ebs17 am April 12, 2022, 12:55:47        Me.Filter = "vFertigSollValue < Date() + 1"
Vorsicht! vFertigSollValue ist auch eine VBA-Variable! Die zugehörige Tabellenspalte scheint DatumFertigSoll zu sein. Auf die Tabellenspalte muss sich eine Where-Condition oder ein Filter beziehen.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

ebs17

@Philipp: Selbstredend sollte da ein Tabellenfeld verwendet werden. Die gesamte Namensgebung im Code ist aber etwas verwirrend, so dass ich mich da wohl angeschlossen habe. Aber wer so etwas initiiert, versteht das auch ...
Mit freundlichem Glück Auf!

Eberhard

PhilS

Zitat von: ebs17 am April 12, 2022, 18:33:09Aber wer so etwas initiiert, versteht das auch ...
Du bist hiermit für den Optimismus-Preis des Jahres nominiert. ;-)
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Umbauwfb

Vielen Dank für die Antworten,
das ist das erste mal, dass ich die Filterung eines Datumsfelds umsetze... da fällt am Anfang die Orientierung schwer...ich werde mich jetzt weiter einarbeiten...

Eine allgemeine Frage noch: Muss ich für die angewandte Technik Me.Filter = .......
das Vorhandensein leerer Datenfelder (das FertigSOLL-Datum [DatumFertigSoll] ist noch nicht gesetzt) programmatisch abfangen?
Mit Nz...oder...? Weil ansonsten der gesamte Code nicht durchläuft...

Oder werden die NULL-Felder durch den gesetzten Filter einfach nicht selektiert? (was zu wünschen wäre)?


Ich will bei dieser Gelegenheit noch etwas zu meinem Hintergrund sagen. Ich bin seit kurzem im Ruhestand. Vorher war ich in leitenden Positionen tätig oder habe Unternehmen geführt. Zu meinem Verantwortungsbereich gehörten in allen Unternehmen immer auch die EDV-Abteilungen. Ich habe Ende der 1980-er Jahre kommplexe rechnergesteuerte Maschinen in Produktionen eingeführt.
Ich habe in einem Unternehmen mit Programmierern ein komplettes ERP-System geschrieben. Die Programmierer haben programmiert...ich habe ihnen die Zusammenhänge und Abläufe erklärt...
Angebunden ist das ERP-System an eine auf AutoCAD basierende kundenspezifische Positionserfassung, die mit einem Varianten-Stücklistenprozessor die Stückliste liefert.
Hat man die Stückliste, kann man alle weiteren Prozesse innerhalb des ERP-Systems programmieren und steuern...inclusive Kalkulation, Kapazitätsplanung, Maschinensteuerung, Materialwirtschaft etc...etc...der komplette reale Unternehmensdurchlauf des Produkts läuft parallel virtuell mit. Virtueller und realer Ablauf beeinflussen sich gegenseitig. 

Erst jetzt habe ich damit begonnen, mir selbst VBA beizubringen...das Projekt, an dem ich arbeite, ist ein soziales Projekt.

Ich weiß also schon, von was ich rede...ich kann einfach noch nicht genügend meine Gedanken in VBA-Sprache umsetzen.
Das bitte ich ein bisschen zu bedenken.

Ich will das mal in einem anderen Zusammenhang darstellen:
Wenn ein Mensch die englische Sprache lernen will...und es gibt ein Produkt, das ihm das Erlernen der englischen Sprache enorm erleichtern würde...die Bedienungsanleitung für das Produkt aber in englischer Sprache geschrieben ist, ist das Produkt für den lernwilligen Menschen sinnlos...er kann die Bedienungsanleitung einfach nicht verstehen, weil er ja noch nicht englisch lesen kann...

So ist es auch mit Hilfestellungen...wenn die gutgemeinten Hilfestellungen für den momentanen Stand des Hilfesuchenden zu komplex formuliert werden, kann er mit dem besten Willen einfach nichts damit anfangen...
mit 2 oder 3 Zeilen Code aber schon.

Zum Schluss: Diese Gruppe hat mir unwahrscheinlich viel geholfen. Ich hätte niemals dahin kommen können, wo ich jetzt (schon) bin, wenn ich nicht so viel Unterstützung von Euch bekommen hätte.
Vielleicht ist es aufgefallen, dass ich lange nichts mehr fragen musste...ich habe aber weiter an dem Projekt programmiert...und kam alleine zurecht.

Also...noch einmal vielen Dank für die bisherige Unterstützung...und versucht bitte, an den nicht englisch sprechenden Menschen zu denken, der eine englische Bedienungsanleitung lesen soll, wenn Ihr mir helft.

Mit sonnigen Grüßen aus Lüneburg
Harry

DF6GL

Hallo,

ZitatEine allgemeine Frage noch: Muss ich für die angewandte Technik Me.Filter = .......
das Vorhandensein leerer Datenfelder (das FertigSOLL-Datum [DatumFertigSoll] ist noch nicht gesetzt) programmatisch abfangen?
Mit Nz...oder...? Weil ansonsten der gesamte Code nicht durchläuft...

Oder werden die NULL-Felder durch den gesetzten Filter einfach nicht selektiert? (was zu wünschen wäre)?

In die Eigenschaft "Me.Filter" kommt einfach eine Where-Condition (wie bei SQL), nur ohne "Where".


Ist für einen Datensatz der Filterausdruck "true", also "wahr" so wird dieser DS berücksichtigt, ansonsten eben nicht.


Nachdem ein leeres Feld (NULL) nicht verglichen werden kann, ergibt der Filter-Ausdruck "false" und diese DS werden nicht berücksichtigt.


Sollen sie berücksichtigt werden, so muss der Ausdruck diese Situation mit einschließen, d. h.

Me.Filter = "[DatumFertigSoll]  < Date() + 1 or [DatumFertigSoll] is Null"



ZitatWeil ansonsten der gesamte Code nicht durchläuft...

Das passiert, wenn der Kriteriumswert selber NULL ist. Ein (SQL-) Syntaxfehlder ist die Folge:

ZitatMe.Filter = "[DatumFertigSoll] = or [DatumFertigSoll] is Null"




Weitere Tipps:


Setze in jeden Modulkopf:

Option Compare Database
Option Explicit



Debugge den Code, indem Du an eine passende Codestelle einen Haltepunkt setzt und den Code mit F8 im Einzelschritt durchläufst. Dabei können die Variablen auf die erwarteten Inhalte geprüft werden. Und immer wieder debuggen/kompilieren ausführen....

Umbauwfb

Hallo Franz,

vielen Dank für die allgemeine Erklärung der Funktionsweise von Me.Filter
Das hilft mir sehr dabei, ein Gesamtverständnis zu erhalten!
-------------------------------
Setze in jeden Modulkopf:
Option Compare Database
Option Explicit
--------------------------------
Danke für den Hinweis...das ist im System eingestellt...ich habe es nur nicht mit kopiert, weil der Code mitten im Gesamt-Code des Formulars steht....


Momentan sieht das Ganze aus wie folgt...
Die "normalen" Fälle kann ich alle abdecken...das ist ja alles super einfach, wenn man die Sprache spricht...

Jetzt hängt es noch an Case 4-6...da bin ich noch überfordert...

'*********Optionsgruppe Filter Termine bis...**********

Private Sub ogrTermineBis_AfterUpdate()
     
    Dim dDate As Date
'    dDate = Date    Für Case 4 brauche ich das Tagesdatum...wie muss ich das hier...oder in Case 4 darstellen???
   
    Select Case ogrTermineBis
        Case 1      'ALLE anzeigen
                Me.Filter = ""
                Me.FilterOn = True
                Me.Requery '
           
        Case 2      'Alle Termine bis einschließlich Heute
                Me.Filter = "[DatumFertigSoll] < Date() +1"
                Me.FilterOn = True
                Me.Requery

        Case 3      'Alle Termine bis einschließlich Morgen
                Me.Filter = "[DatumFertigSoll] < Date() +2"
                Me.FilterOn = True
                Me.Requery
               
        Case 4      'Alle Termine bis Ende der aktuellen Woche.....hier weiss ich nicht, wie das geregelt wird
                Me.Filter = "[DatumFertigSoll] < Weekday(dDate) +2"
                Me.FilterOn = True
                Me.Requery
               
        Case 5      'Alle Termine bis Ende der aktueller Monat.....hier weiss ich nicht , wie das geregelt wird
                Me.Filter = "[DatumFertigSoll] < ??????"
                Me.FilterOn = True
                Me.Requery
               
        Case 6      'Alle Termine bis eingegebenem Datum in Feld: Forms!TaskF!txtDatumBis
                    'Das Feld ist Formatiert als tt.mm.jjjj
                    'Es gelingt mir nicht, das leere Feld abzufangen...
                    'Es gelingt mir nicht, den Filter richtig zu schreiben...
                   
                If Forms!TaskF!txtDatumBis = Null Then
                    MsgBox " Bitte tragen Sie ein Datum ein "
                End If
               
                    Me.Filter = "[DatumFertigSoll] < Forms!TaskF!txtDatumBis.Value +1"
                    Me.FilterOn = True
                    Me.Requery
    End Select
End Sub

DF6GL

April 13, 2022, 14:44:14 #10 Letzte Bearbeitung: April 13, 2022, 16:12:25 von DF6GL
Hallo,


https://docs.microsoft.com/de-de/office/troubleshoot/access/functions-return-wrong-week-number



--- lass me.Requery überall weg, das ist überflüssig, bzw. falsch.

---Case 4:    Schau Dir die Datepart-Funktion an, mit der man die Woche für ein Datum ermitteln kann.

Aber Vorsicht:   https://docs.microsoft.com/de-de/office/troubleshoot/access/functions-return-wrong-week-number 

<edit>
Gerade in diesem Jahr ist die Berechnung falsch  Berechnet: Woche 16,  lt.Kalender: Woche 15  --> falsch , vbFirstFourDays  nicht berücksichtigt
</edit>

bzw. berechne die aktuelle Anzahl der Tage in diesem Jahr und erzeuge daraus das Datum am Ende der Woche, mit dem verglichen wird.

Me.Filter = "[DatumFertigSoll] <= " &  Format(Dateserial( Year(Date),1,Date - Dateserial(Year(Date),1,1) + 7 - Weekday(Date,2)),"\#yyyy-mm-dd\#")

--- Case 5:    Letzter des Monats:  1. des Folgemonats minus 1 Tag


Me.Filter = "[DatumFertigSoll] <= " & Format ( Dateserial (Year(Date), Month(Date)+1,0) ,"\#yyyy-mm-dd\#")



Case 6:      'Alle Termine bis eingegebenem Datum in Feld: Forms!TaskF!txtDatumBis

                   
                If IsNull(Me!txtDatumBis) Then
                    MsgBox " Bitte tragen Sie ein Datum ein "
                    Exit Sub
                Else
                    Me.Filter = "[DatumFertigSoll] >= " & Format(Me!txtDatumBis,"\#yyyy-mm-dd-\#")
                End If


oder wenn leeres Feld das heutige Datum bedeuten soll:

Case 6:      'Alle Termine bis eingegebenem Datum in Feld: Forms!TaskF!txtDatumBis

                   

                    Me.Filter = "[DatumFertigSoll] <= " & Format(nz(Me!txtDatumBis,Date),"\#yyyy-mm-dd\#")
                    Me.FilterOn =True
.
.

Achtung: Alles Luftcode...

Beaker s.a.

Hallo Harry,
Case 4
Me.Filter = "[DatumFertigSoll] < DateSerial(Year(date), Month(Date), Day(date) + 6 -Weekday(Date))"
Case 5
Me.Filter = "[DatumFertigSoll] < DateSerial(iYear, iMonth + 1, 0)
Case 6
    If IsNull(Forms!TaskF!txtDatumBis) Then
'NULL ist das Unbestimmte, damit kannst du nichts vergleichen (nicht mal sich selbst)
'warum befindet sich das Feld auf einem anderen Formular?
        MsgBox " Bitte tragen Sie ein Datum ein "
    End If

gruss ekkehard
--
Beaker s.a., der lieber an seinem eigenen Projekt arbeiten würde/sollte, aber irgendwie immer gerne seinen Senf dazu gibt ;-)
S.M.I².L.E.

Beaker s.a.

Na gut, doppelt hält besser.
Obwohl meinen Filter auf den letzten Tag der Woche halte ich für besser,
da unabhängig von der KW.
--
Beaker s.a., der lieber an seinem eigenen Projekt arbeiten würde/sollte, aber irgendwie immer gerne seinen Senf dazu gibt ;-)
S.M.I².L.E.

ebs17

Date() - mit Klammern, da verwendungsfähige Funktion - im SQL-String halte ich für besser, da man dann auf die zusätzliche Formatierung, die für einen Date-Wert von außen notwendig wird, verzichten kann. Macht das Ganze kürzer und weniger fehleranfällig (beim Schreiben).
Mit freundlichem Glück Auf!

Eberhard

Beaker s.a.

--
Beaker s.a., der lieber an seinem eigenen Projekt arbeiten würde/sollte, aber irgendwie immer gerne seinen Senf dazu gibt ;-)
S.M.I².L.E.