Access-o-Mania

Access-Forum (Deutsch/German) => Formular => Thema gestartet von: Umbauwfb am März 01, 2022, 10:22:00

Titel: SQL mit Laufzeitfehler 3141
Beitrag von: Umbauwfb am März 01, 2022, 10:22:00
Ich hänge einmal mehr an einem SQL fest, obwohl ich der Meinung bin, alles richtig gemacht zu haben...

vID_von und vID_zu bringen die richtigen Werte...
Die restlichen Angaben im SQL habe ich x-mal geprüft...die müssten auch stimmen...

Was ist falsch? Die Fehlermeldung hängt als jpg an...

Der weitere Code ist noch nicht abgeschlossen
Vielen Dank für die Hilfe

Fehlermeldung an der Stelle 'rs_von definieren:

Public Sub TN_verschieben()                   '#loop_doppelt
Dim dB As DAO.Database
Dim rs_von As DAO.Recordset
Dim rs_zu As DAO.Recordset

Dim vID_von As Long
Dim vID_zu As Long

Dim SQL_count As Long

Dim msg As String

Set dB = CurrentDb

'ID_von ermitteln
vID_von = Forms!AdressdatenTauschF.txtFirmenID_von.Value

'ID_zu ermitteln
vID_zu = Forms!AdressdatenTauschF.txtFirmenID_zu.Value


'rs_von definieren
    Set rs_von = dB.OpenRecordset("SELECT" _
    & " FROM TeilnehmerAdressdatenT" _
    & " WHERE AdressdatenID = vID_von;")
       
   
        Do Until rs_von.EOF
       
                'rs_zu definieren
                Set rs_zu = dB.OpenRecordset("SELECT" _
                & "from TeilnehmerAdressdatenT" _
                & "WHERE AdressdatenID = vID_zu;")
               
                    SQL_count = "count (ID) from rs_zu WHERE rs_von!TeilnehmerID = rs_von!TeilnehmerID"
                   
                    Debug.Print SQL_count

Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: PhilS am März 01, 2022, 10:41:29
In deinem zweiten SQL für dB.OpenRecordset fehlen Leerzeichen vor und/oder nach den Zeilenumbrüchen im VBA-Code und deinem SQL_count fehlt das SELECT.

Bei Gelegenheit könntest du dir mal mein Tutorial-Video zu SQL Strings in VBA (https://www.youtube.com/watch?v=HSGSsjcbi2c) anschauen.
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: DF6GL am März 01, 2022, 10:54:40
Hallo,

ohne zu wissen, was überhaupt erreicht werden soll:


ZitatWas ist falsch?

alles...


ZitatPublic Sub TN_verschieben(vID_von as Long, vID_zu as Long)                 
Dim dB As DAO.Database
Dim rs_von As DAO.Recordset
Dim rs_zu As DAO.Recordset

Dim vID_von as Long
Dim vID_zu as Long
    ---> Prozedur-Argumente




Set dB = CurrentDb


    Set rs_von = dB.OpenRecordset("SELECT" _
    & " Count (*) As Anz FROM TeilnehmerAdressdatenT" _
    & " WHERE AdressdatenID = " & vID_von, dbOpenSnapshot))
       
                   
                    Debug.Print rs_von!Anz

    rs_von.close: Set rs_von = Nothing

End Sub
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: ebs17 am März 01, 2022, 11:54:44
Ich muss den Wortbeiträgen von Franz vollständig zustimmen. Die zu stellende Frage sollte eher sein: Was war richtig?

Beginnen sollte man aber mit der Einleitung, was EIGENTLICH gemacht werden soll. Aus der gezeigten Codezusammenwürfelung kann ich nicht wirklich einen Sinn entnehmen.
Daher widerspreche ich auch teilweise der Ansicht, aus Codebeispielen könnte man lernen.
Erst der Sinn, dann die Aktion.

Daher ist eine Codeverbesserung zwar gut gemeint, sehr wahrscheinlich aber wirkungslos.
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: Umbauwfb am März 01, 2022, 12:14:09
Sorry,
ich habe mich nur auf diese eine Stelle fokussiert und daher zu wenig Info mitgegeben...

