Access-o-Mania

Access-Forum (Deutsch/German) => Access Programmierung => Thema gestartet von: Blaupunkt79 am Januar 01, 2024, 11:22:05

Titel: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: Blaupunkt79 am Januar 01, 2024, 11:22:05
Hallo Zusammen,

besteht die Möglichkeit, wenn die DAO Abfrage mittels VBA durch Access ausgeführt wird, einen Bearbeitungsstand abzufragen? Speziell bei längeren Abfragen wäre es für den Benutzer interessant zu erfahren. Sobald die Access Tabelle erzeugt wurde und VBA wieder "aktiv" ist, wäre die Abfrage ja kein Problem. Leider nimmt teils die Erzeugung der Abfragetabelle sehr viel Zeit in Anspruch.

Danke

Grüße
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: MzKlMu am Januar 01, 2024, 11:50:49
Hallo,
prinzipiell ist das keine gute Idee, denn für eine Fortschrittsanzeige muss die Abfrage unterbrochen werden, die Anzeige aktualisiert und die Abfrage dann fortgesetzt werden. Das kostet Zeit und macht die Zeit für die Abfrage noch länger. Wobei ich gar nicht weis, ob das überhaupt möglich ist.

Es ist auch bedenklich, wenn eine Abfrage lange braucht. Bei korektem nomalisiertem Aufbau der DB und indizierung der relevanten Felder sollte (fast) jede Form von Abfragen in wenigen Sekunden erledigt sein.

Im ersten Schritt solltest Du also mal versuchen die Abfrage zu optimieren.

Wie sieht denn die Abfrage aus (SQL) ?
Was ist die Aufgabe der Abfrage ?
Was verstehst Du unter Abfragetabelle ? Wird da wirklich eine Tabelle erzeugt, oder ist das nur eine Abfrage auf Basis einer Tabelle ?
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: Blaupunkt79 am Januar 01, 2024, 12:49:07
Hallo Klaus,

am längsten dauern eben die "negativen" Abfragen (AND NOT EXISTS), eine Beispielabfrage:

SELECT * 
FROM umsatz9 as U 
where U.Art IN ('A','Z',"")
And U.cluster IN ('HDL')
And u.datum BETWEEN #2023-01-03# AND #2023-01-04#
AND NOT EXISTS
(
SELECT NULL FROM umsatz9 AS X
WHERE X.Kunde = U.Kunde
And (
x.datum BETWEEN #2023-02-20# AND #2023-02-25#
or x.datum BETWEEN #2023-02-27# AND #2023-02-28#
)
)

Die relevanten Felder sind bereits indiziert.

Access erstellt ja aus der Abfrage im Hintergrund eine Tabelle über die Resultate:

Set rec_adr = DB.OpenRecordset(sqlsearch)

Nun würde ich dem Benutzer gerne einen Hinweis geben, wie der Stand der Bearbeitung ist.

Danke

Grüße
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: MzKlMu am Januar 01, 2024, 13:47:44
llo,
ich sehe da keine Möglichkeit. Du müsstest ja in der Abfrage selbst nachsehen wie weit diese ist. Ich kann mir nicht vortstellen, dass das überhaupt möglich ist.
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: ebs17 am Januar 01, 2024, 15:47:09
DAO-Abfrage: Der Begriff ist abseits der Realität: Eine Abfrage ist SQL und wird von der DB-Maschine ausgeführt, in Access also von Jet/ACE.
DAO ist wie ADODB eine Zugriffstechnologie, also ein Mittel, Abfragen und Anweisungen an die DB-Maschine zu senden.

SQL ist Massendatenverarbeitung, nach außen für den Ausführenden ALLES auf einmal. Es gibt keine Möglichkeit zum Abruf von Zwischenständen. Wenn Du letzteres willst, musst Du (VBA)Schleifen laufen und hast darüber Möglichkeiten.

ZitatDie relevanten Felder sind bereits indiziert.
Wichtiger Punkt für mögliche Performance.
Welche genau?

2 weitere Punkte sind anzusprechen:
WHERE X.Kunde = U.Kunde
Diese Verknüpfung ist eine vergleichende Operation. Dabei ist es nicht ganz unerheblich, wieviel Bytes jeweils zu vergleichen sind. Mit Zahlen (Long: 4 Byte) kann der Computer das besser als mit Texten.

Das größere Problem ist aber die korrelierte Unterabfrage. Eine solche wird jedesmalig pro Datensatz der Hauptabfrage ausgeführt, und dieser summierte Aufwand wird sich in benötigter Zeit widerspiegeln, eingebaute Schwächen in der Unterabfrage dann quasi exponiert.
In Deinem Vorgängerthema hatte ich Dir zwei Abfragevarianten gezeigt. Bei der zweiten mit dem LEFT JOIN wird die Unterabfrage (nunmehr im FROM-Teil) nur einmal ausgeführt. Das hat Wirkungen ...

