Neuigkeiten:

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

Mobiles Hauptmenü

Aktualisierungsabfrage über Kombinationsfeld bringt Fehler 2482

Begonnen von KonradR, Mai 14, 2023, 09:23:17

⏪ vorheriges - nächstes ⏩

KonradR

Hallo liebe Accessfreunde,

ich habe ein Kombinationsfeld auf einem Unterformular. Wenn ich eine bestimmte Aktion ausführe, möchte ich, dass der Inhalt des Kombinationsfeldes den Inhalt des im Unterformular gezeigten Datensatzes der verknüpften Tabelle aktualisiert. Das Ganze habe ich versucht mit einer Aktualisierungsabfrage in Kombination mit VBA zu lösen. Leider kommt dann der Fehlercode 2482 "Microsoft Access kann den eingegebenen Namen 'Mandelmilch' nicht finden". "Mandelmilch" steht in dem Fall aber im Kombinationsfeld des Unterformulars. Wie kann das sein? Ich habe extra die Funktion Eval() genutzt, weil DAO direkt auf JET zugreift und daher den Bezug auf Access-Objekte im SQL-Text nicht versteht.
Seht ihr da eine Möglichkeit, wie ich eine Aktualisierungsabfrage aufgrund des Inhalts des Kombinationsfeldes machen kann? Hier mein Code:

Public Function ZutatAendern()
    Dim dbZutat As DAO.Database
    Dim cboZutatText As String
    Dim cboZutatWert As Long
    Dim strSQL As String

    Set dbZutat = CurrentDb
    cboZutatText = Eval(Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Text)
    cboZutatWert = Eval(Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Value)

    strSQL = "UPDATE tblZutaten SET ZutatName =" & cboZutatText
    strSQL = strSQL & " WHERE ZutatID =" & cboZutatWert

    dbZutat.Execute strSQL, dbFailOnError
End Function
  •  

PhilS

Ich sehe bei deinem Ansinnen und dessen Umsetzung 3 Probleme.

1.)
Als erstes das Problem, das deine Fehlermeldung verursacht.
Du musst Textliteral in SQL-Satements in Begrenzer einschließen:
    strSQL = "UPDATE tblZutaten SET ZutatName ='" & cboZutatText & "'"
    strSQL = strSQL & " WHERE ZutatID =" & cboZutatWert
(Sieh dir dazu mal mein VBA+SQL-Tutorial an!)

2.)
Die .Text-Eigenschaft von Text- und Comboboxen ist nur verfügbar, während das Steuerelement den Focus hat. In anderen Situationen musst du die .Column-Property verwenden und die korrekte (angezeigte) Spalte referenzieren.

3.)
Das ganze Unterfangen erscheint fragwürdig. Nur die ZutatId zu speichern, ohne den Text ist in einer Datenbank der bessere Weg. Du kannst den ZutatName jederzeit über eine Abfrage hinzuholen. Wenn der ZutatName in mehreren Tabellen gespeichert wird, ist das ersten unnötig und zweitens besteht die Gefahr widersprüchliche Namen zu derselben Id zu speichern.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor
  •  

KonradR

Hallo PhilS,

Zitat von: PhilS am Mai 14, 2023, 10:56:461.)
Als erstes das Problem, das deine Fehlermeldung verursacht.
Du musst Textliteral in SQL-Satements in Begrenzer einschließen:

Danke für den Tip und dein Video. Das war sehr hilfreich. Jetzt habe ich auch die Benutzung von den Anführungszeichen verstanden. Jetzt sieht das Ganze bei mir so aus (Ich habe auch noch die Eval()-Funktion weggenommen):

   
Public Function ZutatAendern()
    Dim dbZutat As DAO.Database
    Dim cboZutatText As String
    Dim cboZutatWert As Long
    Dim strSQL As String
   
    Set dbZutat = CurrentDb
   
    cboZutatText = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Text
    cboZutatWert = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Value
   

    strSQL = "UPDATE tblZutaten SET ZutatName = '" & cboZutatText & "'"
    strSQL = strSQL & " WHERE ZutatID = '" & cboZutatWert & "'"
   
    MsgBox "cboZutatText: " & cboZutatText & " / Datentyp: " & VarType(cboZutatText) & vbCrLf & _
           "cboZutatWert: " & cboZutatWert & " / Datentyp: " & VarType(cboZutatWert) & vbCrLf & _
           "strsQL: " & strSQL & " / Datentyp: " & VarType(strSQL)

    dbZutat.Execute strSQL, dbFailOnError
