TIA Fehlende Anfangszeichen beim CSV Lesen

aleXandroW

Level-2
Beiträge
59
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
Über ein Script wird eine CSV Datei erstellt und dort ein Wort geschrieben. Das geschriebene Wort lese ich nun über Script wieder aus und gebe es als Ausgabefeld (Zeichenkette) auf dem Panel dar. Es fehlen aber die ersten beiden Bucstaben. Esist ein TP1900.
Beispiel:
DB50.DBX0.0 ist ein String[20], dieser wird in der CSV Datei geschrieben. Zum Beispiel "Hallo"
DB51.DBX0.0 ist ein String[20], dieser wird als Ausgabe benutzt und aus der CSV Datei gelesen. Dann steht im Panel "llo"
Hat wohl was mit dem Aufbau der Zeichenkette zu tun, aber komme nicht drauf wie man es löst
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe den Code mal verkürzt um es nicht zu unübersichtlich zu machen.

Schreiben: Es geht um SmartTags("Speichern Sorte 1")

'Dimensionieren Dim fo, fs,datei, semi, ordner1,ordner2, ordner3 Dim tag, monat, monat_aktuell, monat_davor, monatsname, jahr, datum semi = ";" tag = Day(Now) datum = Date tag = Day(Now) monat = Month(Now) monatsname = MonthName(monat,False) jahr = Year(Now) ordner1 = "\Storage Card SD\Tagesmenge" ordner2 = "\Storage Card SD\Tagesmenge\" & jahr ordner3 = "\Storage Card SD\Tagesmenge\" & jahr & "\" & monatsname datei = "\Storage Card SD\Tagesmenge\" & jahr & "\" & monatsname & "\" & datum & ".csv" 'Starten der Fehlerroutine On Error Resume Next 'Create a file object - Datei Objekt erstellen Set fo= CreateObject("FileCtl.File") 'Auf Fehler prüfen If Err.Number<> 0 Then ShowSystemAlarm "Error # " & CStr(Err.Number)& " "& Err.Description Err.Clear Exit Sub End If 'Ordner Objekt erstellen Set fs = CreateObject("filectl.filesystem") 'Auf Fehler prüfen If Err.Number<> 0 Then ShowSystemAlarm "Error # " & CStr(Err.Number)& " "& Err.Description Err.Clear Exit Sub End If 'Überpüfen ob Ordner1 exestiert, wenn nicht -> Ordner erstellen If fs.dir(ordner1) = "" Then fs.mkdir(ordner1) End If 'Überpüfen ob Ordner2 exestiert, wenn nicht -> Ordner erstellen If fs.dir(ordner2) = "" Then fs.mkdir(ordner2) End If 'Überpüfen ob Ordner3 exestiert, wenn nicht -> Ordner erstellen If fs.dir(ordner3) = "" Then fs.mkdir(ordner3) End If 'Öffnen bzw. Erstellen einer Datei fo.open datei,2 fo.LinePrint "Nr.1 " & semi & SmartTags("Speichern Sorte 1") 'Datei wird geschlossen fo.Close 'Objekt wird freigegeben Set fo = Nothing

Lesen: Es geht um SmartTags("Lesen Tag Sorte 1") = splitdata(1)

