TIA Fehler beim Lesen mit Script

aleXandroW

Level-2
Beiträge
59
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe beim Lesen aus einer CSV Datei folgendens Problem:
In der ersten 5 Zeilen stehen irrelevante Informationen, die ich ignoriere. Danach kommen die Informationen die ich rauslesen will. Ich mache dies mit folgendem Code:

Code:
For i=1 To 5
    data = fo.LineInputString
Next

For k=1 To 60
    data = fo.LineInputString
    splitdata=Split(data,semi)
    SmartTags("Produktionsdaten alt " & k & ".Datum") = splitdata(1)
    SmartTags("Produktionsdaten alt " & k & ".Rezept") = splitdata(2)
    SmartTags("Produktionsdaten alt " & k & ".Kochernummer") = splitdata(3)
    SmartTags("Produktionsdaten alt " & k & ".Start Kochung Zeit") = splitdata(4)
    SmartTags("Produktionsdaten alt " & k & ".Ende Kochung Zeit") = splitdata(5)
    SmartTags("Produktionsdaten alt " & k & ".Nachkochungen") = splitdata(6)
    SmartTags("Produktionsdaten alt " & k & ".Druck") = splitdata(7)
    SmartTags("Produktionsdaten alt " & k & ".Start Entleerung Zeit") = splitdata(8)
    SmartTags("Produktionsdaten alt " & k & ".Ende Entleerung Zeit") = splitdata(9)
    SmartTags("Produktionsdaten alt " & k & ".Start Darre Entleerung Zeit") = splitdata(10)
    SmartTags("Produktionsdaten alt " & k & ".Ende Darre Entleerung Zeit") = splitdata(11)
Next

Wenn ich in Zeile 8 (k=3) keine Einträge mehr habe dann kriege ich die Werte aus Zeile 7 (k=2) rausgegeben. Das hängt wohl damit zusammen das data noch die alten Werte gespeichert hat?

Wie kriege ich dies gelöst?
 
Probiere mal nach dem Split() mit UBound(splitdata) abzufragen in wie viele Teile die Zeile gesplittet wurde.

Harald
 
Hmm, dann wird das Array bei Split anscheinend bei Bedarf nur größer, aber nicht wieder kleiner...
Schau mal in die VBS-Hilfe, ob man vielleicht mit Redim oder ähnlichem das Array splitdata vor dem Split wieder verkleinern kann.
Notfalls könntest Du vor dem Split die Werte aller Elemente von splitdata auf den Wert -1 oder was anderes nicht vorkommendes setzen.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ShowSystemAlarm UBound(splitdata) ergibt 11
Hast Du das bei der leeren Zeile ausgegeben?
Welche TIA-Version und welches Panel hast Du?

Ich habe mit WinCC flexible getestet, da liefert Zeile aus Datei einlesen + Split + UBound(splitdata) korrekt den höchsten Arrayindex entsprechend der Anzahl Werte in der Zeile.

Kurzer Testcode für das Split:
Code:
Dim splitdata

splitdata = Split("1;2;3", ";")
ShowSystemAlarm "Z1: " & UBound(splitdata) [COLOR="#008000"]'ergibt 2[/COLOR]

splitdata = Split("1", ";")
ShowSystemAlarm "Z2: " & UBound(splitdata) [COLOR="#008000"]'ergibt 0[/COLOR]

splitdata = Split("", ";")
ShowSystemAlarm "Z3: " & UBound(splitdata) [COLOR="#008000"]'ergibt -1[/COLOR]

splitdata = Split("1;2;3", ";")
ShowSystemAlarm "Z4: " & UBound(splitdata) [COLOR="#008000"]'ergibt 2[/COLOR]

PS: Wieso eigentlich wertest Du nie splitdata(0) aus (den ersten Wert in der Zeile)?

Harald
 
Ich habe TIA V15 mit TP1200.

Ich habe das UBound mal bei der leeren und nicht leeren Zeile angewendet. Kam bei beiden 11 raus.

splitdata(0) ist eigentlich nur ein Index und nicht relevant.

Hier der Code zum speichern