Aufgabe: (anhängend ein Screenshot des Formulars mit Aufgabenbeschreibung)
Firmenadressen können doppelt in die Datenbank eingetragen werden, wenn trotz aller Prüfungen der Firmenname unterschiedlich (mit GBR/ ohne GBR...unkomplett...etc) geschrieben wird.
Wenn bei der zu löschenden Firma schon Beziehungen zu Teilnehmern erstellt wurden, lässt sich diese nicht löschen, weil die Beziehungen bestehen...die Beziehungen sollen ja auch erhalten bleiben, aber verschoben werden.
Deswegen müssen vor dem Löschen des Datensatzes alle Beziehungen von der linken (roten) ID auf die rechte (grüne) ID geändert werden.

Ich wollte das wieder mit einem Loop lösen und innerhalb des Loops prüfen, ob es in dem rs_zu schon einen Datensatz mit der TeilnehmerID aus rs_von gibt.
Dafür wollte ich zählen... und wenn count größer 0 folgt: keine Aktion
Wenn count = 0 folgt:  rs_von!TeilnehmerID wird zu vID_zu oder eben(Forms!AdressdatenTauschF.txtFirmenID_zu.Value)

Sorry für die Verwirrung...beim nächsten mal mache ich das Ganze wieder gründlicher
Harry
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: Umbauwfb am März 01, 2022, 12:20:35
Zitat von: PhilS am März 01, 2022, 10:41:29In deinem zweiten SQL für dB.OpenRecordset fehlen Leerzeichen vor und/oder nach den Zeilenumbrüchen im VBA-Code und deinem SQL_count fehlt das SELECT.

Bei Gelegenheit könntest du dir mal mein Tutorial-Video zu SQL Strings in VBA (https://www.youtube.com/watch?v=HSGSsjcbi2c) anschauen.

Hallo PhilS...danke für den Hinweis...das Video kenne ich schon. Ich habe Dich abonniert. Ich wusste nur nicht dass Du das bist :-)
Harry
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: ebs17 am März 01, 2022, 14:42:22
ZitatIch wollte das wieder mit einem Loop lösen
Ja, die Finger an den Händen abzuzählen ist intellektuell einfach und intuitiv naheliegend.

Wenn man aber in einer Datenbank arbeitet und diese nutzen will, so auch ihre Stärken wie Methoden zur Massendatenverarbeitung, gäbe es da andere und sehr befriedigende Möglichkeiten:
Grundlagen - SQL ist leicht (0) - Vorspiel (https://www.ms-office-forum.net/forum/showthread.php?t=317692)

Wenn ich mich nicht schwer irre, war der Thementitel und damit die Frage nach einer SQL-Anweisung und nicht einem viertel Dutzend in Loops  verschlungen.

Wegen der Fehlermeldung, wenn es interessiert: Würde man nicht gezielt auf die betroffene Anweisung hinweisen, oder gilt die Regel: Wenn man selber nichts weiß, müssen andere alles wissen, wozu sich da spezifiert äußern?
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: Beaker s.a. am März 01, 2022, 18:02:40
UPDATE AdressdatenT
SET AdressdatenT.ID = DeineNeueID
WHERE AdressdatenT.ID = DeineAlteID

edit: in Code eingebettet
Dim sSQL As String
sSQL = "UPDATE AdressdatenT" _
& " SET AdressdatenT.ID = " & DeineNeueID _
& " WHERE AdressdatenT.ID = " & DeineAlteID
CurrentDb.Execute sSQL, 128
' vergessen, geht dann weiter
sSQL = "DELETE FROM Firmen WHERE FirmenID = & DeineAlteID
CurrentDb.Execute sSQL, 128
[code].
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: Umbauwfb am März 02, 2022, 08:27:38
Vielen Dank für den Code, den Ihr für mich geschrieben habt.
Die Aufgabenstellung war von mir anfangs ungenügend beschrieben, weil ich eigentlich nur Hilfe für die angegebene Stelle haben wollte und dann weiter aufbauen wollte.
Deswegen treffen leider manche Stellen eurer Codes nicht die Anforderung. Sorry!

Den Code von Beaker s.a. kann ich leider nicht verwenden, weil der nicht abprüft, ob ein solcher Datensatz schon vorhanden ist. Es wird einfach angehängt (oder verstehe ich das falsch?)
Das kann dann zu doppelten Datensätzen führen.

Ich habe zum Gesamtverständnis jetzt noch ein jpg der Beziehungen angehängt.

Mein Code sieht jetzt wie nachfolgend aus...
Ich hänge noch an der Stelle fest, wo ich das AND einbringen muss...was schreibe ich da falsch?
Der Block obendrüber ohne AND läuft...

& " WHERE AdressdatenID = " & rs_von!TeilnehmerID" _
& " AND TeilnehmerID = " & vID_zu, dbOpenDynaset)     