Dim fo, fs,datei,ordner Dim tag, monat, monat_aktuell, monat_davor, monatsname, jahr, datum, monatsspeicher, tagspeicher Dim mode, i Dim data, splitdata, semi 'Initialization of Tags - Initialisierung von Variablen mode=1 '1 = Input semi = ";" jahr = SmartTags("Lesen Auswahl Jahr") monatsspeicher = SmartTags("Lesen Auswahl Monat") monatsname = MonthName(monatsspeicher,False) tagspeicher = SmartTags("Lesen Auswahl Tag") 'Please replace all sequences which are enclosed with '_' by your own code. If tagspeicher < 10 Then tag = "0" & tagspeicher Else tag = tagspeicher End If 'Please replace all sequences which are enclosed with '_' by your own code. If monatsspeicher < 10 Then monat = "0" & monatsspeicher Else monat = monatsspeicher End If datum = tag & "." & monat & "." & jahr ordner = "\Storage Card SD\Tagesmenge\" & jahr & "\" & monatsname & "\" & datum & ".csv" 'Starting error routine - Starten der Fehlerroutine On Error Resume Next 'Create a file object - Datei Objekt erstellen Set fo= CreateObject("FileCtl.File") 'Check if any errors happend - Auf Fehler prüfen If Err.Number<> 0 Then ShowSystemAlarm "Error # " & CStr(Err.Number)& " "& Err.Description Err.Clear Exit Sub End If 'Open or creat a file - Öffnen bzw. Erstellen einer Datei fo.open ordner,mode 'Check if any errors happend - Auf Fehler prüfen If Err.Number<> 0 Then ShowSystemAlarm "Error # " & CStr(Err.Number)& " "& Err.Description SmartTags("Lesen Ereignis") = 1 Err.Clear Exit Sub End If 'Read data from file - Daten werden aus Datein gelesen, die ersten Zeilen irrelevant For i=1 To 5 data = fo.LineInputString Next data = fo.LineInputString splitdata=Split(data,semi) SmartTags("Lesen Tag Sorte 1") = splitdata(1) 'Close the file - Datei wird geschlossen fo.Close 'Release the Object - Objekt wird freigegeben Set fo = Nothing
 
Klingt so, als hättest du ein CHAR/BYTE-Array als STRING deklariert oder umgekehrt, und schreibst evtl. in den String-Header.
Wie sind denn die HMI-Variablen "Speichern Sorte 1" und "Lesen Tag Sorte 1" projektiert?

Was steht denn in der csv-Datei? Also: passiert der Fehler schon beim Schreiben in die csv-Datei oder erst beim auslesen?

PS: verwende keine Leerzeichen in Variablennamen.
 
Zuletzt bearbeitet:
Beide sind als String(Länge 22) deklariert. Bei der CPU handelt es sich um eine CPU314. DIe SPeichervariable ist auch dort als String[22] deklariert.

Ob es schon beim Schreiben passiert, muss ich später mal prüfen. Kann ich erst heute Abend was zu sagen.

PS: verwende keine Leerzeichen in Variablennamen.
Warum?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Oben hast Du String(20) geschrieben. Meinst Du den Speicherbereich? Ein 20er String braucht 22 Byte Speicher. Wie PN/DP schon sagte, sind die ersten beiden Byte für die maximale Länge und die aktuelle Länge. Die musst Du mit den entsprechenden numerischen Werten füllen. Der eigentliche Text geht dann ab dem dritten Byte los.
 
PS: verwende keine Leerzeichen in Variablennamen.
Warum?
Leerzeichen und Schlüsselzeichen in Variablennamen zuzulassen, ist generell ein Witz. Schau dir mal andere Programmiersprachen an. Minus oder Leerzeichen in den Variablennamen gibts NIRGENDS.
Hör mit dem Unsinn auf und beschwer dich nicht über die unnötige Gutmütigkeit von TIA Portal. Dass Siemens den Mist überhaupt zulässt ist imho der Tatsache geschuldet, dass das in Classic stellenweise auch schon ging und, hätte man dem einen Riegel vorgeschoben, man alte Programme nicht einfach hochkonvertieren könnte.

Es ist String[22] und nicht [20]. Heißt ich würde nicht ab DB50.DBX0.0 speichern, sondern FB50.DBX2.0?
Schau dir in der TIA Hilfe den Aufbau des Datentyps STRING an. Die eigentlichen Zeichen in einem String liegen ab dem dritten Byte (bei dir also ab DBX2.0). Die ersten beiden Bytes enthalten den String-Header mit der maximalen und der tatsächlichen Länge des Strings.

Nochmal meine Frage:
Wie sind denn die HMI-Variablen "Speichern Sorte 1" und "Lesen Tag Sorte 1" projektiert?
 
Das sieht eigentlich gut und richtig aus, wenn deine Strings in den DBs in der PLC wirklich bei DB50.DBX1680.0 und DB51.DBX1288.0 beginnen.
Kannst Du die HMI-Variablen auch symbolisch an die PLC-Variablen anbinden? Oder sind die PLC und das HMI in verschiedenen Projekten?
Wenn man die HMI-Variablen an die PLC-Variablen anbindet, dann kann man schon mal bei der Adresse und beim Datentyp keine Fehler machen.

Hast Du mal das HMI komplett übersetzt (Übersetzen > Software (komplett übersetzen) ) und geladen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Da es eine 300er CPU ist, kann ich es nicht symbolisch anbinden. Ich habe das gleiche mit einer 1500er CPU gemacht und da habe ich das Problem nicht.
Der Fehler ist schon beim Schreiben. Ich habe gerade die CSV Datei aufgemacht.
 
Da es eine 300er CPU ist, kann ich es nicht symbolisch anbinden.
Warum nicht?
Zeige uns mal bitte ein Bild von den DB 50 und 51, wo man die Deklaration der beiden PLC-Variablen sieht.

Eigentlich solltest Du die beiden Variablen auch selber vom HMI zur PLC zurückverfolgen und kontrollieren und zur Kontrolle in der PLC beobachten können, ohne daß wir dir hier jede Einzelheit durch mehrmaliges Nachfragen aus der Nase ziehen...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie kann ich denn die 300er Variablen symbolisch anbinden? Die Zugriffsart steht auf Absolut und ist ausgegraut. Egal ob ich es reinziehe oder so definiere.
Die 300er ist im Simatic Manager programmiert

Ja ... weil du die Variable falsch angebunden hast ... (wie schon 2 bis 3mal geschrieben ...)
Das ist nicht das Problem. Habe ich auch schon ab Byte 2 versucht (DB50.DBX1682.0).

Ich habe mal die Variable als String und Array[0..21] of Char programmiert und beide jeweils im Ausgabefeld dargestellt. Im String lässt er die ersten beiden Zeichen weg und als Array nicht.
 
Ich habe mal die Variable als String und Array[0..21] of Char programmiert ...
Das ist korrekt, wenn die Strings maximal 20 Zeichen Text enthalten sollen.
Im String lässt er die ersten beiden Zeichen weg und als Array nicht.
Im String lässt Siemens die beiden ersten Zeichen nicht weg, sondern intepretiert sie nicht als Text und zeigt sie somit auch nicht als Text an, sondern interpretiert sie als maximale und als tatsächlich benutzte Anzahl TextZeichen.
Im Siemens-DatenTyp STRING beginnt der Text erst im dritten Byte - im Rest der Welt beginnt der DatenTyp STRING mit dem ersten TextZeichen.
Fehlen im SIEMENS-String in den ersten beiden Bytes oder in einem der ersten beiden Bytes die LängenAngaben oder steht dort von vorher noch immer irgendein Schrott, so macht dies Probleme.
Gibt man bei einem SIEMENS-String als AnfangsAdresse nicht die Position "zwei Byte vor dem eigentlichen Text" an, so macht dies ebenfalls Probleme.
Die SIEMENS-StringBefehle (z.B. die Konvertierungen in STRING oder aus STRING) wissen das und berücksichtigen dies automatisch.
Probleme entstehen meistens erst dadurch, dass man sich als Programmierer zuviele Gedanken darüber macht und deshalb dazu neigt, überflüssige Massnahmen und somit ÜberKompensationen einzubauen.
Oder man vergisst, eine vernünftige Basis/Grundlage/Vorbesetzung zu schaffen, mit der die SIEMENS-StringBefehle dann problemlos weiter arbeiten können.

PS:
Für SIEMENS-WSTRING gilt sinngemäss dasgleiche, ABER für Worte statt für Bytes!
Nicht nur für jedes Zeichen des Textes wird ein Wort belegt, sondern auch für jede der beiden LängenAngaben vor dem eigentlichen Text.
 
Zuletzt bearbeitet:
Zurück
Oben