Fragensteller
Laufzeitfehler 3078 ... obwohl Tabelle gerade erzeugt!

Frage
-
Hallo zusammen,
ich führe in einer Datenbank aufgrund von Benutzereingaben in einem Formular den SQL-Code von Auswahlabfragen aus, deren Ergebnisse ich in zur Laufzeit mit SELECT INTO in benutzerpersonalisierte, temporäre Tabellen schreibe und dem Benutzer anzeige. Der kann die die Daten dann exportieren, kopieren oder einfach nur anschauen. Nach Schließen der Form werden die Tabellen gelöscht.
Das läuft seit Jahren einwandfrei. Im neuen Release der DB, das ich grade erstelle, tritt aber jetzt der Laufzeitfehler 3078 auf - am Code der Funktion habe ich nichts geändert -, dass die gerade erzeugte Tabelle nicht gefunden werde. Wenn ich im Debugger dann aber die F8 oder F5-Taste betätige, läuft der Code dann ohne Mucken durch. Ich habe dann nach dem SELECT INTO-Teil ein TableDefs.Refresh eingebaut - ohne Nutzen. Kennt jemand das Problem oder noch besser: eine Lösung? Nachstehend der Code, an der kursiv dargestellten Zeile bleibt er dann hängen:
Dim sttmpTable, stSQL As String Dim db As DAO.Database Set db = DBEngine(0)(0) sttmpTable = "tmp_tbl_" & GetUserName & "_" & Hour(Time) & Minute(Time) & Second(Time) Select Case Me.ctrlAktiva.Tag Case "IFRS" If tableExists("tblErgebnispositionen_IFRS_mit_Sachkonten") Then db.Execute "SELECT t1.*,t3.Zugeordnete_Position As [Geht in]," & _ "t2.[HGB-WinKons-Pos 1] As HGB_BilGuV_Pos1,t2.BEWGP As Kontobereich INTO " & sttmpTable & _ " FROM (tblErgebnispositionen_IFRS_mit_Sachkonten As t1 " & _ "INNER JOIN Sachkonten As t2 ON t1.Kontonummer = t2.SAKNR) " & _ "INNER JOIN tblIFRS_Ergebnispositionsplan As t3 ON t1.Ergebnisposition = t3.PosNr " & _ "WHERE t1.Positionsart <> 'Alternative Kontonummer' And t1.Ergebnisposition = '" & Me.cboIsPosition & "'" db.Execute "INSERT INTO " & sttmpTable & _ " SELECT t1.*,t3.Zugeordnete_Position As [Geht in], " & _ "t2.[HGB-WinKons-Pos 1] As HGB_BilGuV_Pos1,t2.BEWGP As Kontobereich " & _ " FROM (tblErgebnispositionen_IFRS_mit_Sachkonten As t1 " & _ "INNER JOIN Sachkonten As t2 ON t1.Kontonummer = t2.[KtoNr IASD]) " & _ "INNER JOIN tblIFRS_Ergebnispositionsplan As t3 ON t1.Ergebnisposition = t3.PosNr " & _ "WHERE t1.Positionsart <> 'Alternative Kontonummer' And t1.Ergebnisposition = '" & Me.cboIsPosition & "' AND t1.Kontonummer LIKE '91' & '*'" If DCount("*", sttmpTable) > 0 Then DoCmd.OpenTable sttmpTable Else MsgBox "Keine Sachkonten für " & Me.cboIsPosition & " gefunden!" End If Me.cmdClearFind_IsPosition.Enabled = True Else MsgBox "Fehler: Datenquelle nicht vorhanden!" End If
Bin gespannt!
Gruß
Michael
Alle Antworten
-
Hallo,
Wenn der Code ohne Murren nach F8 oder F5 weiterläuft, wäre mein erster Gedanke /decompile.
Gruss - Peter
Mitglied im www.dbdev.org
Access-FAQ: www.donkarl.com
Access in Docs: https://docs.microsoft.com/en-us/office/vba/api/overview/access/?WT.mc_id=M365-MVP-10319- Bearbeitet Peter DoeringMVP, Moderator Montag, 11. November 2019 12:50
-
Hallo!
Das beschriebene Verhalten hatte ich bisher noch nicht gesehen, es könnte aber eventuell mit dem Caching der DBEngine zusammenhängen.
Zum Ausprobieren:
DBEngine.Idle dbRefreshCache
nach den Execute-Anweisungen schreiben.
Gruß
JosefCode-Bibliothek für Access-Entwickler
AccUnit - Testen von Access-Anwendungen
Virtueller Access-Stammtisch -
Hallo Peter,
das war auch mein erster, zweiter und dritter Gedanke und Tun. Ergebnis ist bekannt.
Das Merkwürdige ist eben auch, dass ich im gleichen Modul eine weitere Sub habe, die auch eine SELECT INTO mit anschließendem If DCount ... ausführt (allerdings den Part in eine eigene Function ausgelagert), bei der das einwandfrei klappt.
Ich habe allmählich den Verdacht, dass die DB einen Knacks hat, um's unprofessionell zu sagen.
Gruß
Michael
-
@Josef und Tom Krist der zweite,
im Rahmen meiner weiteren Analyse habe ich erkannt, dass für die Gesamtfunktionalität doch mehr Sinn macht, mit einer bestehenden Tabelle, die mit INSERT INTO befüllt und danach in sttmpTable umkopiert wird, zu arbeiten, weil es einen Use Case gibt, bei dem ich mit dem Neuanlegen einer Tabelle nur hinkomme, wenn ich dafür eine eigene Programmierung mache. Mein Ziel war aber, einen Code für alle Fälle zu schreiben.
Aber die Tipps habe ich mir aufgeschrieben, nicht auszuschließen, dass ich an anderer Stelle die mal einsetzen kann.
Also danke für's Dazulernen lassen.
Gruß
Michael
-
im Rahmen meiner weiteren Analyse habe ich erkannt, dass für die Gesamtfunktionalität doch mehr Sinn macht, mit einer bestehenden Tabelle, die mit INSERT INTO befüllt und danach in sttmpTable umkopiert wird, zu arbeiten, weil es einen Use Case gibt, bei dem ich mit dem Neuanlegen einer Tabelle nur hinkomme, wenn ich dafür eine eigene Programmierung mache. Mein Ziel war aber, einen Code für alle Fälle zu schreiben.
Klingt für mich, als ob nicht der Laufzeitfehler dein Problem ist (deshalb mein Hinweis auf /decompile), sondern der Umstand, dass das Database-Objekt die neue Tabelle nicht kennt. Letzteres lässt sich dadurch beheben, dass zwischen SELECT … INTO und INSERT INTO … ein Refresh auf die Collection erfolgen muss:
db.Execute "SELECT … INTO …" db.TableDefs.Refresh db.Execute "INSERT INTO …"
Gruss - Peter
Mitglied im www.dbdev.org
Access-FAQ: www.donkarl.com- Bearbeitet Peter DoeringMVP, Moderator Mittwoch, 20. November 2019 12:17
-
Hatte ich mir auch überlegt und eingebaut, allerdings nach dem INSERT. Blieb aber ohne den erhofften Effekt.
In einer anderen Prozedur hatte ich den gleichen Laufzeitfehler quasi mit umgekehrtem Vorzeichen: ich lösche eine Tabelle mit
Do.Cmd.DeleteObject "Tabellenname"
um sie gleich darauf mit
SELECT ... INTO Tabellenname
wieder zu erzeugen. Laufzeitfehler mit Meldung "Tabellenname ist schon vorhanden"
Interessanterweise kam es nicht mehr zum Laufzeitfehler , nachdem ich die Löschung mit SQL-DDL durchführe:
db.Execute "DROP TABLE Tabellenname"
Und zu allem Überfluss funktionieren in den momentan noch produktiven Version die alten Befehle noch einwandfrei!
Gruß Michael
-
Hallo,
Hatte ich mir auch überlegt und eingebaut, allerdings nach dem INSERT. Blieb aber ohne den erhofften Effekt.
Weil es nach dem Erstellen der Tabelle gemacht werden muss. Beim INSERT greifst du bereits auf die Tabelle zu, die in der TableDefs-Collection deines referenzierten db-Objekts noch fehlt! NACH dem Refresh hätte der INSERT funktioniert.
In einer anderen Prozedur hatte ich den gleichen Laufzeitfehler quasi mit umgekehrtem Vorzeichen: ich lösche eine Tabelle mit
Do.Cmd.DeleteObject "Tabellenname"
um sie gleich darauf mit
SELECT ... INTO Tabellenname
wieder zu erzeugen. Laufzeitfehler mit Meldung "Tabellenname ist schon vorhanden"
Das liegt daran, dass DoCmd (nicht Do.Cmd) den Makrointerpreter aufruft, der sein eigenes DB-Objekt erstellt. Deines (db.) weiß nichts davon, was DoCmd gemacht hat, d.h. du musst auch da vor deiner nächsten Aktion den db.TableDefs.Refresh einfügen, damit es von der Löschung erfährt.
Interessanterweise kam es nicht mehr zum Laufzeitfehler , nachdem ich die Löschung mit SQL-DDL durchführe:
db.Execute "DROP TABLE Tabellenname"
Genau, denn das findet innerhalb deines db-Objekts statt.
Gruss - Peter
Mitglied im www.dbdev.org
Access-FAQ: www.donkarl.com- Bearbeitet Peter DoeringMVP, Moderator Donnerstag, 21. November 2019 09:20