Hallo
anknüpfend an meine letzte Frage habe ich jetzt das Problem, das eine per String ausgeführte Abfrage in VBA die Tabelle nicht erstellt, weil sie schon vorhanden ist. Füge ich den String in SQL in Acccess in eine Abfrage ein und führe die Abfrage mit DoCmd aus, wird die Tabelle problemlos erstellt bzw. vorher gelöscht und dann erstellt. Mir ist nicht klar, warum das mit dem String nicht geht. Im String will ich das Verzeichnis ändern können. Mein String lautet:
SELECT LadeVorgängeSBG.[Charging Station ID], LadeVorgängeSBG.Serial, LadeVorgängeSBG.[RFID Card], LadeVorgängeSBG.Status, LadeVorgängeSBG.Start, LadeVorgängeSBG.End, LadeVorgängeSBG.[Meter at start (Wh)], LadeVorgängeSBG.[Meter at end (Wh)] INTO LadeVorgängeSBG IN 'Z:\Access Tabellen\eMobility, Schlüssel, Stapler 2022 Tabellen.accdb' FROM LadeVorgängeSBG WHERE (((LadeVorgängeSBG.[Charging Station ID])=2));
Private Sub Übergabe_Click()
Dim Übergabe As String
Dim Verzeichnis As String
Dim Test As String
Verzeichnis = DLookup("[VerzeichnisTabellen]", "Stammdaten", "[ID]=1")
'Debug.Print Verzeichnis
Übergabe = "SELECT LadeVorgängeSBG.[Charging Station ID], LadeVorgängeSBG.Serial, LadeVorgängeSBG.[RFID Card], LadeVorgängeSBG.Status, LadeVorgängeSBG.Start, LadeVorgängeSBG.End, " _
& "LadeVorgängeSBG.[Meter at start (Wh)], LadeVorgängeSBG.[Meter at end (Wh)] INTO LadeVorgängeSBG IN '" & Verzeichnis & "' " _
& "FROM LadeVorgängeSBG " _
& "WHERE (((LadeVorgängeSBG.[Charging Station ID])=2));"
'Debug.Print Übergabe
DoCmd.SetWarnings False
'CurrentDb.Execute Übergabe, dbFailOnError 'Fehlermeldung: Datei bereits vorhanden
'CurrentDb.Execute "Abfrage1" 'Fehlermeldung: Datei bereits vorhanden
DoCmd.OpenQuery "Abfrage1" 'keine Fehlermeldung, Datei wird neu erstellt
DoCmd.SetWarnings True
End Sub
Gibt es dafür eine Erklärung? Wann muss ich Execute verwenden und wann DoCmd? Ich verwende Access 20219.
LG Friedrich
Verkürzte Antwort: DoCmd.OpenQuery ist Abfrageausführung für Dummies. Sie macht noch etwas mehr als "nur" die Abfrage ausführen. Hier wird eine gespeicherte Abfrage benötigt.
ZitatFehlermeldung: Datei bereits vorhanden
Für Nichtdummies: Dass man nicht zwei Objekte gleichen Namens haben kann, sollte jedem mit eingeschaltetem Denken bewusst sein, da sollte man also erst prüfen und dann ausführen.
Die Execute-Methode kann mit gespeicherter Abfrage als auch mit SQL-String anwenden. Sie nervt nicht mit überflüssigen Meldungen, sondern gibt bei Verwendung von dbfailOnError Fehler zurück und führt bei Fehler ein Rollback aus (alles zurück auf Anfang).
Hallo,
ZitatWann muss ich Execute verwenden und wann DoCmd?
Alle Aktionsabfragen (Lösch, Anfüge, Aktualisierungs und Tabellenerstellungsabfragen) werden mit Execute ausgeführt. DoCmd braucht man für Abfragen eher nicht. Auch OpenQuery (für Auswahlabfragen) wird im Regelfall nicht benötigt, da diese Abfragen meist im Zusammenhang mit Formularen und Berichten als Datenquelle dienen und nicht direkt geöffnet werden.
Wenn Du in dem jetzigen Code die Zeile mit "DoCmd.SetWarnings False" entfernst, wirst Du auch mit OpenQuery eine Meldung erhalten. Mit False schaltest Du ja die Meldung direkt ab. Bei Execute werden mit DbFailOnError die Meldung bewusst erzeugt, denn es ist ja sinnvoll eine Tabelle nicht einfach kommentarlos zu löschen.
Private Sub Übergabe_Click()
Dim Übergabe As String, Verzeichnis As String
Verzeichnis = DLookup("[VerzeichnisTabellen]", "Stammdaten", "[ID]=1")
Übergabe = "SELECT [Charging Station ID], Serial, [RFID Card], Status, Start, End, " _
& "[Meter at start (Wh)], [Meter at end (Wh)] INTO LadeVorgängeSBG IN '" & Verzeichnis & "' " _
& "FROM LadeVorgängeSBG " _
& "WHERE [Charging Station ID]=2"
CurrentDb.Execute Übergabe, dbFailOnError 'Fehlermeldung: Datei bereits vorhanden
End SubDer Code ist von überflüssigem Text und Klammern befreit.
Wenn es die Tabelle schon gibt, muss diese vorher mit
DoCmd.DeleteObject acTable, "Tabellenname"gelöscht werden.
Es stellt sich aber eher noch andere Fragen:
Wieso musst Du Tabellen erstellen und löschen und das auch noch in unterschiedlichen Verzeichnissen ?
Eine Datenbank hat im Regelfall mehrere Tabellen, die alle in einem Verzeichnis liegen.
Das Vorhaben scheint mir in dieser Art fragwürdig zu sein.
Kannst Du das mal erklären ?
Es handelt sich um 2 e-Ladestationen, 1x Firma 1x zu Hause (Extern). Bei zu Hause wird der Ladestrom für den Firmen-PKW von der Firma bezalt, für andere Autos nicht. In der Firma werden beide Ladestationen zusammengeführt und dann abgerechnet. Das Zusammenführen passiert in der Weise, dass alle Datensätze der externen Station, die ein größeres Startdatum haben als das bereits für diese Ladestation übernommene, mit einer Anfügeabfrage übernommen werden. Dazu ist es notwendig, die Datei vom externen Laptop in die Anwendung auf dem Rechner zu bekommen. Mit einer gespeicherten Tabellenerstellungsabfrage und den ausgeschalteten Warnungen funktioniert das auch tadellos. Es muss nebenbei so einfach sein, dass ein Mitarbeiter ohne Access-Kenntnisse durch Betätigen der Befehlsschaltfläche dieses Übertragen durchführen kann.
Mit dem Erstellen der externen Tabelle im Hauptrechner mit einer gespeicherten Abfrage wird auch gleich das Löschen der alten Datei erledigt ohne dass irgendwelche Meldungen kommen, die zur Verunsicherung des Bedieners führen.
Ich dachte da eben, dass die Abfrage als String mit Execute die gleiche Wirkung hat, wie eine gespeicherte Abfrage, ohne die Tabelle vorher extra löschen zu müssen.
Übrigens könnte die Tabelle im PC auch einen anderen Namen haben. Das Problem ist, dass sie vorher gelöscht werden muss, da sie von eine früheren Übertragung schon existiert.
Sowohl im PC als auch im Laptop sind die Access Anwendungen in Backend und Frontend aufgeteilt.
Die Warnmeldungen habe ich ganz bewusst ausgeschaltet. Die Frage bleibt bestehen, wie ich vom Laptop aus die Datei im PC löschen kann?
Noch eleganter wäre es, wenn ich am Laptop mit DMax("[Start]","Tabelle im PC") das letzte Übertragungsdatum ermitteln könnte und nur die neuen Datensätze anfüge. Da fehlen mir aber die Kenntnisse.
Jedenfalls Danke an alle Beiden für die Lösungsansätze. Ich hoffe ich habe mein Vorhaben ausführlich beschrieben - sonst bitte nachfragen. Vielleicht gibt es für die elegantere Lösung auch noch eine Idee.
LG Friedrich
Zitat von: risingstar am Mai 07, 2023, 14:01:43Noch eleganter wäre es, wenn ich am Laptop mit DMax("[Start]","Tabelle im PC") das letzte Übertragungsdatum ermitteln könnte und nur die neuen Datensätze anfüge.
Das sollte ja kein Problem sein.
Einfach statt Select Into auf ein Insert Into umstellen und bei der Bedignung dann:
WHERE [Charging Station ID]=2 and Start > (SELECT MAX(Start) FROM LadeVorgängeSBG IN '" & Verzeichnis & "')
Außerdem kannst du dann in der Tabelle LadeVorgängeSBG auch Primärschlüssel und Indizes verwenden, was du so ja nicht machst.
LG Markus
Edit:
Übrigens hat OpenQuery den Vorteil, dass man bei Aktionsabfragen Parameter so wie üblich in Formularen verwenden kann und diese nicht per Parameter Auflistung hinzufügen muss. Ist eine Geschmacksfrage. Ich verwende es nicht.
Um mal ganz vorne anzufangen und um vor Codes über einen Ablauf nachzudenken:
ZitatDazu ist es notwendig, die Datei vom externen Laptop in die Anwendung auf dem Rechner zu bekommen.
Was genau und wie erfolgt das?
Einen wunderschönen guten Morgen,
@ Markus: Mit der Unterabfrage hast Du ins Schwarze getroffen. Die Lösung funktioniert prima. Vielen Dank. Ich verwende in der Tabelle LadevorgängeSBG durchaus einen Primärschlüssel und zwar einen Autowert für die Ladevorgänge, nur brauche ich diesen nicht auf den PC übernehmen, da dort ebenfalls ein Autowert als Primärschlüssel eingerichtet ist.
@ Eberhard: Also ich habe 2 e-Ladestationen. Eine wird auf den Firmen PC ausgelesen und die andere zu Hause auf einen Laptop. Somit habe ich 2 Acess Anwendungen. Die Daten des Laptops müssen jetzt auf den PC übertragen werden um abgerechnet zu werden. Bei der Lösung von Markus wird mittels eines Strings, der eine Unterabfrage beinhaltet, jene Datensätze vom Laptop auf den PC übernommen, deren Datum größer ist, als das letzte übernomme Datum auf dem PC. Diese letzte Datum auf dem PC wird mit der Unterabfrage abgefragt.
Zur Info nochmal der String mit der Unterabfrage, wobei Verzeichnis der Pfad der Access-Tabellen auf dem PC ist:
Übergabe = "INSERT INTO LadeVorgänge ( [Charging Station ID], Serial, [RFID Card], Status, Start, [End], [Meter at start (Wh)], [Meter at end (Wh)] ) IN '" & Verzeichnis & "' " _
& "SELECT LadeVorgängeSBG.[Charging Station ID], LadeVorgängeSBG.Serial, LadeVorgängeSBG.[RFID Card], LadeVorgängeSBG.Status, LadeVorgängeSBG.Start, LadeVorgängeSBG.End, " _
& "LadeVorgängeSBG.[Meter at start (Wh)], LadeVorgängeSBG.[Meter at end (Wh)] " _
& "FROM LadeVorgängeSBG " _
& "WHERE (((LadeVorgängeSBG.Start)>(SELECT Max([Start]) AS StartPC " _
& "FROM LadeVorgänge IN '" & Verzeichnis & "'" _
& "WHERE (((LadeVorgänge.[Charging Station ID])=2)))));"
LG Friedrich
Die beiden Rechner sind also per Netzwerk verbunden, womit die Datenbanken direkt miteinander kommunizieren können.
ZitatDie beiden Rechner sind also per Netzwerk verbunden, womit die Datenbanken direkt miteinander kommunizieren können.
ja, der Laptop verbindet sich über WLAN mit dem Netzwerk, wenn der Mitarbeiter in der Fa. ist und dann werden die Daten angefügt, bzw. die Datei übertragen. Sonst liest er die e-Ladestation zu Hause aus, ohne im Firmennetzwerk zu hängen.