leere Zeilen im Array am Ende löschen

  • Hallo,

    ich habe ein Script, in dem ich CSV Dateien verarbeite. Die CSV wird mit

    [autoit]

    global $Array = _CSV2Array("test.csv")

    [/autoit]


    eingelesen.
    Da die CSV am Ende unterschiedlich viele leere Zeilen hat, wird direkt nachdem das Array erstellt wurde, folgender Code ausgeführt um diese zu löschen:

    [autoit]


    while 1
    If $array[ubound($array)-1][0] = "" Then
    _arraydelete($array,ubound($array))
    Else
    exitloop
    EndIf
    WEnd

    [/autoit]

    Das funktioniert auch so weit. Sporadisch bekomme ich jedoch den Fehler
    Error: Subscript used with non-Array variable.

    Starte ich nun das Script neu und verarbeite die gleiche Datei nochmal, bekomme ich keinen Fehler.

    Nachdem das Array verarbeitet wurde, lösche ich dieses mit $Array="0"

    Ich kann mir diesen Fehler nicht erklären.

    Bestimmt habe ich irgendwo einen Denkfehler und ich sehe es nicht :rolleyes:

  • Der Codeschnipsel den du gepostet hast sieht auf den ersten Blick o.k. aus.
    Der Fehler könnte durchaus woanders liegen.

    Poste also bitte mal ein Minimalskript, welches ohne weitere Änderung direkt bei jedem lauffähig ist und welches den Fehler reproduziert.

  • [autoit]


    #include <_csv2array.au3>
    #include <array.au3>
    #include <file.au3>
    ;deklariere Variablen
    global $logfile=@scriptdir&"\log.txt"
    global $Array = _CSV2Array("test.csv")

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

    _arraydisplay($array)

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

    filewriteline($LogFile,@MDAY&"."&@MON&"."&@YEAR&" "&@hour&":"&@MIN&":"&@SEC&":"&@msec&" lösche leere Zeilen in Array")
    ;~ alle leeren Zeilen am Ende des Arrays löschen
    while 1
    If $array[ubound($array)-1][1] = "" Then
    filewriteline($LogFile,@MDAY&"."&@MON&"."&@YEAR&" "&@hour&":"&@MIN&":"&@SEC&":"&@msec&" Arraygröße:"&ubound($array)-1&" Wert von $array[ubound($array)-1][1]="& $array[ubound($array)-1][1])
    filewriteline($LogFile,@MDAY&"."&@MON&"."&@YEAR&" "&@hour&":"&@MIN&":"&@SEC&":"&@msec&" lösche Zeile")
    _arraydelete($array,ubound($array))
    Else
    exitloop
    EndIf
    WEnd

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

    filewriteline($LogFile,@MDAY&"."&@MON&"."&@YEAR&" "&@hour&":"&@MIN&":"&@SEC&":"&@msec&" lösche leere Zeilen in Array FERTIG")

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

    _arraydisplay($array)

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

    global $Array="0"

    [/autoit]

    Inhalt der CSV ist z.B.

    Spoiler anzeigen


    1,2,3,4,5
    a,b,c,d,e
    b,c,d,e,f
    c,d,e,f,g
    ,,,,
    ,,,,
    ,,,,

    Wenn das Script abstürzt, dann steht im Logfile der Eintrag bei Scriptzeile 10, Logeintrag für Scriptzeile 22 fehlt, ergo liegt der Fehler irgendwo zwischen Scriptzeile 12 und 20. Wie bereits erwähnt tritt der Fehler nur sporadisch auf :( .

  • Auch so ist der Fehler noch nicht nachvollziehbar. Ich denke mal es tritt nur bei bestimmten dateien auf oder?
    Gibt es eventuell Dateien in denen nur eine spalte befüllt ist?
    Die Zeile in der der Fehler auftritt steht direkt vor der Fehlermeldung. Die Zahl in Klammern. Auf die kann man sich auch fast immer verlassen ;)
    Anhand deiner Log datei solltest du auch rausbekommen woran es liegt und wo der Fehler auftritt. Was schreibt denn Zeile 14 in die Log datei wenn das script abstürzt?

    (Logging ist übrigens viel übersichtlicher mit _FileWriteLog)

  • Exakt mit diesem Code und exakt mit dieser csv bekommst du die Fehlermeldung?
    Fehlermeldungen dieser Art können eigentlich nur dann auftreten, wenn in der 2. Spalte (Index [1]) des Arrays alle Werte leer sind.

    Ich gehe jetzt einfach mal davon aus, das ist wirklich das reine unveränderte Skript mit welchem du den Fehler reproduzieren kannst bei dir (bei mir nicht).
    Weiterhin bleibt während des gesamten Vorganges die "test.csv" unangetastet von anderen Prozessen (Heißt also nicht irgendwo anders geöffnet oder wird gerade beschrieben oder ähnliches).
    Des Weiteren stammt die, von dir verwendete Funktion _CSV2Array() von >>Hier<<?
    Wenn dem so ist, ist das Verhalten tatsächlich merkwürdig.

    Ich habe dein Skript mal umgeschrieben und darauf geachtet auf jeden möglichen Fehler zu reagieren.
    Teste also mal ob der Fehler damit immer noch auftritt:

    Spoiler anzeigen
    [autoit]

    #include <_csv2array.au3>
    #include <array.au3>

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

    Global $Array = _CSV2Array("test.csv")

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

    _ArrayDisplay($Array)

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

    If Not IsArray($Array) Then
    MsgBox(48, "Fehler", "$Array ist kein Array!")
    Else
    If UBound($Array, 0) <> 2 Then
    MsgBox(48, "Fehler", "Array ist kein 2D-Array!")
    Else
    If UBound($Array, 2) < 2 Then
    MsgBox(48, "Fehler", "Array hat nur eine Spalte ")
    ExitLoop
    Else
    ; Endzeilen bei denen die zweite Spalte leer ist löschen:
    For $i = UBound($Array) - 1 To 0 Step -1
    If $i = 0 Then
    MsgBox(48, "Fehler", "Arrayspalte 2 war komplett leer!")
    ExitLoop
    EndIf
    If $Array[$i][1] = "" Then
    ReDim $Array[$i][UBound($Array, 2)]
    Else
    ExitLoop
    EndIf
    Next
    EndIf
    EndIf
    EndIf

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

    _ArrayDisplay($Array)

    [/autoit]
  • (Logging ist übrigens viel übersichtlicher mit _FileWriteLog)

    Wieder was gelernt :)

    Der Fehler ist um genau zu sein

    OK
    Line 12521 (File "C:\Script\Script2.exe"):
    Error: Subscript used with non-Array variable.

    Die CSV an sich hat nur ca. 5000 Zeilen +- und der Code zum leere Zeilen löschen steht im Script bei Zeile 150

    Die Dateien an sich haben immer den gleichen Aufbau. Mittlerweile speichere ich Sie sogar zwischen mit einer Laufnummer. Wenn ich nach einem Fehler exakt die Datei, die zum Zeitpunkt des Fehlers benutzt wurde, wieder in das Script einschiesse, funktionierts.

    Wie shcon gesagt: Der Fehler tritt nur sporadisch auf. Es kann 5 Tage lang alles gut gehen; dann macht es ein/zwei mal Bang und es läuft munter weiter.

    Zeile 14 liefert keinen LOG Eintrag, ergo bleibt er bei Zeile 13 hängen

    Da fällt mir gerade ein: Kann es vielleicht an den von mir eingesetzten Versionen (Programm/Includes) liegen?
    Folgende Versionen werden derzeit von mir eingesetzt:

    Spoiler anzeigen


    AutoIt v3.3.8.1
    SciTE Version 3.3.0

    array.au3
    ; #INDEX# =======================================================================================================================
    ; Title .........: Array
    ; AutoIt Version : 3.2.10++
    ; Language ......: English
    ; Description ...: Functions for manipulating arrays.
    ; Author(s) .....: JdeB, Erik Pilsits, Ultima, Dale (Klaatu) Thompson, Cephas,randallc, Gary Frost, GEOSoft,
    ; Helias Gerassimou(hgeras), Brian Keene, SolidSnake, gcriaco, LazyCoder, Tylo, David Nuttall,
    ; Adam Moore (redndahead), SmOke_N, litlmike, Valik
    ; ===============================================================================================================================

    file.au3
    ; #INDEX# =======================================================================================================================
    ; Title .........: File
    ; AutoIt Version : 3.2
    ; Language ......: English
    ; Description ...: Functions that assist with files and directories.
    ; Author(s) .....: Brian Keene, SolidSnake, erifash, Jon, JdeB, Jeremy Landes, MrCreatoR, cdkid, Valik,Erik Pilsits, Kurt, Dale
    ; Dll(s) ........: shell32.dll
    ; ===============================================================================================================================

    _csv2array.au3
    ; #FUNCTION# ===================================================================
    ; Name ..........: _CSV2Array
    ; Description ...:
    ; AutoIt Version : V3.3.0.0
    ; Syntax ........: _CSV2Array($hFile[, $cSeperator = "auto"[, $bFilterString = True[, $iColumnMode = 0]]])
    ; Parameter(s): .: $hFile - Handle for the CSV file to Read
    ; $cSeperator - Optional: (Default = "auto") : Tries to find the separator char ;) or , or TAB or | or space)
    ; | Data-seperator-char
    ; | Empty-string = Opt("GUIDataSeparatorChar")
    ; $bFilterString - Optional: (Default = True) : Removes leading and trailing " or '
    ; $iColumnMode - Optional: (Default = 0) :
    ; | 0: Sets error if lines have different columns and @extended to the csv-line number
    ; | 1: returns lines with different columns numbers comparing to the first line, too
    ; | 2: removing all columns > column numbers in the first line
    ; Return Value ..: Success - 2-dim Array
    ; Failure - 0
    ; @ERROR - 1: error file read
    ; @ERROR - 2: different number of columns / @EXTENDED = CSV-line
    ; - 3: parameter error
    ; Author(s) .....: Thorsten Willert
    ; Date ..........: Mon Dec 07 18:59:46 CET 2009
    ; ==============================================================================


    Zitat

    Weiterhin bleibt während des gesamten Vorganges die "test.csv" unangetastet von anderen Prozessen (Heißt also nicht irgendwo anders geöffnet oder wird gerade beschrieben oder ähnliches).

    Im Hintergrund läuft ein weiteres Script, das ein EMail Postfach prüft und bei Mail Eingang Anhänge in ein Verzeichnis schreibt. Erst wenn der Mailanhang komplett heruntergeladen wurde, wird die Datei in das Zielverzeichnis kopiert. Das andere Script überprüft dieses Zielverzeichnis und wenn Daten vorhanden sind legt es los. Zwischen dem Zeitpunkt "Datei ist vorhanden" und "lösche leere Zeilen" ist ein Sleep Timer von 5 Sek. eingebaut. Bzgl. Schreibgeschwindigkeit von Daten: ich sag nur SSD :D

    Für mich zum Verständnis:
    Da die Log in Zeile 10 geschrieben wird, sollte ja der _CSV2Array Vorgang erfolgreich abgeschlossen sein. Demnach sind die Daten im Array und die Datei Test.csv interessiert nicht mehr.