Neuigkeiten:

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

Mobiles Hauptmenü

Mehrere Datumswerte in DAO (Excel VBA) abfragen

Begonnen von Blaupunkt79, Dezember 30, 2023, 07:40:33

⏪ vorheriges - nächstes ⏩

Blaupunkt79

Hallo Zusammen,

gibt es eine Möglichkeit mehrere Datumswerte abzufragen, speziell für Werte, die nicht per "between" abgerufen werden können und eben nicht aneinandergereiht sind?

Leider erhalte ich bei meinem Versuch einen Datentypenkonflikt.

'Datum Filter
j = 0
Set db1 = DBEngine.OpenDatabase(aktuelle_datei_f_datum, True, False)
Set rec_adr1 = db1.OpenRecordset("f_Datum9")
If rec_adr1.RecordCount > 0 Then
umsatz999 = 1
filteranzahl = filteranzahl + 1
rec_adr1.MoveFirst
Do While rec_adr1.EOF = False
j = j + 1
If j = 1 Then filter(filteranzahl) = filter(filteranzahl) & " And u.datum IN ('" & Format(CDate(RTrim(rec_adr1!f_datum)), "\#yyyy-mm-dd\#") & "'"
If j > 1 Then filter(filteranzahl) = filter(filteranzahl) & ",'" & Format(CDate(RTrim(rec_adr1!f_datum)), "\#yyyy-mm-dd\#") & "'"
rec_adr1.MoveNext
Loop
filter(filteranzahl) = filter(filteranzahl) & ")"
db1.Close
Else
db1.Close
End If

Danke

Grüße

ebs17

Dein Code ist für mich unverständlich, ich gehe nicht weiter darauf ein.

Zitatfür Werte, die nicht per "between" abgerufen werden können und eben nicht aneinandergereiht sind
In welcher Form werden diese "Werte" bereitgestellt? Datentyp?

Es ist effizient, die Tabelle gleich zu filtern. Dann hat man unmittelbar das Ergebnisrecordset und kann es verwenden.
Eine resultierende Abfrage könnte so sein:
SELECT
   yDatum
FROM
   TabelleX