Für die anderen zu einer pauschalen Übersicht:
Wie groß ist die Gesamtzahl der Datensätze in der Tabelle? Welche Zeit genau heißt "lange"?
Welche der genannten Maßnahmen führen zu einer spürbaren Laufzeitverbesserung?
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: Blaupunkt79 am Januar 01, 2024, 16:44:04
Hallo Zusammen,

eine vollständige Datenbank hat ca. 3253348 Datensätze.

Folgende Felder werden bei Anlage der Datenbank indiziert:

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)")

Ich werde morgen mal die Felder "Kunde" sowie "Artikel" als Zahl abändern und berichten, ob es zu schnellerer Verarbeitung kommt.

Aktuell läuft eine "negativ" Abfrage über 6 Stunden, ich möchte wissen, welche Kunden vom 18.12-31.12.2023 einkaufen waren und vom 02.01-17.12.2023 nicht.

An die Left Join Variante habe ich mich noch nicht rangetraut, werde ich die Tage auch noch machen.

Danke

Grüße
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: ebs17 am Januar 01, 2024, 16:55:43
3,25 Mio Datensätze sind natürlich eine Hausnummer. Da sollte man gleich genau wissen, was man zu tun hat.
Zitatdie Left Join Variante ... werde ich die Tage auch noch machen
Das solltest Du unbedingt. Alles über über einer Minute sollte schwer akzeptierbar sein (ich sag mal frech eine Orientierung).

Der Nachteil, den man sich damit einhandelt, wäre die Nichtaktualisierbarkeit der Abfrage. Die Aktualiserbarkeit dürfte hier aber nicht gefragt sein.

Nachtrag: Bei der Indizierung habe ich nur auf die Felder geachtet. Was aber extrem ungewöhnlich ist: Du vergibst stets den gleichen Namen für den Index. Hast Du geprüft, ob die Indizes auch wirklich bestehen, oder ob es nur einer  (der letzte) ist?
Standard bei Verwendung der Accessoberfläche wäre, dass der Einfelderindex gleich zum Feld benannt wird.
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: ebs17 am Januar 01, 2024, 19:31:11
Zitatwelche Kunden vom 18.12 - 31.12.2023 einkaufen waren und vom 02.01 - 17.12.2023 nicht
SELECT
   U.*
FROM
   umsatz9 AS U
      LEFT JOIN
         (
            SELECT
               Kunde
            FROM
               umsatz9
            WHERE
               datum BETWEEN #2023-01-02# AND #2023-12-17#
         ) AS Q
         ON U.Kunde = Q.Kunde
WHERE
   U.Art IN('A', 'Z')
      AND
   U.cluster = 'HDL'
      AND
   U.datum BETWEEN #2023-12-18# AND #2023-12-31#
      AND
   Q.Kunde IS NULL
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: Blaupunkt79 am Januar 02, 2024, 08:24:14
Guten Morgen,

die Geschwindigkeit ist wirklich beeindruckend!

Eine Beispielabfrage:

Alle Kunden der Branchen "Griechische Imbisstuben sowie Restaurants", die noch nie Obst/Gemüse gekauft haben.

SELECT U.* 
FROM  umsatz9 As U
Left Join 

SELECT  Kunde  FROM  umsatz9 
WHERE  Artikel IN (SELECT Artikel FROM [C:\Users\xxx\Desktop\BLSCC_Datenbanken\artikel.mdb].artikel9 WHERE disponent IN ('109')))
AS Q 
ON U.Kunde = Q.Kunde 
where U.Art IN ('A','Z',"")
AND U.branche IN ('GRIECHISCHE IMBISSST','GRIECHISCHE SPEZIALI')
And Q.Kunde is Null

Wie gehe ich mit Left Join um, wenn ich keine negative Abfrage habe?

Beispiel, zeige mir alle Artikel des Disponenten Obst/Gemüse an?