End Function

Zitat von: PhilS am Mai 14, 2023, 10:56:462.)
Die .Text-Eigenschaft von Text- und Comboboxen ist nur verfügbar, während das Steuerelement den Focus hat. In anderen Situationen musst du die .Column-Property verwenden und die korrekt (angezeigte) Spalte referenzieren.

In dieser Situation benötige ich aber die Text-Eigenschaft, weil es bei der Column-Property einen Fehler gibt, weil der Wert in der referenzierten Tabelle NULL ist, da es den eingegebenen Wert noch nicht gibt. Es soll allerdings ein bestehender Wert geändert werden und daher will ich das nehmen, was ich gerade in das Kombinationsfeld hineinschreibe.

Zitat von: PhilS am Mai 14, 2023, 10:56:46Wenn der ZutatName in mehreren Tabellen gespeichert wird, ist das ersten unnötig und zweitens besteht die Gefahr widersprüchliche Namen zu derselben Id zu speichern.

Ich speichere den ZutatName ja nur in einer Tabelle und habe referentielle Integrität festgelegt. Das Ganze mache ich ja, weil es bei der Eingabe von Zutaten im Unterformular manchmal dazu kommt, dass ich den ZutatName falsch schreibe und das erste bemerke, wenn die Bearbeitung schon zu ende ist. Dann müsste ich rein formell noch mal in die referenzierte Tabelle und die Daten da ändern. Genau dass möchte ich halt schnell und bequem über das Unterformular lösen.

Jetzt habe ich allerdings die gleich Fehlermeldung wie zu Beginn. Nun habe ich am Code noch ein paar Veränderungen gemacht und bekomme nun die Fehlermeldung: "Laufzeitfehler 3464: Datentypkonflikt in Kriterienausdruck". Das verstehe ich nicht, denn ich habe über die Funktion vartyp den String strSQL und die Variablen cboZutatText und cboZutatWert geprüft. Der String strSQL und die Variable cboZutatText haben den Datentyp String ("8") und die Variable cboZutatWert hat den Datentyp Long Integer (3). Von den Datentypen her dürfte es doch stimmen?
  •  

MzKlMu

#3
Hallo,
ich glaube Du programmierst hier Sachen, die man nicht braucht. Wenn das Kombi zur Zutatauswahl gebunden ist, wird keine Aktualisierungsabfrage benötigt.
Zitatmanchmal dazu kommt, dass ich den ZutatName falsch schreibe
Wenn über ein Kombi gewählt wird, kann man doch keinen Namen falsch eingeben, es gibt ja nur Zutaten im Kombi die es auch gibt. Falsch schreiben geht doch gar nicht. Für eine neue Zutat ist dann das Ereignis
Du verwechselst da auch was mit Text und Value.
Die Eigenschaft Text hat mit dem Klartext nichts zu tun. In der Eigenschaft Text steht der Wert vor Aktualisierung des Feldes. Wenn das Feld verlassen wird, wird aus .Text . Value, Text und Value haben dann den gleichen Wert, nämlich cboeinkaZutatIDRef und das ist der Fremdschlüssel als Zahl.
Den Namen der Zutat noch zu speichern ist überflüssig. Wenn die Tabellen richtig aufgebaut sind, ist es ohnehin nicht möglich neben der Zahl (Fremdschlüssel) auch noch den Text zu speichern.

Und bei der Gelegenheit noch der Hinweis, dass in den Tabellen keine Nachschlagefelder angelegt werden sollten. Wenn Du welche hast, solltest Du diese wieder in normale Eingabefelder (Textfeld) ändern.
Gruß
Klaus
  •  

KonradR

#4
Hallo MzKlMu,

Zitat von: MzKlMu am Mai 15, 2023, 00:05:54Ich glaube Du programmierst hier Sachen, die man nicht braucht. Wenn das Kombi zur Zutatauswahl gebunden ist, wird keine Aktualisierungsabfrage benötigt.
Aus der Sicht, dass ich ein Kombinationsfeld ausschließlich zum Auswählen der in der Liste befindlichen Werte nutze, sehe ich das genauso. Nun habe ich das so gelöst, dass ich über die Eingabe im Textteil des Kombinationsfeldes auch neue Datensätze der verknüpften Tabelle hinzufügen kann. Dann kann ich mich schon verschreiben und dann macht, meiner Meinung nach, eine Korrekturmöglichkeit Sinn.

