CSV Datei umwandeln und Zeilen vergleichen

  • Hallo zusammen,

    ich komme leider gerade nicht weiter und finde leider auch woanders keine Lösung.

    Hintergrund: ich habe eine CSV-Datei mit verschiedenen Aufträgen.
    Problem ist, dass ein Auftrag mehrere Positionen haben kann, aber jede Postion in einer Zeile steht.
    Ich will die Ausgangsdatei aber in etwas schlankeres umwandeln, also quasi pro Auftrag nur eine Zeile und relevante Werte von den Positionen hintendran.
    Das könnte ich anhand einer Auftragsnummer ausmachen, die in jeder Zeile steht.

    Sowit bin ich zur Zeit:

    [autoit]

    Local $position
    Local $counter = 0

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

    if GUICtrlRead($Checkbox1) = $GUI_CHECKED then
    $file = FileOpenDialog("Bitte wählen Sie eine Datei aus.", @ScriptDir , "CSV-Datei (*.csv)", 1 )
    Else
    $file = @ScriptDir & "\test.csv"
    EndIf

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

    Dim $array
    if Not _FileReadToArray($file, $array) Then
    MsgBox(16,"Error", "Datei konnte nicht gelesen werden!")
    Return $array
    EndIf

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

    ; Ausgangsdatei hat einen Kopf
    For $zeile = 2 To $array[0]
    $wert = StringSplit($array[$zeile], ";")
    $position &= ($wert[1] & ";" & $wert[2] & ";" & $wert[7] & ";" & $wert[8] & ";" & $wert[9] & ";" & $wert[10] & ";" & $wert[14] & ";" & $wert[24] & ";" & $wert[25] & ";" & $wert[29] & ";" & $wert[39] & ";" & $wert[61] & ";" & $wert[66] & ";" & $wert[67] & ";" & $wert[68] & ";" & $wert[72] &@CRLF)
    $counter += 1

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

    Next

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

    FileWrite(@ScriptDir & '\ausgabe.csv', $position)
    MsgBox(0,"Info", "Die Datei hat "&$counter&" Position(en).")

    [/autoit]

    Aber wie kann ich nun die Auftragsnummer (um genau zu sein Spalte 25) in den Zeilen vergleichen und dann gewisse Werte (61, 66, 67 und 68 ) aus den mehrfach vorkommenden Zeilen an die 1. Zeile des Auftrags in der neuen Datei "hintendran" setzen?

    Geht das überhaupt alles auf einmal oder muss ich eine Temp-Datei erzeugen und dort weitermachen?

    Sorry, aber ich steh gerade echt auf dem Schlauch. ?( :(

    2 Mal editiert, zuletzt von odein (29. Juli 2013 um 11:47)

  • Schon mal über eine Schleife überlegt, in der du für jede Zeile nach der Auftragsnummer des jetzigen Durchlaufs dein Array sortierst?

    Ich mag nicht sagen es ist performant, aber ich könnt mir vorstellen das es klappt mit der ein oder anderen Erweiterung...

    #Edit: Ich stelle mir die Datei so vor:

    und du willst die dann so haben:

    Code
    neue Zeilennummer | Auftragsnummer | alte Zeilennummer(n)
    ----------------------------------------------------------------------------------------
    1 | 101 | 1
    2 | 99 | 2, 32, 76
    3 | 237 | 3
    4 | 123 | 4
    5 | 323 | 5

    Davon ausgegangen es gibt 4 Spalten und auf meine Auffassung oben bezogen...

    ungetestet!
    [autoit]

    ; Declare all $Vars first ...

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

    If GUICtrlRead($iCheckbox1) = $GUI_CHECKED then
    $hFile = FileOpenDialog("Bitte wählen Sie eine Datei aus.", @ScriptDir , "CSV-Datei (*.csv)", 1 )
    Else
    $hFile = @ScriptDir & "\test.csv"
    EndIf

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

    If Not _FileReadToArray($hFile, $aFilecontent) Then
    MsgBox(16, "Error", "Datei konnte nicht gelesen werden!")
    Return $aFilecontent
    EndIf

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

    For $i = 2 To $aFilecontent[0]
    $aValues = StringSplit($aFilecontent[$i], ";")
    $aIndexes = _ArrayFindAll($aFilecontent, $aValues[2])
    $sLine = $aValues[1]

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

    ;Look up all found rows with the same value in column $aValues[2]
    For $y = 0 To UBound($aIndexes)
    $aValues2 = StringSplit($aIndexes[$y], ";")
    ;Add all values after column $aValues[2] found by equal $aValues[2]-value
    For $z = 3 To $aValues2[0]
    If $z = 3 Then
    $sLine &= ";" & $aValues2[$i]
    ElseIf $z = $aValues2[0]
    $sLine &= $aValues2[$i]
    Else
    $sLine &= " , " & $aValues2[$i] & " , "
    EndIf
    Next
    Next

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

    $sLine &= ";" & $aValues[3] ;Add the last column
    $iPositions += 1
    Next

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

    FileWrite(@ScriptDir & '\ausgabe.csv', $sLine)
    MsgBox(64, "Info", "Die Datei hat " & $iPositions & " Position(en).")

    [/autoit]

    Grüße Yaerox

    Grüne Hölle

    3 Mal editiert, zuletzt von Yaerox (29. Juli 2013 um 12:33)

  • Hallo,

    danke für die schnellen Antworten.

    Sorry war blöd vor mir erklärt, hätte gleich ein Layout zeigen können...

    Ich mein es eher so:

    Ausgangsdatei:

    Code
    Name; Straße; PLZ; Ort; Auftragsnummer; Artikelnr.; VK
    ----------------------------------------------------------------------
    Mustermann; Musterstr. 15; 12345; Musterstadt; 0001; 01; 6,99
    Mustermann; Musterstr. 15; 12345; Musterstadt; 0001; 50; 9,50
    Mustermann; Musterstr. 15; 12345; Musterstadt; 0001; 15; 19,99
    Meier; Hauptstr. 1; 09845; Testhausen; 0002; 60; 1,99
    Schmitz; Teststraße 1, 79884; Hauptstadt; 0003; 05; 4,99
    Schmitz; Teststraße 1, 79884; Hauptstadt; 0003; 10; 6,99

    Enddatei:

    Code
    Name; Straße; PLZ; Ort; Auftragsnummer; Artikelnr.; VK
    ----------------------------------------------------------------------
    Mustermann; Musterstr. 15; 12345; Musterstadt; 0001; 01|6,99|50|9,50|15|19,99
    Meier; Hauptstr. 1; 09845; Testhausen; 0002; 60|1,99
    Schmitz; Teststraße 1, 79884; Hauptstadt; 0003; 05|4,99|10|6,99
  • Kannst dir ja mein Beispiel mal anschauen, es ist für sowas gedacht, wie gesagt leider ungetestet, aber vielleicht hilft dir das auf die springende Idee zu kommen.

    Im endeffekt wird bei dir Name; Straße; PLZ; Ort; Auftragsnummer zum Suchkriterium und Artikelnr. und VK als Anhangskriterium genutzt.

    Grüße Yaerox

    Grüne Hölle

  • Hallo YaeroxXO,

    vielen Dank, hab ich und bin gerade schon fleißig am testen... :D aber zur Zeit spukt er mir immer nur das Suchkriterium aus...

  • Falls ich es richtig verstanden habe:

    [autoit]

    #include <array.au3>
    #include <GUIConstantsEx.au3>
    #include <File.au3>
    Dim $aFilInp,$aFld
    Dim $hFilInp
    dim $sFilInp,$i,$j

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

    $sFilInp = FileOpenDialog("Bitte wählen Sie eine Datei aus.", @ScriptDir , "CSV-Datei (*.csv)", 1 )
    if @error then ; oder was auch immer
    $sFilInp = @ScriptDir & "\test_Input.csv"
    consolewrite(@crlf&@ScriptDir & "\test_Input.csv")
    EndIf

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

    If Not _FileReadToArray($sFilInp, $aFilInp) Then
    MsgBox(16, "Error", "Datei konnte nicht gelesen werden!")
    ;Return $aFilInp
    EndIf
    Dim $aFilOut [$aFilInp[0]] =[0] ;Ausgabe maximal = eingabezeilen

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

    For $i = 2 To $aFilInp[0]
    $aFld = StringSplit($aFilInp[$i], ";")
    $j = _ArraySearch($aFilOut,";"&$aFld[5]&";",1,0,0,1) ; Casesensitiv,Partial compare
    if @error then ; Auftragsnummer neu
    $aFilOut[0] += 1 ; Neues Elementweiterzählen
    $aFilOut[$aFilOut[0]] = $aFilInp[$i] ; ganze zeile
    else
    $aFilOut[$j] &= ";"& $aFld[6] &";"& $aFld[7] ; nur arttikelnr & Preis anhängen
    endif
    next
    Redim $aFilOut [$aFilOut[0]+1] ; auf aktuelle Zeilenanzahl reduzieren
    _arraydisplay($aFilOut)
    _FileWriteFromArray(@ScriptDir & '\Test_Ausgabe.csv',$aFilOut,1,$aFilOut[0],";")
    MsgBox(64, "Info", "Die Datei hat " & $aFilOut[0] & " Position(en).")

    [/autoit]


    Eingabe:

    Spoiler anzeigen

    Name; Straße; PLZ; Ort; Auftragsnummer; Artikelnr.; VKPreis
    Mustermann; Musterstr. 15; 12345; Musterstadt; 0001; 01; 6,99
    Mustermann; Musterstr. 15; 12345; Musterstadt; 0001; 50; 9,50
    Mustermann; Musterstr. 15; 12345; Musterstadt; 0001; 15; 19,99
    Meier; Hauptstr. 1; 09845; Testhausen; 0002; 60; 1,99
    Schmitz; Teststraße 1; 79884; Hauptstadt; 0003; 05; 4,99
    Schmitz; Teststraße 1; 79884; Hauptstadt; 0003; 10; 6,99


    Ausgabe:

    Spoiler anzeigen


    Mustermann; Musterstr. 15; 12345; Musterstadt; 0001; 01; 6,99; 50; 9,50; 15; 19,99
    Meier; Hauptstr. 1; 09845; Testhausen; 0002; 60; 1,99
    Schmitz; Teststraße 1; 79884; Hauptstadt; 0003; 05; 4,99; 10; 6,99


    mfG
    DerPensionist