SELECT U.* 
FROM  umsatz9 As U 
Left Join
 ( 
SELECT  Artikel  FROM  umsatz9 
where U.Art IN ('A','Z',"")
And U.Artikel IN (SELECT Artikel FROM [C:\Users\xxx\Desktop\BLSCC_Datenbanken\artikel.mdb].artikel9
WHERE disponent IN ('109'))

Bei der Indizierung hattest Du auch recht, habe ich nun angepasst mit den Bezeichnungen.

Danke

Grüße
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: ebs17 am Januar 02, 2024, 09:41:29
ZitatWie gehe ich mit Left Join um, wenn ich keine negative Abfrage habe?
Weglassen. Nichts Tun ist am schnellsten erledigt.

Wenn Du jetzt externe Datenbanken einbindest, vermutlich weil die Gesamtdaten dadurch aufgeteilt werden (müssen?), dann solltest Du spätestens auf ein aktives DBMS umziehen, das diese Gesamtmenge alleine aufnehmen und verwalten kann. Eine hausinterne Verarbeitung durch eine schnelle Maschine wird einige Pluspunkte bringen gegenüber dem Laden von Daten aus externen Quellen und dem Datentransport über Netzwerk.
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: Blaupunkt79 am Januar 02, 2024, 09:50:33
Ok verstehe, baue ich mit ein, nun noch eine Frage, wenn ich mehrere negative Abfragen einbauen möchte, bringt er mir nicht die gewünschten Ergebnisse, habe ich " AS Q" falsch positioniert? Die Abfrage spuckt Artikel des Disponenten 105 mit aus.

Kein Kauf im Zeitraum: 21.02+23.02.2023
Keine Artikel des Disponenten: 105

Kauf im Zeitraum: 02.01-05.01.2023

SELECT U.* 
FROM  umsatz9 As U 
Left Join 

SELECT  Kunde  FROM  umsatz9 
WHERE  (datum IN (#2023-02-21#,#2023-02-23#)) 
And Artikel IN (SELECT Artikel FROM [C:\Users\xxx\Desktop\BLSCC_Datenbanken\artikel.mdb].artikel9 WHERE disponent IN ('105')) 
)
AS Q
ON U.Kunde = Q.Kunde 
where U.Art IN ('A','Z',"")
And (u.datum BETWEEN #2023-01-02# AND #2023-01-05#)
And Q.Kunde is Null

Danke

Grüße
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: ebs17 am Januar 02, 2024, 12:00:55
Wenn Du jetzt die Erwartung hast, dass ich jeden Deiner stark wechselnden Versuche kommentieren würde, wird diese Erwartung sicher enttäuscht werden.

Angenommen, ich hätte Zeit und Lust, verbleiben da immer offene Bedingungen. Du nennst einige Kriterien, in der Abfrage setzt Du aber ungefragt immer zusätzliche ein, als ob jene keine Rolle spielen könnten. Außerdem genügt nicht immer nur die Abstraktion über eine SQL-Anweisung, da SQL-Anweisungen auch konkrete Datenlagen berücksichtigen müssen und man daher auch diese irgendwann mal einschätzen und daher kennen müsste.

Also pauschal: Wenn Deine verwendete Abfragelogik ungewünschte Ergebnisse zeigt, ist sie falsch.
Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: Blaupunkt79 am Januar 02, 2024, 18:55:05
Hallo Eberhard,

sorry, wollte Dir nicht zu nahe treten, mir ist bewusst, dass Du Deine Freizeit dafür einsetzt, anderen, wie mir, zu helfen. Ich selber habe auch durch Dich große Fortschritte in Sachen Access gemacht, die Puzzleteilchen fügen sich langsam zusammen.

Viele anderen Dinge habe ich bei meinem Tool selber umgesetzt, bin aktuell noch dran, es in verschiedenen Sprachen zur Verfügung zu stellen, auch das klappt immer besser. Ich freue mich, wenn ich Dinge aufsaugen und auch umsetzen kann. Einige andere Dinge mache ich eben zum ersten Mal, wie z.b. "Left Join", dass wirkt wahrscheinlich extrem holprig, aber jeder fängt mal klein an. ;-)

Ich habe eben heute morgen Deinen Hinweis mit "Left Join" eingebaut und teste mich durch verschiedene Abfragen, um zu sehen, ob die Logik greift, daher auch Dein Eindruck, der stark wechselnden Versuche.

Was mir bei meinem aktuellem Problem noch fehlt, ist wie ich mehrere negative Abfragen einbauen kann, ich bin davon ausgegangen, dass sich dieses "AS Q" auf alle Kunden bezieht, die gefiltert werden, also folglich:

            " Left Join ( " & _
            " SELECT " & _
            " Kunde " & _
            " FROM umsatz9 " & _
            " WHERE (datum BETWEEN #2023-02-20# AND #2023-02-25#) " & _
            " And Artikel IN (SELECT Artikel FROM " & _
            "[C:\Users\xxx\Documents\BLSCC\Märkte\Würzburg\artikel.mdb].artikel9 WHERE disponent IN
            "('103')) " & _
            " )

Führe ich die negativen Abfragen einzeln aus, klappt es.

Vielleicht kannst Du mir einen Denkanstoß geben.

Danke

Grüße

Mirko


Titel: Re: Access Bearbeitungsstand bei Erzeugung der Abfragetabelle durch VBA
Beitrag von: ebs17 am Januar 02, 2024, 19:15:38
Zitat"AS Q"

Grundlagen - SQL ist leicht (2) - Alias (https://www.ms-office-forum.net/forum/showthread.php?t=298432)
Das Q ist schlicht ein Tabellenalias, da jedes Objekt, also auch die Unterabfrage als Tabelle, einen eindeutigen Namen haben muss.

ZitatFühre ich die negativen Abfragen einzeln aus, klappt es.
Wahrscheinlich ist es falsche Logik, die Bedingungen zusammenzuführen in einer Abfrage, wenn jede Bedingung für sich zu 100 Prozent wirken soll. Da braucht man dann vermutlich eine AND-Verknüpfung:

' mehrfach joinen
(umsatz LEFT JOIN sq1 ...) LEFT JOIN sq2 ON ...

' Kombi im WHERE
WHERE NOT EXISTS (sq1)
  AND NOT EXISTS (sq2)