Hallo Zusammen,
ich habe ein Problem mit den anscheinenden Limits von SQL Abfragen in Access VBA oder ich übersehe etwas.
Struktur:
Ich habe eine Tabelle Metadaten (tblMetadaten - Enthält grundsätzliche Daten zu einem Prozess) und eine Tabelle Komponenten (tblKomp - Enthält spezifische Daten zu einem Prozess (muss änderbar sein und darf öfter vorkommen)).
Beide sind mit einer 1:n Beziehung aus der tblKomp zu tblMetadaten verknüpft über RezhelpID
tblMetadaten -> *RezID | RezhelpID | ...
tblKomp -> *RezhelpID | RezID | Losgroesse | ...
Das Ziel das ich anstrebe ist einen Datensatz in beiden Tabellen zu duplizieren in Abhägigkeit vom im [tblMetadaten] ausgewählten Datensatz.
Sobald ich in der [tblMetadaten] über ein Formular einen Datensatz anlege / dupliziere wird in der [tblKomp] ebenfalls ein Datensatz angelegt mit *RezhelpID'(Auto-Inkrement) und der entsprechenden RezID aus [tblMetadaten] sowie allen anderen Spalten leer.
Nun möchte ich das die Werte der Spalten in [tblKomp] anhängig von der in [tblMetdaten] ausgewählten RezID in die entsprechende Reihe in [tblKomp] aktualisiert werden.
Beispiel:
[tblMetadten] -> *RezID = 1 | Name = Hans #duplizieren#
*RezID = 2 | Name = Hans
das funktioniert einwandfrei da ich die Bordmittel von Access nutze.
[tblKomp] -> RezID = 1 | *RezhelpID = 1 | Losgroesse = 5000
RezID = 2 | *RezhelpID = 2 | Losgroesse = 5000
Dazu habe ich den ein oder anderen Code aus dem Internet genutzt also nicht wundern falls euch das bekannt vor kommt :)
Hier der Code dazu:
Private Sub cmdDupe_Click()
On Error GoTo Fehler
Dim sichRezID As Integer
'Sichern der alten RezeptID
If Not IsNull(Me.RezID) Then
sichRezID = Me.RezID
End If
If MsgBox("Soll das Rezept " & sichRezID & " kopiert werden?", vbQuestion + vbYesNo, "Kopieren bestätigen")
= vbNo Then
Exit Sub
End If
'Markieren
DoCmd.DoMenuItem acFormBar, acEditMenu, acSelectRecord, , acMenuVer70
'Kopieren
DoCmd.DoMenuItem acFormBar, acEditMenu, acCopy, , acMenuVer70
DoEvents
'Am Ende anfügen
DoCmd.DoMenuItem acFormBar, acEditMenu, 5, 0, acMenuVer70
MsgBox "Rezepte wurde kopiert!", vbInformation, "Meldung!"
'kopierten Datensatz endgültig sichern
DoCmd.RunCommand acCmdSaveRecord
'Zum letzten Datensatz wechseln (=neu kopierter)
DoCmd.RunCommand acCmdRecordsGoToLast
An dieser Stelle kurz eingeschoben:
Ich weiß das das unglücklich ist es mit Menüeinträgen zu machen weil die änderbar sind und dann nicht mehr funktionieren aber zu Testzwecken klappt das hervorragend, damit beschäftige ich mich später noch einmal.
Nun zur Updatefunktion die mir seit 3 Wochen Kopfschmerzen bereitet:
Variante 1:
'Kopieren der Zutaten des zuvor kopierten Rezepts
Dim SQL1 As String
SQL1 = "UPDATE tblKomp SET Losgroesse = (SELECT Losgroesse FROM tblKomp" & _
"WHERE (((tblKomp.RezID)=" & sichRezID & "))) WHERE RezID = 23"
DoCmd.RunSQL SQL1
Note: "sichrezID" ist eine Variable in der die RezID aus [tblMetadaten] zwischengespeichert wird auf die sich
alles beziehen soll. Der return als Integer funktioniert und gibt immer die RezID, die im Formular, das die Daten
aus [tblMetadaten] anlegt/dupliziert aus.
Wert "23" im letzten WHERE Ausdruck soll noch ersetzt werden durch einen Returnwert der mir die RezID
des zuletzt hinzugefügten Datensatzes in der Tabelle Komp liefert und in den die Aktualisierung erfolgen
soll. Aktuell trage ich das händisch ein um so viele Fehlerquellen wie möglich aus zu schließen.
Der 1. Fehler entsteht an der Stelle ... SET Losgrosse = (SELECT ... Dieser Coder liefert immer den Fehler "3144
Syntaxerror in FROM Klausel". Nach etwas research habe ich herausgefunden das Access scheinbar nicht
damit klar kommt das in der SET Anweisung eine weitere SELECT Anweisung kommt, ist halt kein SQL Server
¯\_(ツ)_/¯.
Variante 2:
Dim var As Variant
var = "SELECT Losgroesse FROM tblKomp WHERE (((tblKomp.RezID)=" & sichRezID & "))"
SQL1 = "UPDATE tblKomp SET (((tblKomp.Losgroesse)='" & var & "')) WHERE RezID = 23"
DoCmd.RunSQL SQL1
Note: Das deklarieren von "var" funktioniert in diesem Code ausschließlich als "Variant", String, Integer
und Long liefern immer einen Typenfehler.
Dieser Code macht zwar was er soll, aber er liefert ebenfalls einen Fehler wegen Typenkonflikt:
"Microsoft Access hat 1 Felder wegen Typumwandlungsfehlern nicht aktualisiert"
Das Feld aus dem die Daten kommen und in das sie wieder sollen ist aber "Zahl - Long Integer"
Alle anderen Feldgrößentypen für "Losgroesse" funktionieren auch nicht.
Wenn ich aus Spaß das Feld auf String setzte dann schreibt er die SQL SELECT Anweisung da rein,
was sinn mach und richtig ist.
Fehlerbehandlung und Bestätigung über Messagebox das alles geklappt hat.
Hilfe?
Grüße
Razcal
@Edit: Rechtschreibfehler (Ist bestimmt noch der ein oder andere drinnen.) und Formatierung
Hallo,
hole dir den Wert per DLookUp() aus der Tabelle und baue damit den SQL-Code zusammen.
Aktualisierungsabfragen solltest du besser per "<currentdb>.execute" starten.
Lasse dir immer auch den fertig zusammengesetzen SQL-Code ausgeben.debug.print SQL1
Zitat von: steffen0815 am Dezember 08, 2020, 12:33:17Hallo,
hole dir den Wert per DLookUp() aus der Tabelle und baue damit den SQL-Code zusammen.
Aktualisierungsabfragen solltest du besser per "<currentdb>.execute" starten.
Lasse dir immer auch den fertig zusammengesetzen SQL-Code ausgeben.debug.print SQL1
Ja macht Sinn *Facepalm*
Manchmal sieht man den Baum vor lauter Wald nicht mehr oder so ähnlich :D
Ich probiere es heute Abend und gebe dann feedback + den fertig Code falls nochmal jemand so ein Problem hat.
Hallo Rascal,
ZitatJa macht Sinn
Und mit diesem kleinen Tool (http://access-codelib.net/download/addins/SqlDebugPrint.zip) (AddIn) geht das noch komfortabler.
Damit bekommst du den SQL-String nicht nur geparst angezeigt,
wie im Direktfenster, sondern er wird in einem Formular angezeigt,
mit der zusätzlichen Information ob die Abfrage korrekt ist bzw.
die bei Fehlern zur Laufzeit ausgelöste Fehlermeldung.
In dem Formular kannst du die Abfrage dann bearbeiten, in die
Datenblatt-/SQL-Ansicht wechseln, und ein paar Features für den
Einsatz hier (C&P).
gruss ekkehard