Januar 19, 2021, 07:08:18

Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!


Problem mit UPDATE Funktion in Access SQL/VBA

Begonnen von Razcal, Dezember 08, 2020, 10:51:02

⏪ vorheriges - nächstes ⏩

Razcal

Dezember 08, 2020, 10:51:02 Letzte Bearbeitung: Dezember 08, 2020, 11:03:56 von Razcal
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

steffen0815

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
Gruß Steffen

Razcal

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.

Beaker s.a.

Hallo Rascal,
ZitatJa macht Sinn
Und mit diesem kleinen Tool (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
--
Beaker s.a., der lieber an seinem eigenen Projekt arbeiten würde/sollte, aber irgendwie immer gerne seinen Senf dazu gibt ;-)
S.M.I².L.E.