Office: (Office 2016) Currentdb.Execute delete löscht alle Datensätze trotz Where Bedingung

Helfe beim Thema Currentdb.Execute delete löscht alle Datensätze trotz Where Bedingung in Microsoft Access Hilfe um das Problem gemeinsam zu lösen; Hallo Zusammen, ich hoffe, dass mir jemand weiter helfen kann. Ich habe folgendes Problem: Ich habe eine Tabelle (RegieImp), in welche ich aus Excel... Dieses Thema im Forum "Microsoft Access Hilfe" wurde erstellt von dejupp, 23. Januar 2024.

  1. dejupp User

    Currentdb.Execute delete löscht alle Datensätze trotz Where Bedingung


    Hallo Zusammen,
    ich hoffe, dass mir jemand weiter helfen kann. Ich habe folgendes Problem:
    Ich habe eine Tabelle (RegieImp), in welche ich aus Excel Daten importiere. Es gibt eine eindeutige ID (DigiTi ID), welche sich wie folgt zusammensetzt:
    2023/012285-1 oder eben...2023/012285-2; die ersten 11 Zeichen sind Jahr und eine eindeutige fortlaufende Nummer. die Zahl hinter dem Minus ist eine "Versionsnummer". D.h. es kann vorkommen, dass zunächst die Version 1 importiert wird, dann aber - aufgrund von Änderungen - die Version 1 verworfen wird und an deren Stelle die Version 2 tritt (Die Daten kommen nicht von mir). Da die Daten somit immer wieder aktuallisiert werden, kann es vorkommen, dass Daten "quasi" doppelt vorkommen (obwohl ja durch die Versionsnummer immernoch eindeutig). Ich benötige aber immer nur die neueste Version (hat mit der Weiterverarbeitung der Daten zu tun) und muss daher die ältere Version löschen. In meiner Tabelle habe ich zu Testzwecken einige Datensätze mit der Version 1 einen Datensatz mit 2 Versionen. Ich habe dazu folgenden Code entworfen - wobei ich zunächst zu Testzwecken erstmal nur die Version 2 löschen möchte:
    Code:
    Public Sub Regiebereinigen()
    
    Dim db As DAO.Database
    Dim rsimp As DAO.Recordset
    
    Dim Summe As String
    Dim digiti As String
    Dim digitiAZ As String
    Dim digitistamm As String
    Dim digitiex As Long
    Dim strSQLD As String
    
    Set db = CurrentDb
    Set rsimp = db.OpenRecordset("RegieImp")
    On Error Resume Next
    
    Do Until rsimp.EOF
        
        digiti = rsimp![DigiTi ID]
        digitistamm = Left(digiti, 11)
        digitiex = Right(digiti, 1)
        strSQLD = "DELETE * FROM RegieImp " & "WHERE " & digiti & "=" & digitistamm & -2
        'alternativ ... strSQLD = "DELETE * FROM RegieImp WHERE " & digitiex & " = 2"
        Debug.Print strSQLD
        CurrentDb.Execute strSQLD, dbFailOnError
        ' alternativ ... DoCmd.RunSQL ("DELETE * FROM RegieImp WHERE " & digitiex & " = 2")
        
        rsimp.MoveNext
    Loop
    
    End Sub
    Leider löscht er mir immer alle Datensätze, trotz "Where-Bedingung". Er durchläuft die ersten Datensätze mit der Version 1. Sobald er den Datensatz mit der Version 2 findet, löst er "Alle" Datensätze.
    Kann mir jemand weiter helfen? Wo liegt der Fehler?
    Vielen Dank,
    DeJupp
     
  2. Doming
    Doming hat Ahnung
    Moin DeJupp,

    ich mag keine Sonderzeichen in einer ID, also würde ich mir die Daten erst mal aufbereiten.
    In diesem Fall würde ich mir die Daten in eine Tabelle importieren, damit sie eine vernünftige ID bekommen (Autowert). Ich beschränke mich jetzt mal nur auf die ID, die Felder, die Du ansonsten brauchst, müssen natürlich auch mit in die Tabelle.
    In diesem besteht sie aus dID (primärschlüssel), DigiTi (die Zahlen bis zum Bindestrich (das / wird durch Relace gelöscht)) und die Version, also alles, was nach dem Bindestrich kommt.
    In der Tabelle beides als Zahl definiert.
    Code:
    INSERT INTO Tabelle1 (DigiTi, Version)
    SELECT Left(Replace([digiti_ID],"/",""),10)*1 AS dID, Mid([digiti_id],InStr([digiti_id],"-")+1) AS Version
    FROM tbl_RegieImp
    ORDER BY Left(Replace([digiti_ID],"/",""),10)*1, Mid([digiti_id],InStr([digiti_id],"-")+1) DESC;
    So werden die Daten sortiert importiert. Je nachdem welche die aktuellere Version ist, kann man dann in der Schleife die kommenden Daten mit der gleichen DigiTi löschen
    Ich trenne die Spalte [DigiTi ID] in die Felder ID und Version auf.
    Die Löschprozedur kann man dann so durchführen
    Code:
    Public Sub Regiebereinigen()
     Dim cDB As DAO.Database
     Dim rsImp As DAO.Recordset
     
        Set db = CurrentDb
        Set rsImp = db.OpenRecordset("Tabelle1")
        Do Until rsImp.EOF
            If DCount("ID", "Tabelle1", "DigiTi = " & rsImp!ID) > 1 Then
                strSQL = "DELETE FROM Tabelle1 WHERE DigiTi = " & rsImp!digiti & " AND dID <> " & rsImp!dID
                cDB.Execute strSQL, dbFailOnError
            End If
            rsImp.MoveNext
        Loop
    
        Set rsImp = Nothing
    End Sub
    
    Musst mal gucken, ob Du damit klarkommst. Evtl ist es sicherer, die Daten erst in der Löschschleife sortiert aufzurufen, damit man auch immer die Version zuerst erwischt, die bleiben soll.
    Gruß
    Doming
     
  3. dejupp User
    Hallo Doming,

    auch hierfür herzlichen Dank. Es hat zwar etwas gedauert, aber mit bissl umschreiben hat es jetzt funktioniert.

    Da ich ja schon eine Importdatei habe, hab ich die importierten Datensätze dann einfach nur mit UPDATE die entsprechenden Felder ergänzt. Mit INSERT INTO hat es nicht funktioniert, da ich ja keine neuen Datensätze anfügen wollte, sondern die DigiTi ID nur gesplittet zusätzlich in den Datensatz aufnehmen wollte:

    Code:
    '3. Ergänzen der Datensätze RegieImp bit gesplitteter DigiTI ID
    Dim db As DAO.Database
    Dim rsimp As DAO.Recordset
    
    Dim digiti As String
    Dim digitistamm As String
    Dim Version As Integer
    Dim strSQLD As String
    
    Set db = CurrentDb
    Set rsimp = db.OpenRecordset("SELECT * FROM RegieImp " & "ORDER BY DigiTi, Version ASC;")
    
    Do Until rsimp.EOF
        digiti = rsimp![DigiTi ID]
        digitistamm = Left(Replace(digiti, "/", ""), 10) * 1
        Version = Mid(digiti, InStr(digiti, "-") + 1)
    
        strSQLD = "Update RegieImp set DigiTi = " & digitistamm & "  where " & "[DigiTi ID] = '" & digiti & "'"
        'Debug.Print strSQLD
        CurrentDb.Execute strSQLD, dbFailOnError
        strSQLD = "Update RegieImp set Version= " & Version & "  where " & "[DigiTi ID] = '" & digiti & "'"
        'Debug.Print strSQLD
        CurrentDb.Execute strSQLD, dbFailOnError
        
        rsimp.MoveNext
    Loop
    Bei der DELETE Anweisung musste ich auch etwas basteln und probieren, bis ich die richtige Synthax hatte, aber jetzt funktioniert es. Ich weiß nur nicht warum ;-):

    Code:
    Public Sub Regiebereinigen()
    
    Dim db As DAO.Database
    Dim rsimp As DAO.Recordset
    Dim rsAZimp As DAO.Recordset
    Dim rs As DAO.Recordset
    Dim digiti As String
    Dim digitiAZ As String
    Dim digitistamm As String
    Dim Version As Integer
    Dim strSQLD As String
    Dim anzahl As Integer
    
    Set db = CurrentDb
    Set rsimp = db.OpenRecordset("select * from RegieImp")
    Set rsAZimp = db.OpenRecordset("select * from RegieAZImp")
    Set rs = db.OpenRecordset("select * from Regie")
    'On Error Resume Next
    
    Do Until rsimp.EOF
        digiti = rsimp![DigiTi ID]
        digitistamm = Left(Replace(digiti, "/", ""), 10) * 1
        Version = Mid(digiti, InStr(digiti, "-") + 1)
        anzahl = DCount("[DigiTi ID]", "RegieImp", "[DigiTi] = '" & digitistamm & "'")
        'Debug.Print anzahl
        If anzahl > 1 Then
    
            strSQLD = "DELETE FROM RegieImp WHERE " & "[DigiTi ID] = '" & digiti & "'" & " And " & [digiti] & " <> '" & digitistamm & "'"
            'Debug.Print strSQLD
            CurrentDb.Execute strSQLD, dbFailOnError
        End If
        rsimp.MoveNext
    Loop
    Set rsimp = Nothing
    
    End Sub
    Vielen Dank nochmal
    Gruß DeJupp
     
  4. Doming
    Doming hat Ahnung

    Currentdb.Execute delete löscht alle Datensätze trotz Where Bedingung

    ääääh vielleicht solltest Du das 'Debug.Print strSQLD wieder aktivieren?
    strSQLD = "DELETE FROM RegieImp WHERE " & "[DigiTi ID] = '" & digiti & "'" & " And " & [digiti] & " <> '" & digitistamm & "'"

    oben steht digiti = rsimp![DigiTi ID], also steht in dem Satz in rot: WHERE [DigiTi ID] = [DigiTi ID], kann also weg.
    also bleibt WHERE [DigiTi ID] <> '" digitistamm & "'" - digistamm ist ein Teil von [DigiTi ID], wie kann es also identisch sein?
    Das soll funktionieren?
     
  5. Doming
    Doming hat Ahnung
    Probier mal sowas:
    Erstelle eine Abfrage, meinetwegen Abfrage1
    Code:
    SELECT Left(Replace([DigiTi ID],"/",""),10)*1 AS DigitiStamm, Mid([DigiTi ID],InStr([DigiTi ID],"-")+1)*1 AS Version
    FROM tbl_RegieImp;
    So hast Du den Digitistamm als Zahl und auch die Version als Zahl (Ist wichtig, sonst wäre Version 11 niedriger als Version 2)

    Nun kannst Du die STRSQLD vom vorherigen Post so aufziehen:
    strSQLD = "DELETE FROM Abfrage1 WHERE Digitistamm = " & rsImp!Digitistamm & " AND Version <> " & rsImp!Version
    Musst natürlich sicherstellen, dass Du den Datensatz aktiviert hast, der bleiben soll.
     
  6. dejupp User
    Hallo Doming,

    etwas spuki ;-):
    genau das habe ich auch nicht verstanden, normalerweise geht das nicht. Aber nach näherem Betrachten und probieren und dem Debug.Print aktivieren hab ichs verstanden. Folgendes (hier mal mein Code mit mehreren Varianten zum Verständnis):
    Code:
    Public Sub Regiebereinigen()
    
    Dim db As DAO.Database
    Dim rsimp As DAO.Recordset
    Dim rsAZimp As DAO.Recordset
    Dim rs As DAO.Recordset
    Dim digiti As String
    Dim digitiAZ As String
    Dim digitistamm As String
    Dim Version As Integer
    Dim strSQLD As String
    Dim anzahl As Integer
    
    Set db = CurrentDb
    Set rsimp = db.OpenRecordset("select * from RegieImp")
    Set rsAZimp = db.OpenRecordset("select * from RegieAZImp")
    Set rs = db.OpenRecordset("select * from Regie")
    'On Error Resume Next
    
    Do Until rsimp.EOF
        digiti = rsimp![DigiTi ID]
        digitistamm = Left(Replace(digiti, "/", ""), 10) * 1
        Version = Mid(digiti, InStr(digiti, "-") + 1)
        anzahl = DCount("[DigiTi ID]", "RegieImp", "[DigiTi] = '" & digitistamm & "'")
        'Debug.Print anzahl
        If anzahl > 1 Then
            ' hier löscht es die niedrigeren Versionen/Datensätze (also die Älteren), wenn DigiTi ID richtig sortiert ist:
            'strSQLD = "DELETE FROM RegieImp WHERE " & "[DigiTi ID] = '" & digiti & "'" & " And " & [digiti] & " <> '" & digitistamm & "'"  'funktioniert nur, weil der erste Teil stimmt und der zweite Teil <> vergleicht
            'strSQLD = "DELETE FROM RegieImp WHERE " & "[DigiTi ID] = '" & digiti & "'" & " And " & "[DigiTi]" & " = '" & digitistamm & "'"
            'strSQLD = "DELETE FROM RegieImp WHERE " & "[DigiTi ID] = '" & digiti & "'" & " And " & "[Version]" & " = " & Version & ""
            'strSQLD = "DELETE FROM RegieImp WHERE " & "[DigiTi ID] = '" & digiti & "'"
            strSQLD = "DELETE FROM RegieImp WHERE " & "[DigiTi]" & " = '" & digitistamm & "'" & " And " & "[Version]" & " = " & Version & ""
            
            ' hier löscht er die höheren Versionen (also die Neueren), jedoch nur, wenn "On Error Resume Next" aktiviert ist:
            'strSQLD = "DELETE FROM RegieImp WHERE " & "[DigiTi]" & " = '" & digitistamm & "'" & " And " & "[Version]" & " <> " & Version & ""
    
            Debug.Print strSQLD
            CurrentDb.Execute strSQLD, dbFailOnError
        End If
        rsimp.MoveNext
    Loop
    Set rsimp = Nothing
    
    End Sub
    
    Er macht ja mit jedem Datensatz einen Loop. Man darf hier nicht nur das DELETE mit der WHERE-Bedingung betrachten, sondern auch die vorgeschaltete IF THEN Anweisung.

    Richtig, Aber...
    Er vergleicht ja im Loop einen aktuell gefundenen/untersuchten x-ten Datensatz aus der Tabelle [RegieImp] mit eben der in der Tabelle [RegieImp] befindlichen Datensätze, also irgendwie schon mit sich selbst, aber durch den Loop eben einen Datensatz nach dem anderen. Da findet er also immer so viele Match's, wie Datensätze vorhanden sind. So und jetzt kommt die If Then Anweisung dazu. Die besagt ja, dass das nur passieren soll, wenn mehr als 1 Datensatz davon vorhanden ist. Somit reduziert sich das ganze erstmal stark. Dann löscht er den ersten, den er findet und macht den loop gleich nochmal. Da dann aber nur noch ein Datensatz von dieser Digiti ID vorhanden kommt er durch die If Then Anweisung gar nicht erst in die DELETE Anweisung. Deswegen funktioniert es auch nur mit dem:
    [QUOTE"DELETE FROM RegieImp WHERE " & "[DigiTi ID] = '" & digiti & "'"][/QUOTE]
    es muss nur sortiert sein. Der zweite Vergleich hinter dem AND ist quasi durch das <> irrelevant. Da kannst du auch Äppel mit Birnen vergleichen, und es würde trotzdem funktionieren.

    So ich danke dir auf jeden Fall für deine Hilfe, du hast mich auf den richtigen Trichter gebracht.
    Gruß DeJupp
     
Thema:

Currentdb.Execute delete löscht alle Datensätze trotz Where Bedingung

Die Seite wird geladen...
  1. Currentdb.Execute delete löscht alle Datensätze trotz Where Bedingung - Similar Threads - Currentdb Execute delete

  2. Delete und Backspace in TextBox deaktivieren

    in Microsoft Excel Hilfe
    Delete und Backspace in TextBox deaktivieren: Hallo, gibt es eine Möglichkeit, in einer Textbox einer Userform die Tasten Delete und Backspace zu deaktivieren? Die Eingabe in der Textbox darf nicht gelöscht werden, sondern soll überschrieben...
  3. Commandbar().delete

    in Microsoft Excel Hilfe
    Commandbar().delete: Hi Leute! Ich habe eine Befehlsleiste mit vielen eigens erstellten Icons. Diese habe ich an meine Arbeitsmappe angefügt. An den Rechnern an denen diese Mappe geöffnet wird, wird Diese von Excel...
  4. Sql Delete Left Join

    in Microsoft Access Hilfe
    Sql Delete Left Join: Moin, ich versuche Löschaktion zu führen in HT die keine Daten in UT haben, leider erfolglos. Code: DELETE tabATupdate.* FROM tabATupdate LEFT JOIN tabUnATupdate ON tabATupdate.UpID =...
  5. Transaktionen und CurrentDB()?

    in Microsoft Access Hilfe
    Transaktionen und CurrentDB()?: Hallo zusammen, ich habe in meiner Anwendung eine globale Variable Dim db as DAO.Database definiert, welche beim Starten mit set db = CurrentDB initialisiert wird. Alle folgenden Zugriffe auf...
  6. DELETE-Anweisung

    in Microsoft Access Tutorials
    DELETE-Anweisung: DELETE-Anweisung Access für Microsoft 365 Access 2019 Access 2016 Access 2013 Access 2010 Access 2007 Mehr... Weniger...
  7. EXECUTE-Anweisung

    in Microsoft Access Tutorials
    EXECUTE-Anweisung: EXECUTE-Anweisung Access für Microsoft 365 Access 2019 Access 2016 Access 2013 Access 2010 Access 2007 Mehr... Weniger...
  8. Kann nicht Text auwaehlen und dann mit Delete Taste Loeschen

    in Microsoft Word Hilfe
    Kann nicht Text auwaehlen und dann mit Delete Taste Loeschen: Problem mit Microsoft Word. Ich kann nicht einen Text auswaehlen und dann loeschen. Mit del delete Taste kann ich nur ein Buchstabe nach dem anderen loeschen. Wenn mir jemand helfen kann waer es...
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Auf dieser Website werden Cookies für die Zugriffsanalyse und Anzeigenmessung verwendet.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden