TIA WinCC Advanced V17/V18 mit VB - Script csv-Datei einlesen

S_Toben

Level-2
Beiträge
16
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich bin gerade dabei mit VB - Script in WinCC Advanced einzuarbeiten. Meine Aufgabe ist folgende:
Der Kunde arbeitet ausschließlich mit einer Exceltabelle. Ich speichere die Excel-Datei als csv-Datei.
Die Excelltabelle besteht aus ca. 1200 Produkte (Zeilen) mit 12 Datenelemente (Spalten).
Die CSV - Datei wird mit einem USB -Stick mir zur Verfügung gestellt. Die Datei wird einmalig eingelesen
und nach Änderung der Excel-Datei wieder eingelsesn.

Meine Hardware:
- CPU 1515-2 PN
- WinCC Advanced Runtime V17
- Simatic IPC 477E

Hier ein Auszug der csv-Datei:

SAP;Bez;Flaschentyp;Verschlusstyp;Karton;Flaschen/Karton;Pulpentyp;UN Nummer;Hazard Class;Sub Risk 1;Limited Quantity(ADR);Produktetikett
10095011;LUMILUX DISP. RED CD 974 1,00KG 1PBT;1 L Plastik;Leichtverschluss;61430;6;;;;;;QB
10095013;LUMILUX DIS. YELLOW CD 997-1PBT;1 L Plastik;Leichtverschluss;61430;6;;;;;;QB
10184608;F32028 Fluoride Buffersol.DEV D41,00LPE;1 L Plastik;Leichtverschluss;61430;6;;;;;;QB
10184701;F37855 HYDRANAL-LIPOSOLVER CM 1,00LFL;1 L Glas;Glocke;60631;6;74107;UN1992;3;6_1;LQ;QB +
10184702;F37856 HYDRANAL-LIPOSOLVER MH 1,00LFL;1 L Glas;Glocke;60631;6;74107;UN1230;3;6_1;LQ;QB +
10184710;F37863 HYDRANAL-CHLOROFORM 1,00LFL;1 L Glas;Leichtverschluss;60631;6;74107;UN1888;6_1;;LQ;QB +
10184714;F37866 HYDRANAL-XYLENE 1,00LFL;1 L Glas;Leichtverschluss;60631;6;74107;UN1307;3;;LQ;QB +
10184772;F38214 10M Sodium hydroxide FIX 1,00SPE;1 L Plastik;Glocke;61430;6;;UN1824;8;;LQ;QB
10184791;F38283 10M Hydrochlor.ac. FIX 1,00SPE;2,5 L Plastik;Glocke;61435;4;;UN1789;8;;;QB
10185021;ETHYLENE GLYCOL 1,00LPE;1 L Plastik;Leichtverschluss;61430;6;;;;;;QB
10185022;ETHYLENE GLYCOL 2,50LPF;2,5 L Plastik;Leichtverschluss;61435;4;;;;;;QB

Meine Aufgabe besteht darin die csv-Datei einzulesen und die Daten in die SPS zu übertragen.
Dazu habe in der SPS vorbereitet den DB "dbProduktuebersicht" und die HMI-Tags "Produkt".

Mit dem VB - Script lese ich die Datei ein.

Code:
Sub VBFunktion_2()
' Read data from file()
Dim fso, f, field, MyZf, data, splitdata , test(5000,11),j
Dim n, delimiter, FileName
n=0
j=0

FileName = "D:\Produktdaten\TestCsv1.csv"
'Catch Erros -- Fehler abfangen
On Error Resume Next

'Create Opject -- Objekt erstellen
Set fso = CreateObject("Scripting.FileSystemObject")
If Err.Number <> 0 Then
    ShowSystemAlarm "Error #" & CStr(Err.Number) & "" & Err.Description
    Err.Clear
    Exit Sub
End If

Set f = fso.OpenTextFile(FileName, 1, 0, -2)
If Err.Number <> 0 Then
    ShowSystemAlarm "Error #" & CStr(Err.Number) & "" & Err.Description
    Err.Clear
    Exit Sub
End If

f.SkipLine(1) 'Zeile Ueberschriften überspringen

Do While f.AtEndOfStream <> True
       data = f.ReadLine 'Zeile einlesen   
       splitdata = Split(data, ";")
      
    For n = 0 To 10
    test(j,n)= splitdata(n)
    Next
    
    SmartTags(CDbl("SAP"))(n) = test(1,1)
    SmartTags(CStr("Bez"))(n) = test(1,2)
    SmartTags(CStr("FlaschenTyp"))(n) = test(1,3) 
    SmartTags(CStr("VerschlussTyp"))(n) = test(1,4)
    SmartTags(CDbl("KartonTyp"))(n)  = test(1,5)
    SmartTags(CDbl("FlaschenKarton"))(n) = test(1,6)
    SmartTags(CDbl("PulpenTyp"))(n) = test(1,7)
    SmartTags(CStr("UnNummer"))(n) = test(1,8)
    SmartTags(CStr("HazartClass"))(n) = test(1,9)
    SmartTags(CStr("SubRisk1"))(n) = test(1,10)
    SmartTags(CStr("LQ"))(n) = test(1,11)
    SmartTags(CStr("ProduktEtikett"))(n) = test(1,12)
    j=j+1
Loop

' Tidy up -- Aufraeumen
fso.Close
Set f = Nothing
Set fso = Nothing
ShowSystemAlarm "Readout of the data was succesfull!"
    
End Sub

Mein Problem ist, führe ich das Script aus erhalte ich die Meldung "Readout of the data was Successfull!
Wenn ich mit den "dbProduktuebersicht" DB online gehe ist kein Wert übertragen worden!

Habt Ihr eine Tipp was ich falsch gemacht habe?
 

Anhänge

  • dbProduktuebersicht.PNG
    dbProduktuebersicht.PNG
    60,9 KB · Aufrufe: 32
  • HMI Tags.PNG
    HMI Tags.PNG
    99,8 KB · Aufrufe: 32
  • DB online.PNG
    DB online.PNG
    116,2 KB · Aufrufe: 34
Deaktiviere das "On Error Resume Next" (auskommentieren) und schau, wo Dein Skript wegen Runtime-Error "gekillt" (abgebrochen) wird. Ich schätze mal, irgendwo im Zusammenhang mit Split()

Weil Dein Skript bei der Fehlerbehandlung "If Err.Number <> 0 ..." eh' nur die Fehlernummer und -Beschreibung ausgibt und das Skript beendet, kannst Du die Fehlerbehandlung auch ganz weglassen und "On Error Resume Next" löschen. Dann wird das Skript bei von Dir nicht behandelten Runtime-Errors wenigstens mit mehr oder weniger aussagekräftiger Systemfehlermeldung abgebrochen.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Harald,
ersteinmal Vielen Dank für die schnelle Antwort. Ich habe "On Error Resume Next" auskommentiert.

Jetzt bekomme ich andere Fehlermeldungen.

1. Error Falsche anzahl an Argumenten oder ungültige Eigenschaftszuweisung: 'f.SkipLine' in Zeile 27
 
Die Funktion Skipline kannte ich bislang noch gar nicht.
Wenn ich so etwas benötigt habe dann habe ich immer die Zeile in einen Hilfsstring eingelesen, der dann nicht mehr weiter bearbeitet wird - also z.B. so :
Code:
z = f.Readline
 
Die SkipLine-Methode hat keine Argumente - daher darf auch kein Argument übergeben werden.
Das muß bei Dir so: f.SkipLine 'Zeile Ueberschriften überspringen

Gibt es in TIA V17 endlich eine VBS-Dokumentation/Hilfe? Oder hast Du auch WinCC flexible? In WinCC flexible ist eine VBS-Hilfe/Referenz vorzüglich integriert.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ansonsten solltest du in dem Block :
Code:
    SmartTags(CDbl("SAP"))(n) = test(1,1)
    SmartTags(CStr("Bez"))(n) = test(1,2)
    SmartTags(CStr("FlaschenTyp"))(n) = test(1,3)
    SmartTags(CStr("VerschlussTyp"))(n) = test(1,4)
    SmartTags(CDbl("KartonTyp"))(n)  = test(1,5)
    SmartTags(CDbl("FlaschenKarton"))(n) = test(1,6)
    SmartTags(CDbl("PulpenTyp"))(n) = test(1,7)
    SmartTags(CStr("UnNummer"))(n) = test(1,8)
    SmartTags(CStr("HazartClass"))(n) = test(1,9)
    SmartTags(CStr("SubRisk1"))(n) = test(1,10)
    SmartTags(CStr("LQ"))(n) = test(1,11)
    SmartTags(CStr("ProduktEtikett"))(n) = test(1,12)