Private Sub cmdTeilnehmerVerschieben_Click()
                 
Dim dB As DAO.Database
Dim rs_von As DAO.Recordset
Dim rs_zu As DAO.Recordset

Dim vID_von As Long
Dim vID_zu As Long

Dim sSQL As String

Set dB = CurrentDb
vID_von = Me.txtFirmenID_von.Value      'braucht man das .Value?    Brauche ich die Variable oder kann ich direkt den Wert des Textfelds einsetzen?
vID_zu = Me.txtFirmenID_zu.Value        'braucht man das .Value?    Brauche ich die Variable oder kann ich direkt den Wert des Textfelds einsetzen?

    Set rs_von = dB.OpenRecordset("SELECT" _
    & " * FROM TeilnehmerAdressdatenT" _
    & " WHERE AdressdatenID = " & vID_von, dbOpenSnapshot)
 
        Do Until rs_von.EOF
       
                    Set rs_zu = dB.OpenRecordset("SELECT" _
                    & " Count (*) As Anz FROM TeilnehmerAdressdatenT" _
                    & " WHERE AdressdatenID = " & rs_von!TeilnehmerID, dbOpenDynaset)   'dieser Block läuft...
                                                                                        'warum läuft der Block mit AND nicht?

'                    Set rs_zu = dB.OpenRecordset("SELECT" _
'                    & " Count (*) As Anz FROM TeilnehmerAdressdatenT" _
'                    & " WHERE AdressdatenID = " & rs_von!TeilnehmerID" _
'                    & " AND TeilnehmerID = " & vID_zu, dbOpenDynaset)          'wie muss ich die Stelle mit dem AND schreiben?
'
                                     
                    Debug.Print rs_zu!Anz
                   
                        If rs_zu!Anz = 0 Then
                            rs_zu!AdressdatenID = rs_von!AdressdatenID
                            Exit Do
                        End If

            rs_von.MoveNext
            Loop
           
    sSQL = "DELETE FROM TeilnehmerAdressdatenT WHERE AdressdatenID = & vID_von.Value"
    CurrentDb.Execute sSQL, dbFailOnError
       

'Aufräumen
Set rs_von = Nothing
Set rs_zu = Nothing
Set dB = Nothing

End Sub
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: Beaker s.a. am März 02, 2022, 16:01:23
Hallo Harry,
Zitat von: undefinedDen Code von Beaker s.a. kann ich leider nicht verwenden, weil der nicht abprüft, ob ein solcher Datensatz schon vorhanden ist. Es wird einfach angehängt (oder verstehe ich das falsch?)
Nö, es wird nur ein Fremdschlüssel in einer abhängigen Tabelle geändert, und
anschliessend der DS, zu dem es dann keine abhängigen DS mehr gibt gelöscht.
Zitat von: undefinedDas kann dann zu doppelten Datensätzen führen.
Na ja, die hast du ja vorher auch schon gehabt, nur mit unterschiedlichem FK.
Die würde ich vorher löschen. Erstelle dazu mit dem Abfrage-Assi eine "Abfrage
zur Duplikatsuche". Die verwendest du dann im Code für eine Löschabfrage
CurrentDb.Execute "DELETE FROM NameDerAbfrage", 128
'dann Code wie geschrieben