Code:
    If fs.dir(datei) = "" Then
        fo.open datei, 2
        fo.LinePrint "Kochanlage 2 " & semi & "Produktionsdaten "
        fo.LinePrint ""
        fo.LinePrint "Erstelldatum: " & semi & datum
        fo.LinePrint ""
        fo.LinePrint "Index " & semi & "Datum " & semi & "Rezept " & semi & "Kocher " & semi & "Start Kochung " & semi & "Ende Kochung " & semi & "Nachkochungen " & semi & "Druck " & semi & "Start Entleerung " & semi & "Ende Entleerung " & semi & "Start Darre Entl. " & semi & "Ende Darre Entl. "
        fo.LinePrint "1 " & semi & SmartTags("Produktverfolgung Darre.Datum") & semi & SmartTags("Produktverfolgung Darre.Rezept") & semi & SmartTags("Produktverfolgung Darre.Kochernummer") & semi & SmartTags("Produktverfolgung Darre.Start Kochung Zeit") & semi & SmartTags("Produktverfolgung Darre.Ende Kochung Zeit") & semi & SmartTags("Produktverfolgung Darre.Nachkochungen") & semi & SmartTags("Produktverfolgung Darre.Druck") & semi & SmartTags("Produktverfolgung Darre.Start Entleerung Zeit") & semi & SmartTags("Produktverfolgung Darre.Ende Entleerung Zeit") & semi & SmartTags("Produktverfolgung Darre.Start Darre Entleerung Zeit") & semi &  SmartTags("Produktverfolgung Darre.Ende Darre Entleerung Zeit")
        fo.Close
    Else
        fo.open datei, 8
        fo.LinePrint "1 " & semi & SmartTags("Produktverfolgung Darre.Datum") & semi & SmartTags("Produktverfolgung Darre.Rezept") & semi & SmartTags("Produktverfolgung Darre.Kochernummer") & semi & SmartTags("Produktverfolgung Darre.Start Kochung Zeit") & semi & SmartTags("Produktverfolgung Darre.Ende Kochung Zeit") & semi & SmartTags("Produktverfolgung Darre.Nachkochungen") & semi & SmartTags("Produktverfolgung Darre.Druck") & semi & SmartTags("Produktverfolgung Darre.Start Entleerung Zeit") & semi & SmartTags("Produktverfolgung Darre.Ende Entleerung Zeit") & semi & SmartTags("Produktverfolgung Darre.Start Darre Entleerung Zeit") & semi &  SmartTags("Produktverfolgung Darre.Ende Darre Entleerung Zeit")
        fo.Close
    End If
 
Ich habe das UBound mal bei der leeren und nicht leeren Zeile angewendet. Kam bei beiden 11 raus.
Bei einer leeren Zeile muß UBound den Wert -1 liefern. Es sei denn, die "leere Zeile" gibt es überhaupt gar nicht, dann schlägt schon vorher das "data = fo.LineInputString" fehl und es wird ein Runtime-Error geworfen und das Skript abgebrochen - es sei denn Du hast festgelegt daß Runtime-Errors einfach ignoriert werden sollen ("On Error Resume Next"), dann arbeitet das Split(data,semi) mit der vorher eingelesenen Zeile.

Wenn ich in Zeile 8 (k=3) keine Einträge mehr habe dann kriege ich die Werte aus Zeile 7 (k=2) rausgegeben.
Was heißt "keine Einträge mehr"? Hat die Zeile 8 nur 11 Semikolons ohne Werte dazwischen oder ist die Zeile komplett leer (mit einer Zeilenschaltung davor und einer oder keiner Zeilenschaltung dahinter) oder gibt es gar keine Zeile 8 mehr (ist die Datei da schon zuende)? Hast Du Dir die csv-Datei mal mit einem einfachen Texteditor angeschaut und kannst Du da den Eingabecursor unter den Zeilenanfang der Zeile 7 setzen oder nur ans Ende der Zeile 7? z.B. Notepad von Windows: wo springt der Eingabecursor hin wenn Du Strg+Ende drückst?

Erweitere mal Dein Skript um die blauen Codezeilen:
Code:
For i=1 To 5
[COLOR="#0000FF"]    If fo.EOF Then [COLOR="#008000"]'Datei-Ende erreicht?[/COLOR]
        ShowSystemAlarm "csv einlesen: Datei '" & datei & "' enthält keine Datenzeilen"
        Exit For
    End If[/COLOR]
    data = fo.LineInputString