WHERE
   zDatum IN(#2023-05-02#, #2023-06-04#, #2023-09-17#, #2023-11-01#)
oder so (Parameter werden in eine Parametertabelle geschrieben):
SELECT
   X.yDatum
FROM
   TabelleX AS X,
   Parametertabelle AS P
WHERE
   X.zDatum = P.parValue
Erst nach Klarheit, wie die benötigte auszuführende Abfrage aussehen soll, kommt dann die Umsetzung über VBA.
Mit freundlichem Glück Auf!

Eberhard

Blaupunkt79

Hallo Eberhardt,

ich hatte in meinem Code das "'" Zeichen zuviel, welches zu dem Fehler führte.

Die Daten liegen im Date-Type vor. Nun habe ich noch eine Frage, ob folgende SQL Abfrage Sinn ergibt.

Der Benutzer wählt aus einer Tabelle verschiedene Datumswerte aus, die er sich anzeigen lassen möchte. Das sind alles Werte, an denen der Endkunde verschiedene Artikel gekauft hat.

Aus einer weiteren Tabelle wählt er nun verschiedene Datumswerte aus, an denen der Endkunde nicht gekauft hat.

Meine SQL Abfrage lautet nun so:

ZitatSELECT *  FROM umsatz9 as U  where U.Art IN ('A','Z',"") AND U.branche IN ('ARAL') And u.datum IN (#2022-01-03#) AND NOT EXISTS (SELECT NULL FROM umsatz9 AS X WHERE X.Kunde = U.Kunde OR u.datum IN (#2022-01-05#))

Danke

Grüße


ebs17

Zitatob folgende SQL Abfrage Sinn ergibt
Sinn ergibt sich aus erfülltem Zweck und vorhandenen Strukturen und Daten.
Deine Beschreibungen und die Abfrage  vermag ich nicht als identisch zusammenzubringen.


ZitatU.Art IN ('A','Z',"")
Der Vergleich auf Nullstring erscheint sinnfrei. Es bedarf besonderer Tabellendefinition, um so etwas verwendbar zu machen. I.d.R. entspricht leer einem NULL-Inhalt, welcher wiederum anders zu handeln ist.

OR u.datum IN (#2022-01-05#)Das hat nach meinem Gefühl in der korrelierten Unterabfrage nichts zu suchen.

Daneben: Bei einem einzigen Vergleichswert kann man auch schreiben
u.datum = #2022-01-05#Das IN-Konstrukt wird man verwenden, wenn es grundsätzlich mehrere Vergleichswerte geben kann, die per OR-Verkettung abzugleichen sind.
Mit freundlichem Glück Auf!

Eberhard

Blaupunkt79

Die letztendliche SQL Abfrage entscheidet der Benutzer, indem was er auswählt.

Ich habe mal die Abfrage angepasst, aber leider werden mir Daten angezeigt, die ausgeblendet gehören. Bitte mal den Nullstring am Anfang ignorieren, funktioniert soweit.

ZitatSELECT *  FROM umsatz9 as U  where U.Art IN ('A','Z',"") AND U.branche IN ('ARAL') And u.datum IN (#2022-01-04#) AND NOT EXISTS (SELECT NULL FROM umsatz9 AS X WHERE X.Kunde = U.Kunde And u.datum IN (#2022-02-19#) and u.datum BETWEEN #2022-02-21# AND #2022-02-22#)

Dummerweise wird mir beispielsweise 1 Kunde angezeigt, der im Zeitraum 04.01.2022 und 21.02.2022 eingekauft hat und das sollte ja eigentlich nicht angezeigt werden. Ich wollte ja Kunden haben, die am 04.01.2022 eingekauft haben und u.a. am 21.02.2022 nicht. Habe ich irgendwo eine Klammer falsch positioniert oder sonst einen Fehler drinnen?

Danke

Grüße

Beaker s.a.

Hallo,

Vielleicht sollte man, wie so oft, einen kritischen Blick auf das Datenmodell werfen.
Ein Tabellenname mit einer Zahl (umsatz9), alphanumerische Fremdschlüssel (U.Art,
U.Branche), - liest sich nicht so toll.

Vielleicht lädt der TS ja mal ein Bild des Beziehungsfensters hoch.

gruss ekkehard

Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

Blaupunkt79

Hallo Zusammen,

ich habe Euch mal 2 Bilder eingefügt, um zu sehen, wie das Tool funktioniert.

Der User klickt auf diverse Filter und bestimmt somit, was ausgewertet werden soll und letztendlich damit die SQL Abfrage.





Die Datenbank habe ich wie folgt angelegt:

Sub Datenbank_umsatz()
On Error Resume Next
Dim DB As Database
Dim Antwort As Long

'Datenbank anlegen, falls nicht vorhanden
If Dir(laufwerk & "\umsatz.mdb") = "" Then
   Set DB = CreateDatabase(laufwerk & "\umsatz.mdb", dbLangGeneral)
'Datenbank öffnen
Set DB = DBEngine.OpenDatabase(laufwerk & "\umsatz.mdb", True, False)
'Datenbank anlegen
DB.Execute ("Create table umsatz9" _
          & "(Artikel char(10), Kunde char(10), Kunde_Text char(50), Branche char(50), cluster char(15), fachberater char(10), Art char(2), datum date, umsatz char(20), ertrag char(20), absatz char(20),einheit char(5))")

Else
End If

DB.Execute ("CREATE INDEX BLSCC ON umsatz9 (Artikel)")
DB.Execute ("CREATE INDEX BLSCC ON umsatz9 (Datum)")
DB.Execute ("CREATE INDEX BLSCC ON umsatz9 (Kunde)")
DB.Execute ("CREATE INDEX BLSCC ON umsatz9 (Branche)")
DB.Execute ("CREATE INDEX BLSCC ON umsatz9 (cluster)")
DB.Execute ("CREATE INDEX BLSCC ON umsatz9 (Fachberater)")
DB.Execute ("CREATE INDEX BLSCC ON umsatz9 (Art)")

DB.Close
Set DB = Nothing
End Sub

Das Befüllen der Datenbank (Excel Datei aus dem SAP (BI-Launchpad)) erfolgt folgendermaßen:

  laenge = InStrRev(Path, "\")
    Dateiname = Mid$(Path, InStrRev(Path, "\") + 1)
    Pfad = Left$(Path, laenge)
umsatz_string = ""
 
   sPfad = Pfad
   sDatei = Dateiname
   Application.ScreenUpdating = False
   
   If Dir(sPfad & sDatei) <> "" Then
      Workbooks.Open (sPfad & sDatei)
      ThisWorkbook.Activate
      'Application.ActiveWindow.Visible = False
    Else
      Exit Sub
   End If
   
   If Workbooks(sDatei).Sheets("VA06 Artikelumsatzbericht").Range("b5") <> "Variablen" Then Workbooks(sDatei).Close SaveChanges:=False: GoTo start1
   
   Set WkSh_Q = ThisWorkbook.Worksheets("UM")
   Set WkSh_Z = Workbooks(sDatei).Worksheets("VA06 Artikelumsatzbericht")
   
   WkSh_Q.Cells.Range("A1:at1").Copy Destination:=WkSh_Z.Range("a26:at26")
   
   Workbooks(sDatei).Sheets("VA06 Artikelumsatzbericht").Rows("1:25").Delete Shift:=xlUp
   
   Workbooks(sDatei).Sheets("VA06 Artikelumsatzbericht").Range("M2:a" & Rows.Count).NumberFormat = "dd.mm.yyyy"
   
   Workbooks(sDatei).Close SaveChanges:=True
   
   Application.ScreenUpdating = True
start1:

Call lesen
Application.DisplayAlerts = False

Set DB = DBEngine.OpenDatabase(aktuelle_datei_umsatz, True, False)
sSQL = "INSERT INTO umsatz9 (Artikel, Einheit, Cluster, Kunde, Kunde_Text, Fachberater, Branche, Art, Datum,Umsatz, Ertrag,Absatz)" & _
         " SELECT T.Artikel, T.Einheit, T.Cluster, T.Kunde, T.Kunde_Text, T.Fachberater, T.Branche, T.Art, T.Datum, T.Umsatz, T.Ertrag, T.Absatz" & _
         " FROM [excel 12.0 xml;hdr=yes;imex=1;DATABASE=" & sPfad & sDatei & "].[VA06 Artikelumsatzbericht$] AS T"
   DB.Execute sSQL, 128      ' dbFailOnError
   Application.DisplayAlerts = True

DB.Close
Set DB = Nothing

Soweit funktioniert das Ganze ja auch, nur mit diesen negativen Filtern habe ich so meine Probleme.

Hoffe, Ihr könnt helfen.

Danke

Grüße


PhilS

#7
Zitat von: Blaupunkt79 am Dezember 30, 2023, 13:22:15
ZitatSELECT *  FROM umsatz9 as U  where U.Art IN ('A','Z',"") AND U.branche IN ('ARAL') And u.datum IN (#2022-01-04#) AND NOT EXISTS (SELECT NULL FROM umsatz9 AS X WHERE X.Kunde = U.Kunde And u.datum IN (#2022-02-19#) and u.datum BETWEEN #2022-02-21# AND #2022-02-22#)
[...]
Habe ich irgendwo eine Klammer falsch positioniert oder sonst einen Fehler drinnen?
In deiner Unterabfrage beziehst du dich auf u.datum. u ist aber ein Alias aus der Hauptabfrage. - Das sieht sehr verdächtig aus und ist höchstwahrscheinlich nicht, was du beabsichtigst.

PS:
Zitat von: Blaupunkt79 am Dezember 30, 2023, 13:22:15... u.datum IN (#2022-02-19#) and u.datum BETWEEN #2022-02-21# AND #2022-02-22#)
Diese beiden Bedingungen können nicht wirklich beide erfüllt werden.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

ebs17

#8
ZitatIch wollte ja Kunden haben, die am 04.01.2022 eingekauft haben und u.a. am 21.02.2022 nicht.
So etwas verstehe ich.
SELECT
   U.*
FROM
   umsatz9 AS U
WHERE
   U.datum IN(#2022-01-04#)
      AND
   NOT EXISTS
      (
         SELECT
            NULL
         FROM
            umsatz9 AS X
         WHERE
            X.Kunde = U.Kunde
               AND
            X.datum IN(#2022-02-21#)
      )
SELECT
   U.*
FROM
   umsatz9 AS U
      LEFT JOIN
         (
            SELECT
               Kunde
            FROM
               umsatz9
            WHERE
               datum = #2022-02-21#
         ) AS X
         ON U.Kunde = X.Kunde
WHERE
   U.datum = #2022-01-04#
      AND
   X.Kunde IS NULL
Mit freundlichem Glück Auf!

Eberhard

Blaupunkt79

Hallo Eberhard,

Du bist ein Genie, er wertet nun die richtigen Daten aus, was ein Buchstabe so alles ausmacht.

Jetzt wollte ich mal sehr viele verschiedene negative Datumswerte testen, ob das auch funktioniert, bei folgender Abfrage sollte der Kunde XY nicht erscheinen, da er am 05.02.2022 einkaufen war. Leider wird er mir angezeigt. Das ist die Abfrage hierfür:

SELECT *  FROM umsatz9 as U  where U.Art IN ('A','Z',"") AND U.branche IN ('ARAL') And u.datum IN (#2022-01-11#) AND NOT EXISTS (SELECT NULL FROM umsatz9 AS X WHERE X.Kunde = U.Kunde And x.datum IN (#2022-02-05#) and x.datum BETWEEN #2022-02-07# AND #2022-02-09# and x.datum IN (#2022-02-14#))

Der Kunde war einkaufen am 11.01.2022 und am 05.02.2022, an allen anderen Daten war er nicht einkaufen.

Hast Du da eine Idee, wo der Fehler liegt?

Danke

Grüße

PhilS

Ich hatte es oben schon in meinen Beitrag als nachträgliche Ergänzung geschrieben...

Zitat von: Blaupunkt79 am Dezember 30, 2023, 17:52:41E X.Kunde = U.Kunde And x.datum IN (#2022-02-05#) and x.datum BETWEEN #2022-02-07# AND #2022-02-09# and x.datum IN (#2022-02-14#))
Wie soll das funktionieren, dass x.datum gleichzeitig BETWEEN #2022-02-07# AND #2022-02-09# und ebenfalls IN (#2022-02-14#) ist?


Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

ebs17

Ein Datensatzfeld enthält genau einen Wert. Du wirst also keinen Datensatz finden, wo das Datum der 05.02. UND etwas zwischen 07.02 und 09.02. UND der 14.02. ist.
Die Unterabfrage liefert somit eine leere Menge und folglich keinen Ausschluss von irgendwas.


Es kann also nur eine OR-Verknüpfung als Logik eingesetzt werden.
... And x.datum IN (#2022-02-05#, #2022-02-14#) OR x.datum BETWEEN #2022-02-07# AND #2022-02-09#)
Das IN-Konstrukt ist auch eine OR-Verknüpfung.
x.datum IN (#2022-02-05#, #2022-02-14#)entspricht
x.datum = #2022-02-05# OR x.datum = #2022-02-14#
Mit freundlichem Glück Auf!

Eberhard

Blaupunkt79

Hallo Eberhard,

klingt logisch, was Du schreibst, hab es auch so abgeändert, funktioniert nur nicht:

SELECT *  FROM umsatz9 as U  where U.Art IN ('A','Z',"") AND U.branche IN ('ARAL') And u.datum BETWEEN #2022-01-03# AND #2022-01-06# AND NOT EXISTS (SELECT NULL FROM umsatz9 AS X WHERE X.Kunde = U.Kunde And x.datum IN (#2022-02-12#) or x.datum BETWEEN #2022-02-15# AND #2022-02-17#)

Der Kunde war am 04.01.2022 einkaufen und am 14.02.2022. An allen anderen Daten nicht, leider wird er mir nicht angezeigt. Wähle ich nur ein "nicht" Datum aus, also entweder den 12.02.2022 oder 15.02-17.02.2022 dann geht es.

Hast Du eine Idee?

Danke

Grüße

ebs17

#13
- zurückgezogen -
Mit freundlichem Glück Auf!

Eberhard

PhilS

Zitat von: Blaupunkt79 am Dezember 31, 2023, 11:58:52SELECT *  FROM umsatz9 as U  where U.Art IN ('A','Z',"") AND U.branche IN ('ARAL') And u.datum BETWEEN #2022-01-03# AND #2022-01-06# AND NOT EXISTS (SELECT NULL FROM umsatz9 AS X WHERE X.Kunde = U.Kunde And x.datum IN (#2022-02-12#) or x.datum BETWEEN #2022-02-15# AND #2022-02-17#)

AND hat eine höhere Bindungswirkung als OR. Daher wird der OR-Teil am Ende komplett unabhängig von der Prüfung auf die Gleichheit des Kunden ausgewertet. Du brauchst Klammern, um das explizit zu steuern.

SELECT *  FROM umsatz9 as U 
where U.Art IN ('A','Z',"")
AND U.branche IN ('ARAL')
And u.datum BETWEEN #2022-01-03# AND #2022-01-06#
AND NOT EXISTS (SELECT NULL FROM umsatz9 AS X
   WHERE X.Kunde = U.Kunde
   And (x.datum IN (#2022-02-12#)
        or x.datum BETWEEN #2022-02-15# AND #2022-02-17#))
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor