bestimmte Zeilen löschen

  • Hallo,
    habe hier ein kleines Problem mit den löschen in meinen .csv Dateien.

    Ich habe 3 .csv Dateien

    [autoit]

    $sFile1 = @ScriptDir & "\1.csv"
    $sFile2 = @ScriptDir & "\2.csv"
    $sFile3 = @ScriptDir & "\protokoll.csv"

    [/autoit]

    Die Daten von File1 kommen aus einer Exceltabelle
    Die Daten für File2 kommen aus File1

    [autoit]

    FileWrite($sFile2, FileRead($sFile1) & @CRLF & FileRead($sFile2))

    [/autoit]


    File2 wird über ein Listview geladen und es können einzelne Datensätze gelöscht werden.
    Doch bevor diese gelöscht werden, kommen sie ins Protokoll (File3).

    Da es häufig vorkommt, dass in der Exceltabelle noch Datensätze drinn sind die schon "durch File1 gelaufen" sind, bekommme ich dann natürlich die Datensätze wieder doppelt, was aber nicht gewollt ist.
    Für die "doppler" habe ich schon hier im Forum was funktionierendes eingebaut.

    Jetzt suche ich was um die Datensätze die im Protokoll(File3) stehen mit den aus File2 zu vergleichen und wenn gleiche Datensätze vorhanden, sollen diese komplett, also alle gelöscht werden im File2.

    Mein Ansatzt ist bisher, dass ich das Protokoll(File3) mit:

    [autoit]

    _FileReadToArray($sFile3, $aContent)

    [/autoit]

    in ein Array packe,
    Die Ausgabe mit:

    [autoit]

    _ArrayDisplay($aContent, 0)

    [/autoit]


    klappt auch, nur wie bekomme ich jetzt die Sachen die im Array sind, jetzt als Index für die Löschfunktion im File2.

    Oder besser gefragt, die Sachen die im Protokoll(File3) stehen, sollen und dürfen nicht mehr im File2 sein weil die ja schon "abgehandelt" sind und das bekomme ich nicht hin.

    Ich hoffe ich konnte mich irgendwie verständlich ausdrücken

    Einmal editiert, zuletzt von Jensen.. (26. April 2014 um 15:15)

  • Hallo Kanashius,
    erstmal Danke für deine Hilfe.
    Ich habe das mal gleich getestet, jedoch verändert sich nichts im File2.
    Hier mal der komplette Code den ich verwendet habe:

    [autoit]

    #include <array.au3>
    #include <File.au3>

    [/autoit][autoit][/autoit][autoit]

    Dim $aContent
    Dim $sData

    [/autoit][autoit][/autoit][autoit]

    $sFile2 = @ScriptDir & "\file2.csv"
    $sFile3 = @ScriptDir & "\protokoll.csv"

    [/autoit][autoit][/autoit][autoit]

    _deltest()

    [/autoit][autoit][/autoit][autoit]

    Func _deltest()
    If Not _FileReadToArray($sFile2, $aContent) Then
    MsgBox(0, "Achtung", "Datei konnte nicht eingelesen werden!")
    Exit
    EndIf
    _FileReadToArray($sFile3, $aContent) ; protokoll.csv einlesen im Array

    [/autoit][autoit][/autoit][autoit]

    _ArrayDisplay($aContent) ; Array anzeigen

    [/autoit][autoit][/autoit][autoit]

    $sData = FileRead($sFile2)
    ;MsgBox(0, "", $sData)
    For $i = 0 To UBound($aContent) - 1 Step 1
    StringReplace($sData, $aContent[$i], "")

    [/autoit][autoit][/autoit][autoit]

    Next
    FileDelete($sFile2)
    FileWrite($sFile2, $sData)

    [/autoit][autoit][/autoit][autoit]

    FileClose($sFile2)

    [/autoit][autoit][/autoit][autoit]

    EndFunc ;==>_deltest

    [/autoit]

    Die .csv Files sind folgend aufgebaut:

    protokoll.csv

    Code
    1
    2

    file2.csv

    Code
    1
    2
    3
    4
    5

    Jetzt sollen die Sachen was in der protokoll.csv stehen aus der file2.csv herrausgelöscht werden.
    Das heißt, am ende sollte die file2.csv so aussehen:
    file2.csv

    Code
    2
    3
    4
    5
  • Sorry. Flüchtigkeitsfehler von mir. StringReplace gibt einen String zurück. Ich habe den String nicht wieder gespeichert. Das ersetzte ist somit "verfallen"... :whistling:

    [autoit]

    #include <array.au3>
    #include <File.au3>

    [/autoit][autoit][/autoit][autoit]

    Dim $aContent
    Dim $sData

    [/autoit][autoit][/autoit][autoit]

    $sFile2 = @ScriptDir & "\file2.csv"
    $sFile3 = @ScriptDir & "\protokoll.csv"

    [/autoit][autoit][/autoit][autoit]

    _deltest()

    [/autoit][autoit][/autoit][autoit]

    Func _deltest()
    #cs
    If Not _FileReadToArray($sFile2, $aContent) Then
    MsgBox(0, "Achtung", "Datei konnte nicht eingelesen werden!")
    Exit
    EndIf
    _FileReadToArray($sFile3, $aContent) ; protokoll.csv einlesen im Array
    #ce
    $aContent=FileReadToArray($sFile3)
    _ArrayDisplay($aContent) ; Array anzeigen

    [/autoit][autoit][/autoit][autoit]

    $sData = FileRead($sFile2)
    ;MsgBox(0, "", $sData)
    ;msgbox(48,"",$sData)
    For $i = 0 To UBound($aContent) - 1 Step 1
    $sData=StringReplace($sData, $aContent[$i], "")
    Next
    $oFile=FileOpen($sFile2,2)
    FileWrite($sFile2, $sData)
    FileClose($oFile)
    EndFunc ;==>_deltest

    [/autoit]


    PS: Eventuell können noch "leere" zeilen übrig bleiben. Das liegt daran, dass dort dann @crlf oder @cr oder @lf drin steht. Dazu sieh dir die Makros am besten an (sie markieren das zeilenende). Daher sind sie im normalen Editor, etc. nicht sichtbar. (zum anzeigen kannst du z.B. Notepad++ verwenden. Dort kann man sich die anzeigen lassen.)
    Ich hab noch nen paar kleinere Änderungen hinzugefügt. Sieh sie dir am besten selbst an.

    Viel Glück noch! 8)

  • Moin!

    Hier mal mein Vorschlag mit einem Scripting Dictionary:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ;==> zur Vereinfachung/Veranschaulichung direkt Arrays deklarieren, anstatt einzulesen
    Global $aProtokoll[5] = [1,2,4,6,7]
    Global $afile2[10] = [1,2,3,4,5,6,7,8,9,10]

    [/autoit] [autoit][/autoit] [autoit]

    If _DelDouble() = 0 Then MsgBox(0, "", "Keine Doubletten gefunden!")
    _ArrayDisplay($afile2)
    ;<==

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Global $aProtokoll
    ;~ Global $afile2

    [/autoit] [autoit][/autoit] [autoit]

    ;~ $sFile2 = @ScriptDir & "\file2.csv"
    ;~ $sFile3 = @ScriptDir & "\protokoll.csv"

    [/autoit] [autoit][/autoit] [autoit]

    ;~ _FileReadToArray($sFile2, $afile2)
    ;~ _FileReadToArray($sFile3, $aProtokoll)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If _DelDouble() = 1 Then ;==> Datei nur schreiben, wenn etwas geändert wurde
    ;~ _FileWriteFromArray(@ScriptDir & "\file2.csv", $afile2, 1) ;==> Achtung: Startindex auf 1, da Index 0 die ursprüngliche Anzahl der Elemente enthält
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Func _DelDouble()
    Local $oDictionary = ObjCreate('Scripting.Dictionary')
    $oDictionary.CompareMode = 1
    For $i = 0 To UBound($aProtokoll) - 1
    $oDictionary.Add($aProtokoll[$i], 1)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Local $iIndex = 0, $iChangeFlag = 0
    For $iElement In $afile2
    If $oDictionary.Exists($iElement) Then
    _ArrayDelete($afile2, $iIndex)
    $iChangeFlag = 1
    $iIndex -= 1
    EndIf
    $iIndex += 1
    Next
    Return $iChangeFlag
    EndFunc

    [/autoit]


    Sanfte Grüße :D

  • Hi,
    Kanashius: ich hatte noch probleme mit diesen Teil weil er die Funktion nicht kannte bei mir.

    [autoit]

    $aContent=FileReadToArray($sFile3)

    [/autoit]

    habe das wieder geändert in:

    [autoit]

    _FileReadToArray($sFile3, $aContent)

    [/autoit]

    und jetzt funktioniert alles wie gewollt, vielen Dank nochmal für deine Hilfe.

    Friesel
    Auch dir ein Danke für deine Hilfe, ich habe das auch gleich mal getestet und werde es für einen anderen Part im Programm sehr gut gebrauchen können.