Zitat von: MzKlMu am Mai 15, 2023, 00:05:54Du verwechselst da auch was mit Text und Value.
Die Eigenschaft Text hat mit dem Klartext nichts zu tun. In der Eigenschaft Text steht der Wert vor Aktualisierung des Feldes. Wenn das Feld verlassen wird, wird aus .Text . Value, Text und Value haben dann den gleichen Wert, nämlich cboeinkaZutatIDRef und das ist der Fremdschlüssel als Zahl.
Das die Eigenschaft .Text und die Eigenschaft .Value zwei unterschiedliche Sachen sind, ist mir bewusst. Daher nutze ich ja den Wert der Text-Eigenschaft um den Wert der Value-Eigenschaft zu verändern. Wenn ich ins Kombinationsfeld z.B. Mandelmilchh schreibe, ich aber nur Mandelmilch haben will, dann ist es doch sinnvoll, genau den Wert mit dieser ZutatID auch zu verändern. Dann ist Mandelmilchh der Wert der Value-Eigenschaft und Mandelmilch der Wert der Text-Eigenschaft. Eine andere sinnvolle Lösung sehe ich nicht. Wenn ich dann einen neuen Datensatz für die Zutat anlege, muss ich die bereits verwendeten austauschen (weil ich das vorher vielleicht nicht bemerkt habe) und ich habe dann viele unbenutzte Datensätze in meiner Tabelle. Das finde ich unpraktisch und verwirrend.

Zitat von: MzKlMu am Mai 15, 2023, 00:05:54Und bei der Gelegenheit noch der Hinweis, dass in den Tabellen keine Nachschlagefelder angelegt werden sollten. Wenn Du welche hast, solltest Du diese wieder in normale Eingabefelder (Textfeld) ändern.
Verletze ich dann nicht die 2. Normalform beim erstellen von relationellen Datenbanken, die sich auf die Redundanz der Daten bezieht und aussagt, dass ich Felder bzw. Daten, die ich nachlagen kann auch nachschlagen muss?

Jetzt habe ich zumindestens das Aktualisieren hinbekommen, weil ich die Position bei den Anführungszeichen für die Variable cboZutatWert verändert habe. Allerdings wird jetzt, neben der Aktualisierung des Datensatzes zusätzlich ein neuer Datensatz angelegt. Wie kann ich das verhindern? Habt ihr da eine Idee. Hier mein neuer Code:
Public Function ZutatAendern()
    Dim dbZutat As DAO.Database
    Dim cboZutatText As String
    Dim cboZutatWert As Long
    Dim strSQL As String
   
    Set dbZutat = CurrentDb
   
    cboZutatText = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Text
    cboZutatWert = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Value
   

    strSQL = "UPDATE tblZutaten SET ZutatName = '" & cboZutatText & "'"
    strSQL = strSQL & " WHERE ZutatID = " & cboZutatWert

    dbZutat.Execute strSQL, dbFailOnError
End Function
  •  

MzKlMu

#5
Hallo,
mein lieber Mann, hier bringst Du aber wirklich einiges durcheinander. Die Eigenschaft .Text ist nicht der Text "Mandelmilch" sondern das ist der gleiche Wert wie .Value.
ZitatDas die Eigenschaft .Text und die Eigenschaft .Value zwei unterschiedliche Sachen sind, ist mir bewusst.
Das sind keine unterschiedlichen Sachen, habe ich auch nicht geschrieben .Text ist der Wert vor Aktualisierung und .Value der Wert nach Aktualisierung, mit dem Klartext hat .Text absolut nichts zu tun.
Zeige mal mit 2 MsgBox die Werte an:
cboZutatText = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Text
cboZutatWert = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Value
MsgBox cboZutatText
MsgBox cboZutatWert
Da wird jeweils der gleiche Wert gezeigt, nämlich die Zahl.
Um auf den Text zuzugreifen muss die Eigenschaft Column(x) verwendet werden. Wenn das bei Dir nicht geht, hast Du was falsch gemacht. Bei Column beginnt die Spaltenzählung bei 0, 1 ist dann die 2.Spalte der Klartext.

Zitatdass ich über die Eingabe im Textteil des Kombinationsfeldes auch neue Datensätze der verknüpften Tabelle hinzufügen kann.
Für neue Einträge nutzt man das Ereignis "Bei nicht in Liste", da öffnet man ein Formular und trägt den neuen Text ein. Das lässt sich auch beliebig ändern bei einem Tipfehler.

Siehe hierzu:

Nicht in Liste

Zitatdass ich Felder bzw. Daten, die ich nachlagen kann auch nachschlagen muss?
Du sollst ja die Nachschlagefelder nur in Tabellen nicht verwenden. Auf Formularen (und nur dort) kann man und sollte die man natürlich einsetzen.

Siehe hierzu:

https://www.ms-office-forum.net/forum/showpost.php?p=2081877&postcount=2
Gruß
Klaus
  •  

KonradR

Hallo MzKlMu,

Zitat von: MzKlMu am Mai 15, 2023, 10:53:06Zeige mal mit 2 MsgBox die Werte an:
Hier mein Code für die MSG BOX:
    cboZutatText = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Text
    cboZutatWert = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Value

    MsgBox cboZutatText & " " & cboZutatWert

Und hier das Ergebnis:
Sie dürfen in diesem Board keine Dateianhänge sehen.

Zitat von: MzKlMu am Mai 15, 2023, 10:53:06Um auf den Text zuzugreifen muss die Eigenschaft Column(x) verwendet werden. Wenn das bei Dir nicht geht, hast Du was falsch gemacht. Bei Column beginnt die Spaltenzählung bei 0, 1 ist dann die 2.Spalte der Klartext.
Dann sehe ich ja den Klartext der in der Tabelle drin steht. Den möchte ich aber verändern. Dann ist es doch sinnvoll das zu nehmen, was ich an Text gerade in das Kombinationsfeld schreibe, wenn ich nicht ein zusätzliches Formular zur Bearbeitung aufrufen bzw. erstellen und die Bearbeitung gleich im Kombinationsfeld erledigen möchte. Siehst du da, ohne ein zusätzliches Formular zu erstellen bzw. aufzurufen eine andere Möglichkeit?
  •  

MzKlMu

#7
Hallo,
Du hast es immer noch nicht verstanden. Ich glaube, Du bist Dir über die genaue Funktionsweise eines Kombis nicht im Klaren.

So wie Du das machst, versuchst Du den Text "Mandelmilch" in das Fremdschlüsselfeld (Zahl) zu schreiben, was natürlich zu einem Fehler führt.
Um es noch mal deutlich zu sagen:
Die Eigenschaft .Text hat mit dem Klartext nichts, absolut nichts zu tun. .Text und .Value haben nach Aktualisierung genau den gleichen Wert. Beide beziehen sich auf die gebundene Spalte des Kombis.

Lade ein Beispiel hier hoch.

PS:
Bitte lies meinen Beitrag #5 noch mal, ich habe och einiges nachgetragen.



Gruß
Klaus
  •  

KonradR

Hallo MzKlMu,

Zitat von: MzKlMu am Mai 15, 2023, 11:45:37So wie Du das machst, versuchst Du den Text "Mandelmilch" in das Fremdschlüsselfeld (Zahl) zu schreiebn, was natürlich zu einem Fehler führt.
Klar, das führt zu einem Fehler. Aber das mache ich ja auch nicht. Ich schreibe den Text "Mandelmilch" in das Feld "ZutatName" der verknüpften Tabelle und das hat den Datentyp String. Aus meiner SQL-Anweisung geht ja auch hervor, dass ich hier eine klare Abgrenzung mache:
    strSQL = "UPDATE tblZutaten SET ZutatName = '" & cboZutatText & "'"
    strSQL = strSQL & " WHERE ZutatID = " & cboZutatWert

Das Beispiel habe ich hochgeladen:
Sie dürfen in diesem Board keine Dateianhänge sehen.
  •  

MzKlMu

#9
Hallo,
es wäre sinnvoll, wenn Du jetzt noch erklärst um welches Formular es geht. Und beschreibe Dein Vorgehen schrittweise.

Es wäre auch nicht notwendig gewesen die ganze DB hier hochzuladen. Ein Ausschnit mit dem Problem hätte genügt.

Ich sehe mir das an, aber erst heute gegen Abend.
Gruß
Klaus
  •  

KonradR

Hallo MzKIMu

Zitat von: MzKlMu am Mai 15, 2023, 12:23:08es wäre sinnvoll, wenn Du jetzt noch erklärst um welches Formular es geht. Und beschreibe Dein Vorgehen schrittweise.
Das Kombinationsfeld cboeinkaZutatIDRef um das es geht befindet sich auf dem Formular frm03BWTMahlzeitRezepteZutatenErfassen_Unter welches ein Unterformular vom Hauptformularr frm00BWT_Haupt ist.

