Brauche Resourcenspaarende Variante um eine Exel Tabelle einzulesen.

  • Nabend!
    Ich habe mir mal selber einen CSV-Parser geschrieben um CSV´s einzulesen, speichern und neu zu erstellen. Alles mit nem 2D-Array! Ich habe die Funktion jetzt nicht mehr Testen können, aber sie sollte funktionieren...

    Spoiler anzeigen
    [autoit]

    Func _CSVparser($sFile, $iStart = 0, $iEnd = 0, $sMode = "Load", $a2DArray = 0)
    Local $a2DArrayNeu[1][1], $iRow, $iCol
    Switch $sMode
    Case "Load"
    Local $tmp, $tmpArray
    Local $file = FileOpen($sFile)
    Local $tmpArray = FileRead($sFile)
    FileClose($file)
    $tmpArray = StringSplit($tmpArray, @CRLF, 1)
    $iRow = $tmpArray[0]
    _ArrayDelete($tmpArray, 0)
    $tmp = StringSplit($tmpArray[0], ";", 1)
    $iCol = $tmp[0]
    ReDim $a2DArrayNeu[$iRow][$iCol]
    for $i = 0 to $iRow-1
    $tmp = StringSplit($tmpArray[$i], ";", 1)
    for $j = 0 to $tmp[0]-1
    $a2DArrayNeu[$i][$j] = $tmp[$j+1]
    Next
    Next
    Return $a2DArrayNeu

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

    Case "Save"
    Local $tmp
    Local $file = FileOpen($sFile)
    Local $a2DArrayNeu = FileRead($sFile)
    FileClose($file)
    $a2DArrayNeu = StringSplit($a2DArrayNeu, @CRLF, 1)
    $iRow = $a2DArrayNeu[0]
    _ArrayDelete($a2DArrayNeu, 0)
    $tmp = StringSplit($a2DArrayNeu[0], ";")
    $iCol = $tmp[0]
    if $iEnd = 0 then $iEnd = $iCol
    if $iEnd > $iRow then $iEnd = $iRow
    Local $sCSV
    for $i = $iStart to $iEnd-1
    for $j = 0 to $iCol-1
    $sCSV &= $a2DArray[$i-$iStart][$j] & ";"
    Next
    $sCSV = StringTrimRight($sCSV, 1) & @CRLF
    Next
    $sCSV = StringTrimRight($sCSV, 2)
    $file = FileOpen($sFile, 10)
    FileWrite($file, $sCSV)
    FileClose($file)
    Return 1

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

    Case "New"
    $iEnd = UBound($a2DArray,1)
    $iCol = UBound($a2DArray,2)
    ReDim $a2DArrayNeu[$iEnd]
    Local $sCSV
    for $i = 0 to $iEnd-1
    for $j = 0 to $iCol-1
    $sCSV &= $a2DArray[$i][$j] & ";"
    Next
    $sCSV = StringTrimRight($sCSV, 1) & @CRLF
    Next
    $sCSV = StringTrimRight($sCSV, 2)
    if FileExists($sFile) then FileDelete($sFile)
    $file = FileOpen($sFile, 10)
    FileWrite($file, $sCSV)
    FileClose($file)
    Return 1

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

    EndSwitch
    EndFunc

    [/autoit]


    Kannste ja mal Testen,
    Grüsse!

    [EDIT]
    Mit $iStart und $iEnd kann man den Bereich wählen der ausgelesen/gespeichert werden soll.
    $a2DArray Ist für das Abspeichern wichtig, da mußte eben das CSV-Array angeben welches Gesichert werden soll.

    misterspeed: Bei wirklich GROSSEN CSV-Dateien ist diese Möglichkeit viiiiel schneller als mit _FileReadToArray - Da ich einfach Fileread verwende und anschliessend eben mit StringSplit trenne.

  • misterspeed: Bei wirklich GROSSEN CSV-Dateien ist diese Möglichkeit viiiiel schneller als mit _FileReadToArray - Da ich einfach Fileread verwende und anschliessend eben mit StringSplit trenne.

    Glaube ich dir prinzipiell, allerdings macht _filereadtoarray() so ziemlich das selbe. Der Unterschied ist, dass deine Funktion z.B. nur auf @CRLF splitten kann. Besitzt die CSV hingegen lediglich @LF oder @CR für den Zeilenumbruch, was leider nicht selten so ist, dann würde deine Funktion scheitern, _filereadtoarrray hingegen nicht. Das mag zwar etwas langsamer, dafür aber auch zuverlässiger sein. Ein weiterer Nachteil deiner Lösung könnte die Nutzung von _arraydelete() sein, dürfte btw auch unnötig sein den Eintrag zu löschen, da man die Indizes auch anderweitig anpassen kann. Wenn ich mich recht entsinne glänzt diese Funktion auch nicht unbedingt durch Performance, müsste man aber testen. Nicht böse gemeint, viele Wege führen nach Rom, die einen schneller, die anderen zuverlässiger.

  • OK, nix Böse :D
    Ich habe meine CSV´s mit @crlf getrennt - weil meine einfach so aufgestellt waren ;) Und das Arraydelete bezieht sich auf das Stringsplit - ginge auch anders, so war´s einfach bequemer...
    Aber wie du sagtest viele Wege führen nach Rom :)

    Ausserdem habe ich diese Funktion auch eher als Vorlage eingeworfen, lässt sich natülich immer verändern und verbessern...
    Grüsse!

  • Mal ne Zwischenfrage: Wenn das eine CSV-Datei ist und ein MySQL-Server, hast du kein Shellzugriff auf den MySQL-Server?
    mysqld kann auch CSV-Dateien direkt verarbeiten.
    Bei mir wurstelt der mysqld 1,2 Millionen Datensätze innerhalb von 30Sekunden in die Datenbank.