Next

For k=1 To 60
[COLOR="#0000FF"]    If fo.EOF Then [COLOR="#008000"]'Datei-Ende erreicht?[/COLOR]
        Exit For
    End If[/COLOR]
    data = fo.LineInputString
    splitdata = Split(data,semi)
[COLOR="#0000FF"]    If UBound(splitdata) <> 11 Then
        ShowSystemAlarm "csv einlesen: Formatfehler Datei '" & datei & "' Zeile " & k + 5 'oder: k + i
        Exit For
    Else[/COLOR]
        SmartTags("Produktionsdaten alt " & k & ".Datum") = splitdata(1)
        ...
        SmartTags("Produktionsdaten alt " & k & ".Ende Darre Entleerung Zeit") = splitdata(11)
[COLOR="#0000FF"]    End If[/COLOR]
Next

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ohne "On Error Resume Next" kommt die Meldung 'File Pointer has reached End of File' im Script Zeile 98. Zeile 98 wäre "data = fo.LineInputString" in der 1 bis 60 Schleife.

Im Anhang habe ich ein Screen der CSV Datei angehängt. Mit Strg+Ende springt der Cursor zu L7

Mit deinem Code wird ohne Feherausgabe die Datei richtig ausgelesen. Ich müsste dann noch die restlichen Variablen mit 0 füllen, weil sonst ja die alten Werte gespeichert sind.
 

Anhänge

  • CSV Datei.JPG
    CSV Datei.JPG
    58 KB · Aufrufe: 12
Als Programmierer, der csv-Dateien auswerten will/soll, schaut man sich csv-Dateien mit einem Texteditor (oder ganz harte Fälle mit einem Hex-Editor) an und nicht mit Excel wie die normalen Anwender... ;) :cool:

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit deinem Code wird ohne Feherausgabe die Datei richtig ausgelesen. Ich müsste dann noch die restlichen Variablen mit 0 füllen, weil sonst ja die alten Werte gespeichert sind.
Du könntest einfach eine Muster-Zeile (Datensatz mit Null-Werten) angeben, welche anstelle der nicht vorhandenen Zeilen ausgewertet wird:
Code:
[COLOR="#0000FF"]Dim NullDS[/COLOR]

For i=1 To 5
    If fo.EOF Then [COLOR="#008000"]'Datei-Ende erreicht?[/COLOR]
        ShowSystemAlarm "csv einlesen: Datei '" & datei & "' enthält keine Datenzeilen"
        Exit For
    End If
    data = fo.LineInputString
Next

[COLOR="#008000"]'Datensatz mit Null-Werten, Index wird weiter unten davor zugefügt[/COLOR]
[COLOR="#0000FF"]NullDS = semi& "01.01.1990 00:00:00" &semi& "(kein)" &semi& 0 _
        &semi& "01.01.1990 00:00:00" &semi& "01.01.1990 00:00:00" &semi& 0 &semi& 0 _
        &semi& "01.01.1990 00:00:00" &semi& "01.01.1990 00:00:00" _
        &semi& "01.01.1990 00:00:00" &semi& "01.01.1990 00:00:00"[/COLOR]

For k=1 To 60
    If fo.EOF Then [COLOR="#008000"]'Datei-Ende erreicht?[/COLOR]
[COLOR="#0000FF"]        data = k & NullDS [COLOR="#008000"]'Datensatz mit Index und Null-Werten[/COLOR]
    Else
        data = fo.LineInputString [COLOR="#008000"]'Zeile mit Datensatz aus Datei[/COLOR][/COLOR]
    End If
    splitdata = Split(data,semi)
    If UBound(splitdata) <> 11 Then
        ShowSystemAlarm "csv einlesen: Formatfehler Datei '" & datei & "' Zeile " & k + 5 [COLOR="#008000"]'oder: k + i[/COLOR]
        Exit For
    Else
        SmartTags("Produktionsdaten alt " & k & ".Datum") = splitdata(1)
        ...
        SmartTags("Produktionsdaten alt " & k & ".Ende Darre Entleerung Zeit") = splitdata(11)
    End If
Next

Harald
 
Zuletzt bearbeitet:
Zurück
Oben