Edit: Uuups, da muss natürlich noch ein Filter auf die alte Nummer rein
CurrentDb.Execute "DELETE FROM NameDerAbfrage WHERE ID = DeineAlteID", 128
'dann Code wie geschrieben
(bei den Schlüsselfeldern bin ich nicht sicher, ob das die richtigen sind, kann
man aus dem Bild nicht ganz klar ersehen.

gruss ekkehard
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: Umbauwfb am März 02, 2022, 17:54:13
Hallo Ekkehard,
vielen Dank dass Du dich so beständig um mein Problem kümmerst :-)

Ich schaue mir Deinen Code in aller Ruhe und gründlich an!

Kannst Du vielleicht noch 1nen Blick auf meinen jetzigen Stand werfen...ich denke der Code ist komplett und läuft...bis auf 1ne Stelle, wo ich den SQL mit dem AND nicht richtig schreiben kann.
Ich weiss nicht, in wieviel Versionen ich Anführungszeichen und Leerstellen gesetzt und wieder weggenommen habe. Es hängt nur an der "Rechtschreibung"...die Stelle ist in meinem letzten post klar gekennzeichnet...

Gruß aus Lüneburg
Harry
Titel: Re: SQL mit Laufzeitfehler 3141
Beitrag von: Umbauwfb am März 04, 2022, 14:30:02
Nach hartem Kampf, unter Einbezug sämtlicher Hinweise und vor allem Codes steht die Prozedur jetzt und läuft einwandfrei!
Vielen Dank für die Hilfe :)
Harry

Private Sub cmdTeilnehmerVerschieben_Click()
                 
Dim dB As DAO.Database

Dim rs_von As DAO.Recordset
Dim rs_zu As DAO.Recordset

Dim vID_von As Long
Dim vID_zu As Long

Dim sSQL As String
Dim sSQL1 As String

Set dB = CurrentDb
vID_von = Me.txtFirmenID_von
vID_zu = Me.txtFirmenID_zu
 
            Set rs_von = dB.OpenRecordset("SELECT" _
            & " * FROM TeilnehmerAdressdatenT" _
            & " WHERE AdressdatenID = " & vID_von, dbOpenSnapshot)
               
                Do Until rs_von.EOF
           
                    Set rs_zu = dB.OpenRecordset("SELECT" _
                    & " Count (*) As Anz FROM TeilnehmerAdressdatenT" _
                    & " WHERE AdressdatenID = " & vID_zu _
                    & " AND TeilnehmerID = " & rs_von!TeilnehmerID, dbOpenSnapshot)
                    Debug.Print rs_zu!Anz
 

                        If rs_zu!Anz = 0 Then
'                            TEST-Druck
'                            sSQL = "SELECT (*) FROM TeilnehmerAdressdatenT "
'                            sSQL = sSQL & " WHERE AdressdatenID = " & vID_von & " "
'                            sSQL = sSQL & " AND TeilnehmerID = " & rs_von!TeilnehmerID
'                            Debug.Print sSQL
                                               
                       
                            sSQL1 = "UPDATE TeilnehmerAdressdatenT SET AdressdatenID = '" & vID_zu & "'"
                            sSQL1 = sSQL1 & " WHERE AdressdatenID = " & vID_von & " "
                            sSQL1 = sSQL1 & " AND TeilnehmerID = " & rs_von!TeilnehmerID
'                            Debug.Print sSQL1
                            CurrentDb.Execute sSQL1, dbFailOnError

'                            Debug.Print vID_zu
'                            Exit Do
                        Else
                        End If
                rs_von.MoveNext
                Loop
           
    sSQL = "DELETE * FROM TeilnehmerAdressdatenT WHERE AdressdatenID = " & vID_von & " "
    CurrentDb.Execute sSQL, dbFailOnError
 
'Aufräumen
Set rs_von = Nothing
Set rs_zu = Nothing
Set dB = Nothing

End Sub