... statt der 1 dann auch mit j arbeiten - sonst überträgst du ja immer nur die erste Zeile, die dafür dann aber in jedem Schleifendurchlauf ...
 
... und Du verwendest test(1,11) und test(1,12), weist denen aber nie einen Wert zu. test(1,12) wird es auch nie geben, weil der zweite Index nur von 0 bis 11 geht (nicht 1 bis 12!)

Vor und nach dem Split() lauern die nächsten Fallen:
- Split() darf nicht mit einer leeren Zeile aufgerufen werden ( If data = "" Then 'Sonderbehandlung leere Zeile )
- nach dem Split() muß mit If UBound(splitdata) >= 11 Then geprüft werden, ob auch mindestens (oder exakt) 12 Werte in der Zeile enthalten waren, bevor auf splitdata(n) zugegriffen wird
- je nach Datentyp der SmartTags("...") kann es auch Probleme geben, wenn der zugehörige Wert in der Zeile fehlt, also mehrere Semikolon aufeinanderfolgen

Harald
 
Und die Schreibweise der CDbl und CStr und der Indizes bei den "SmartTags(CDbl("SAP"))(n) = test(1,1)" ist total falsch, das müsste so:
Code:
    SmartTags("SAP")(j) = CDbl(test(j,0))
    ...
    SmartTags("ProduktEtikett")(j) = CStr(test(j,11))

Harald
 
Hallo,
ich habe Eure Tipps und anregungen getestet.
@ Harald
Das Script habe jetzt so angepasst:

Code:
Sub VBFunktion_2()
' Read data from file()
Dim fso, f, field, MyZf, data, splitdata , test(5000,11), j
Dim n, delimiter, FileName,Bez
n=0
j=0

FileName = "D:\Produktdaten\TestCsv1.csv"
'Catch Erros -- Fehler abfangen
'On Error Resume Next

'Create Opject -- Objekt erstellen
Set fso = CreateObject("Scripting.FileSystemObject")
If Err.Number <> 0 Then
    ShowSystemAlarm "Error #" & CStr(Err.Number) & "" & Err.Description
    Err.Clear
    Exit Sub
End If

Set f = fso.OpenTextFile(FileName, 1, 0, -2)
If Err.Number <> 0 Then
    ShowSystemAlarm "Error #" & CStr(Err.Number) & "" & Err.Description
    Err.Clear
    Exit Sub
End If

f.SkipLine 'Zeile Ueberschriften überspringen

Do While f.AtEndOfStream <> True
       data = f.ReadLine 'Zeile einlesen   
       splitdata = Split(data, ";")
       If UBound(splitdata) >= 11 Then       
        For n = 0 To 10
              test(j,n)= splitdata(n)
    
              SmartTags("SAP")(j) = CDbl(test(j,0))
              SmartTags("Bez")(j)=CStr(test(j,n))
              SmartTags("FlaschenTyp")(j) = CStr(test(j,2)) 
              SmartTags("VerschlussTyp")(j) = CStr(test(j,3))
              SmartTags("KartonTyp")(j)  = test(j,4)
              SmartTags("FlaschenKarton")(j) = test(j,5)
              SmartTags("PulpenTyp")(j) = test(j,6)
              SmartTags("UnNummer")(j) = CStr(test(j,7))
              SmartTags("HazartClass")(j) = test(j,8)
              SmartTags("SubRisk1")(j) = test(j,9)
              SmartTags("LQ")(j) = test(j,10)
              SmartTags("ProduktEtikett")(j) = test(j,11)
              j=j+1
        Next
    End If       
Loop

' Tidy up -- Aufraeumen
fso.Close
Set f = Nothing
Set fso = Nothing
ShowSystemAlarm "Readout of the data was succesfull!"
    


End Sub

Ich bekomme jetzt folgende Fehlermeldung:

SmartTags: Ungültige Array-Verwendung -> Das nur bei den Stringvariablen
 

Anhänge

  • Error.PNG
    Error.PNG
    13,2 KB · Aufrufe: 12
was mir aufgefallen ist :
Code:
SmartTags("Bez")(j)=CStr(test(j,n))
das sollte doch sicher eher so heißen :
Code:
SmartTags("Bez")(j)=CStr(test(j,1))
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dann sind die HMI-Variablen vermutlich nicht als Array projektiert?
Wie sind die HMI-Variablen projektiert?

PS:
SmartTags: Ungültige Array-Verwendung -> Das nur bei den Stringvariablen
"bei den Stringvariablen" meinst Du bei allen Stringvariablen oder nur bei dieser Zeile:
SmartTags("Bez")(j)=CStr(test(j,n))
?
 
Man kann doch Stringvariablen gar nicht als HMI-Arrays deklarieren ... oder hat sich da mittlerweile etwas geändert ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sieht so aus, als ob die HMI-Variablen tatsächlich als Arrays projektiert sind.
Von der "Logik" her hätte ich da in der SPS nur ungern 12 einzelne Arrays [1..11] of String deklariert, sondern ein Array [0..10] of Struct (Datensätze) - doch das kann (glaube ich) das WinCC nicht abbilden?

Weiteres Problem: jeder Schreibzugriff auf ein SmartTags-Array löst das schreiben des ganzen Arrays aus - jedes der 12 Arrays wird also 11 mal komplett in die SPS geschrieben. Die Arrays würde ich zuerst komplett im Skript zusammenbauen und erst danach nur einmal in die SPS schreiben. Vielleicht habe ich nachmittags Zeit für ein Codebeispiel...

Nochwas beachten: das lesen der csv-Datei muß kontrolliert werden, daß höchstens 11 Zeilen gelesen werden, und nicht im Blindflug bis zum Dateiende (f.AtEndOfStream).
Und drüber nachdenken und entscheiden, was soll passieren, wenn die csv-Datei nicht exakt 11 Zeilen mit genau 12 Werten enthält? Da würde ich die gesamte Datei abweisen und nichts in die SPS übernehmen.

Und nochmal meine Frage:
SmartTags: Ungültige Array-Verwendung -> Das nur bei den Stringvariablen
"bei den Stringvariablen" meinst Du bei allen Stringvariablen oder nur bei dieser Zeile:
SmartTags("Bez")(j)=CStr(test(j,n))
?
bitte noch beantworten

Harald
 
Das j=j+1 steht an der falschen Stelle. Es darf nicht in der For-Schleife stehen, sondern erst danach direkt vor dem Loop
 
Hallo Harald,
das war ein Schreibfehler,
SmartTags("Bez")(j)=CStr(test(j,n)) -> SmartTags("Bez")(j)=CStr(test(j,0)) usw.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, das war klar.
Meine Frage zum driten Mal: Erhältst Du den Runtime-Error bei jeder String-Variable oder war das nur bei der Zeile mit dem Schreibfehler?

Und Deine For-Schleife "For n = 0 To 10" ist auch falsch. Das muß "For n = 0 To 11" heißen. Zählen ab 0 ist ziemlich kompliziert ;)

Harald
 
arbeite doch spaßeshalber mal mit einem in der Methode deklarierten Array an der Stelle - einfach um sicher zu stellen, dass wir da etwas übersehen - also ggf so :
Code:
dim mySap(10), myBez(10), myFlaschentyp(10), myVeschlusstyp(10), usw.

Do While f.AtEndOfStream <> True
       data = f.ReadLine 'Zeile einlesen  
       splitdata = Split(data, ";")
       If UBound(splitdata) >= 11 Then      
        For n = 0 To 10
              test(j,n)= splitdata(n)
   
              mySap(j) = CDbl(test(j,0))
              myBez(j)=CStr(test(j,1))
              myFlaschentyp(j) = CStr(test(j,2))
              myVeschlusstyp(j) = CStr(test(j,3))
              myKartonTyp(j)  = test(j,4)
              myFlaschenKarton(j) = test(j,5)
              myPulpenTyp(j) = test(j,6)
              myUnNummer(j) = CStr(test(j,7))
              myHazartClass(j) = test(j,8)
              mySubRisk1(j) = test(j,9)
              myLQ(j) = test(j,10)
              myProduktEtikett(j) = test(j,11)
        Next
    End If      
Loop
 
Zurück
Oben