Mein Vorgehen:
Wenn ich mit der rechten Maustaste auf das Kombinationsfeld klicke, anschließend den Eintrag ändere dann mit der rechten Maustaste das selbst erstellte Kontextmenü aufrufe und da den Eintrag "Zutat in der Stammtabelle bearbeiten" auswähle und mit der linken Maustaste bestätige, soll der Eintrag bzw. der Text, der im Kombinationsfeld zu sehen ist in der Tabelle "tblZutaten" geändert werden. Dabei entspricht der im Kombinationsfeld angezeigte Text vor der Änderung dem Inhalt des Feldes "ZutatName" in der Tabelle "tblZutaten" und ist über das Feld "ZutatID" referenziert. Nach der Änderung soll der im Kombinationsfeld geänderte Text in das Feld "ZutatName" der betreffenden, referenzierten Zutat geschrieben werden und den vorherigen Inhalt in dem entsprechenden Feld in der Tabelle "tblZutaten" ersetzen.

Zitat von: MzKlMu am Mai 15, 2023, 12:23:08Es wäre auch nicht notwendig gewesen die ganze DB hier hochzuladen. Ein Ausschnit mit dem Problem hätte genügt.
Dann habe ich das falsch verstanden.

Zitat von: MzKlMu am Mai 15, 2023, 12:23:08Es wäre auch nicht notwendig gewesen die ganze DB hier hochzuladen. Ein Ausschnit mit dem Problem hätte genügt.
Das ist mehr als ich erwarten kann. Vielen Dank dafür.
  •  

KonradR

Hallo MzKIMu,

ich denke, dass ich mir gerade meine Frage selbst beantwortet habe. Ich habe ja das Problem, dass es mir bei einer Änderung im genannten Kombinationsfeld und der Auswahl des betreffenden Menübefehls über das selbst erstellte Kontextmenü die Änderung in das entsprechende Feld in der Tabelle "tblZutaten" schreibt und diese Änderung zusätzlich als neuen Datensatz anlegt. Jedoch hatte ich vergessen, dass ich für das Kombinationsfeld das Ereignis "NOT IN LIST" programmiert hatte. Da sollte dann ein neuer Datensatz eingefügt werden, wenn es den noch nicht gibt. Daher werde ich für das Ereigniss "NOT IN LIST" zu erst eine Prüfung über eine If Verzweigung vorsehen, die prüft ob schon was im Kombinationsfeld drin ist. Wenn nicht, wird bei dem Ereignis "NOT IN LIST" ein neuer Datensatz hinzugefügt, sonst wird er bearbeitet. Das probiere ich mal und schreibe dann hier meine Antwort noch mal rein.
  •  

KonradR

Hallo MzKIMu, Hallo PhilS,

ich habe jetzt eine Lösung gefunden. Hier mein Code und vielen Dank für eure Hilfe, dass war mir ein großer Beitrag:
Option Compare Database
Option Explicit

Dim cboWertVorhanden As Integer

Private Sub cboeinkaZutatIDRef_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Me.NewRecord = True Then
        cboWertVorhanden = 0
    Else
        cboWertVorhanden = 1
    End If
End Sub

Private Sub cboeinkaZutatIDRef_NotInList(NewData As String, Response As Integer)
    Dim db As DAO.Database
    Dim dbZutat As DAO.Database
    Dim cboZutatText As String
    Dim cboZutatWert As Long
    Dim strSQL As String
   
    Set dbZutat = CurrentDb
    Set db = CurrentDb
   
    If cboWertVorhanden = 0 Then
        db.Execute "INSERT INTO tblZutaten(ZutatName) VALUES ('" & NewData & "')", _
        dbFailOnError
        Response = acDataErrAdded
    ElseIf cboWertVorhanden = 1 Then
        cboZutatText = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Text
        cboZutatWert = Forms![frm00BWT_Haupt]![sfrmBWTEinkaufsliste_Unter].Form![cboeinkaZutatIDRef].Value
        strSQL = "UPDATE tblZutaten SET ZutatName = '" & cboZutatText & "'"
        strSQL = strSQL & " WHERE ZutatID = " & cboZutatWert
        dbZutat.Execute strSQL, dbFailOnError
        Response = acDataErrAdded
    End If
End Sub

  •