WinCC Datenspeicherung auf Server über HMI-Panel

KSEHJ

Level-1
Beiträge
9
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
Ich soll gerade ein Bestandsprojekt erweitern. Momentan werden Produktionsdaten in einem .txt - File abgelegt. Das File heißt "Ergebnisdaten" und wird erstellt, wenn es nicht existiert.
Nun soll das .txt - File das variable Datum des Datensatzes tragen. Das Datum steht in einem DB und ist in die HMI verlinkt (SmartTags("DB_TP900_Daten_Speichern_Datum")).
Wie könnte ich den Smarttag in den Dateinamen (path="\\NAS-FGS\Produktionsdatenspeicherung\Ergebnisdaten.txt") einfügen, damit das variabel an- bzw. abgelegt wird?
Des weiteren möchte ich die Rückmeldung abfragen, ob die Daten erfolgreich abgelegt wurden. Gibt es im VB-Skript eine Möglichkeit das abzufragen?
Ich benutze ein TP900 Comfort panel und arbeite mit TIA WinCC Advanced V14 SP1.
Vielleicht kennt sich jemand damit aus :).
Hier der VB-script Code, der bisher läuft:




'Tip:
' 1. Use the <CTRL+SPACE> or <CTRL+I> shortcut to open a list of all objects and functions
' 2. Write the code using the HMI Runtime object.
' Example: HmiRuntime.Screens("Screen_1").
' 3. Use the <CTRL+J> shortcut to create an object reference.
'Write the code as of this position:

Dim trigger
Dim Datum
Dim path
Dim delimeter
Dim fo
Dim mode

Datum="04.11.2019"
'path="\\NAS-FGS\Produktionsdaten\Ergebnisdaten.txt"
'path="\\NAS-FGS\data\Ergebnisdaten.txt"
path="\\NAS-FGS\Produktionsdatenspeicherung\Ergebnisdaten.txt"
delimeter=";"
mode=8

Set fo= CreateObject("FileCtl.File")

fo.open path,mode

If SmartTags("DB_TP900_Daten_Speichern_TriggerSchreiben") = True Then
If fo.LOF = 0 Then
fo.LinePrint(" Datum //Ignore// Zeit " & delimeter & " Kennnummer " & delimeter & " IO/NIO " & delimeter & " DMC Links " & delimeter & " DMC Rechts " & delimeter ) 'make the header on txt file
End If

fo.LinePrint(SmartTags("DB_TP900_Daten_Speichern_Datum") & " " & SmartTags("DB_TP900_Daten_Speichern_Uhrzeit") & " " & delimeter & " " & DB_TP900_Daten_Speichern_KennNummer & delimeter & " " & DB_TP900_Daten_Speichern_IO & " " & delimeter & " " & DB_TP900_Daten_Speichern_DMC_LI & delimeter & " " & DB_TP900_Daten_Speichern_DMC_RE & delimeter) 'make the data on txt file

fo.Close
End If

Set fo = Nothing
 
Nun soll das .txt - File das variable Datum des Datensatzes tragen. Das Datum steht in einem DB und ist in die HMI verlinkt (SmartTags("DB_TP900_Daten_Speichern_Datum")).
Wie könnte ich den Smarttag in den Dateinamen (path="\\NAS-FGS\Produktionsdatenspeicherung\Ergebnisdaten.txt") einfügen, damit das variabel an- bzw. abgelegt wird?
siehe Datenausgabe per USB als CSV Datei

Des weiteren möchte ich die Rückmeldung abfragen, ob die Daten erfolgreich abgelegt wurden. Gibt es im VB-Skript eine Möglichkeit das abzufragen?
Was meinst Du damit?
Gibt es einen Grund für die Frage? Kann es sein, daß manchmal falsche Werte in den Dateien stehen? Wenn die Werte der SmartTags nicht per Handshake aus der SPS ins HMI eingelesen werden dann gibt es Probleme mit der Aktualisierung der Variablenwerte und es können falsche Werte in die Dateien geschrieben werden. Das ist ein generelles Problem was man z.B. mit Lesen als Rezepturen sicher lösen kann.

Du könntest nach allen VBS-Anweisungen, wo Fehler passieren können, abfragen ob ein Fehler aufgetreten ist: If Err.Number <> 0 Then ...
Du könntest die Datei mit einigen Sekunden Abstand zweimal erstellen und danach die beiden Dateien vergleichen.


PS: Du könntest den TIA-Müll für VBS-Anfänger am Anfang des Skriptes löschen... der hat mit der Funktion des Skriptes überhaupt nichts zu tun...

Harald
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Harald,
Danke für die Antworten. Leider sind damit nicht alle meine Fragen beantwortet.
Ich habe meinen Code mal entsprechend angepasst:

Sub Daten_speichern_Server()
Dim trigger
Dim Datum, s, t
Dim path
Dim delimeter
Dim fo
Dim mode
Dim datawrite

'Datenstring für Dateinamen zusammenstellen
Datum = (SmartTags("DB_TP900_Daten_Speichern_Datum")
s = DatePart("yyyy", Datum) & Right("0" & DatePart("m", Datum), 2) & Right("0" & DatePart("d", Datum), 2)


path="\\NAS-FGS\Produktionsdatenspeicherung\Ergebnisdaten&"s".txt"
delimeter=";"
mode=8

Set fo= CreateObject("FileCtl.File")

fo.open path,mode

If SmartTags("DB_TP900_Daten_Speichern_TriggerSchreiben") = True Then
If fo.LOF = 0 Then
fo.LinePrint(" Datum //Ignore// Zeit " & delimeter & " Kennnummer " & delimeter & " IO/NIO " & delimeter & " DMC Links " & delimeter & " DMC Rechts " & delimeter ) 'make the header on txt file
End If

fo.LinePrint(SmartTags("DB_TP900_Daten_Speichern_Datum") & " " & SmartTags("DB_TP900_Daten_Speichern_Uhrzeit") & " " & delimeter & " " & DB_TP900_Daten_Speichern_KennNummer & delimeter & " " & DB_TP900_Daten_Speichern_IO & " " & delimeter & " " & DB_TP900_Daten_Speichern_DMC_LI & delimeter & " " & DB_TP900_Daten_Speichern_DMC_RE & delimeter) 'make the data on txt file
If Err.Number == 0 Then
datawrite = True 'smarttag für erfolgreiches Schreiben einfügen
End If
fo.Close
End If

Set fo = Nothing

In Zeile 11+12 bastle ich den Datenstring zusammen. Da habe ich Hoffnung das es so funktioniert.
In Zeile 15 möchte ich die Variable "s" in den Dateinamen einfügen. Das Zeigt mir TIA aber noch als Fehler. Hier habe ich die passende Syntax noch nicht verstanden. Kannst du mir vielleicht noch den passenden Hinweis geben?
In Zeile 29+30+31 schreibe ich die Ergebnisdaten auf den Datenträger weg. Wenn dies nicht gelingt (weil z.B. die Verbindung unterbrochen ist), soll keine Rückmeldung für erfolgreiches Schreiben an die SPS zurückgegeben werden.

Die Daten stehen immer richtig in den Dateien. Es ging mir um die Rückmeldung des Schreibens auf den Datenträger, nicht die Kommunikation SPS <-> HMI

Noch eine Erklärung zum Aufbau. Die SPS speichert Produktionsdaten in einem Ringspeicher. Von dem Ringspeicher werden die Daten auf den Server geschrieben. Und zwar ein ein .txt - File mit dem Datum der Produktions(Smarttag), nicht der aktuellen Systemzeit (wichtig bei einem Verbindungsausfall). Bei erfolgreichem Schreiben der Daten (deshalb die Rückmeldung) wird der Zeiger der Schreibdaten im Ringdatenspeicher weitergeschoben, sonst nicht (sonst würden ja Daten verloren gehen).

Es ist noch ein weiteres (kleines) Problem aufgetaucht. Die Daten werden so abgelegt:

Datum // Ignore // Zeit ; Kennnummer ; IO/NIO ; DMC Links ; DMC Rechts ;
31.12.2019 01.01.1990 10:50:18 ; 12345 ; 1 ; ; ;

Das Datum und die Zeit stimmen soweit. Kennnummer und alle Daten auch. Mein Problem ist der "01.01.1990", das unter dem // Ignore // steht. Ich verstehe nicht, warum dieses Datum geschrieben wird. Die entsprechende Codezeile ist ja diese:
fo.LinePrint(SmartTags("DB_TP900_Daten_Speichern_Datum") & " " & SmartTags("DB_TP900_Daten_Speichern_Uhrzeit") & " " & delimeter & " " & DB_TP900_Daten_Speichern_KennNummer & delimeter & " " & DB_TP900_Daten_Speichern_IO & " " & delimeter & " " & DB_TP900_Daten_Speichern_DMC_LI & delimeter & " " & DB_TP900_Daten_Speichern_DMC_RE & delimeter) 'make the data on txt file

Wie gesagt, das ist ein kleines Problem. Wir so akzeptiert. Aber schön ist es halt nicht...

Für mich ist die Umsetzung des Projektes etwas schwierig, da ich alles nur "offline" vorbereiten kann. Die Umsetzung erfolgt dann natürlich an der Anlage unter Zeitdruck. Deshalb würde es mir echt helfen, wenn mir ein "alter Hase" hier Rückmeldung geben könnte, ob das Abspeichern mit Datum aus dem Smarttag im Dateinamen so funktionieren könnte bzw. wie ich den Code entsprechend anpassen müsste (Zeilen 11-15) und ob die Abfrage des erfolgreichen Schreibens auf den Server (Zeile 29-31) so umgesetzt werden kann.
 
Zuletzt bearbeitet:
Welchen Datentyp hat die HMI-Variable (und die zugehörige PLC-Variable) "DB_TP900_Daten_Speichern_Uhrzeit"? Da lässt sich das VBS verleiten, den WinCC-Datentyp automatisch in das komplette VBS-DateTime-Format inkl. Datum zu konvertieren. Um keine Überraschungen zu erleben, sollte man Datum/Uhrzeit-Strings immer komplett selbständig formatieren.
Übrigens: Trennzeichen (delimiter) gehören nur zwischen Werte, aber nicht ans Zeilenende
Code:
[COLOR="#008000"]'Sub Daten_speichern_Server()[/COLOR]
Const ForAppending = 8
Dim d, t
Dim path
Dim delimiter
Dim fo
Dim datawrite

On Error Resume Next

[COLOR="#008000"]'Datums-String für Dateiname zusammenstellen[/COLOR]
d = SmartTags("DB_TP900_Daten_Speichern_Datum")
d = Year(d) & Right("0" & Month(d), 2) & Right("0" & Day(d), 2)

path = "\\NAS-FGS\Produktionsdatenspeicherung\Ergebnisdaten_" & d & ".txt"
delimiter = ";"

Set fo = CreateObject("FileCtl.File")

fo.open path, ForAppending

If SmartTags("DB_TP900_Daten_Speichern_TriggerSchreiben") = True Then

    [COLOR="#008000"]'make header line on txt file[/COLOR]
    If fo.LOF = 0 Then  [COLOR="#008000"]'filesize is 0! New file --> write header[/COLOR]
        fo.LinePrint "  Datum      Zeit   " & delimiter & "  Kennnummer   " & delimiter & "  IO/NIO    " & delimiter _
                     & "  DMC Links                " & delimiter & "  DMC Rechts               "
    End If

    [COLOR="#008000"]'make data line on txt file[/COLOR]
    d = SmartTags("DB_TP900_Daten_Speichern_Datum")
    d = Right("0" & Day(d), 2) & "." & Right("0" & Month(d), 2) & "." & Year(d)

    t = SmartTags("DB_TP900_Daten_Speichern_Uhrzeit")
    t = Right("0" & Hour(t), 2) & ":" & Right("0" & Minute(t), 2) & ":" & Right("0" & Second(t), 2)

    fo.LinePrint d & " " & t & " " & delimiter _
                 & "   " & SmartTags("DB_TP900_Daten_Speichern_KennNummer") & delimiter _
                 & "  " & SmartTags("DB_TP900_Daten_Speichern_IO") & "         " & delimiter _
                 & "   " & SmartTags("DB_TP900_Daten_Speichern_DMC_LI") & delimiter _
                 & "   " & SmartTags("DB_TP900_Daten_Speichern_DMC_RE")
    fo.Close

    If Err.Number == 0 Then
        datawrite = True [COLOR="#008000"]'smarttag für erfolgreiches Schreiben einfügen[/COLOR]
    End If
End If

Set fo = Nothing

Harald
 
Was mir beim Überfliegen so ins Auge gesprungen ist:
Code:
    If Err.Number [B][COLOR=#ff0000]==[/COLOR][/B] 0 Then
        datawrite = True 'smarttag für erfolgreiches Schreiben einfügen
    End If
Das "DoppelGleich" erinnert an S7 AWL, dürfte aber von VB & Co bemeckert werden. ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das "DoppelGleich" erinnert an S7 AWL, dürfte aber von VB & Co bemeckert werden. ;)
Hast recht, diesen einfachen Fehler hab' ich ihm drin gelassen, damit TIA auch noch was zu tun hat ;) Ich hätte den Code wohl doch mal in TIA eingeben sollen ...

Irgendwie scheint sein originaler Code nicht wirklich aus TIA kopiert zu sein, weil da noch mehr Fehler drin sind, mit denen das Skript gar nicht gelaufen sein kann (z.B. 2 Syntaxfehler in Zeile 11 + 12).

Harald
 
Hallo Harald,
Besten Dank für die Hilfe :D.

Welchen Datentyp hat die HMI-Variable (und die zugehörige PLC-Variable) "DB_TP900_Daten_Speichern_Uhrzeit"? Da lässt sich das VBS verleiten, den WinCC-Datentyp automatisch in das komplette VBS-DateTime-Format inkl. Datum zu konvertieren. Um keine Überraschungen zu erleben, sollte man Datum/Uhrzeit-Strings immer komplett selbständig formatieren.
Übrigens: Trennzeichen (delimiter) gehören nur zwischen Werte, aber nicht ans Zeilenende
Harald

Der Datentyp ist Datum (bzw. Date). 2Byte.

Ich habe noch nicht verstanden, warum die die Variablen d und t immer in 2 aufeinanderfolgenden Zeilen beschreibst. Sind das 2 Möglichkeiten, die beide zum gleichen Ergebnis führen? Bei der unteren Variante kann man jeweils die Anordnung der einzelnen Daten selbst bestimmen?

Beste Grüße
Hansjörg
 
Hast recht, diesen einfachen Fehler hab' ich ihm drin gelassen, damit TIA auch noch was zu tun hat ;) Ich hätte den Code wohl doch mal in TIA eingeben sollen ...

Irgendwie scheint sein originaler Code nicht wirklich aus TIA kopiert zu sein, weil da noch mehr Fehler drin sind, mit denen das Skript gar nicht gelaufen sein kann (z.B. 2 Syntaxfehler in Zeile 11 + 12).

Harald

Der originale Code lief in TIA. Den habe ich hier aber nicht gepostet. Ich habe den erweiterten Code hier gepostet, damit mögliche Helfer eine bessere Idee bekommen, wo ich hin möchte. Nochmal vielen Dank an alle :D
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Welchen Datentyp hat die HMI-Variable (und die zugehörige PLC-Variable) "DB_TP900_Daten_Speichern_Uhrzeit"? (...)
Der Datentyp ist Datum (bzw. Date). 2Byte.
:confused: Wie kann VBS da eine Uhrzeit rauslesen? Hast Du Dich verguckt? Kann es sein daß es tatsächlich ein Date_And_Time ist?


Ich habe noch nicht verstanden, warum die die Variablen d und t immer in 2 aufeinanderfolgenden Zeilen beschreibst. Sind das 2 Möglichkeiten, die beide zum gleichen Ergebnis führen?
Nein, es müssen immer beide Codezeilen ausgeführt werden, so wie es da steht. Die Verwendung von zweimal die gleiche Variable bei der Zuweisung ist einfach dafür, daß ich mir weniger Variablennamen ausdenken muß. :cool: Bei VBS kann sich der Datentyp der Zielvariablen bei jeder Zuweisung ändern, daher kann man auch einer Variable zuerst ein Date zuweisen und danach einen String, und danach noch ganz was anderes wenn man will.
Bei der ersten Zuweisung an d oder t sollte der Variablenname möglichst kurz sein, weil die Variable danach noch mehrmals verwendet wird. Bei der zweiten Zuweisung hätte ich mir nun einen weiteren Variablenname ausdenken können, oder einfach die selbe Variable wiederverwenden, weil deren erster Inhalt danach nicht mehr gebraucht wird.

Harald
 
:confused: Wie kann VBS da eine Uhrzeit rauslesen? Hast Du Dich verguckt? Kann es sein daß es tatsächlich ein Date_And_Time ist?



Nein, es müssen immer beide Codezeilen ausgeführt werden, so wie es da steht. Die Verwendung von zweimal die gleiche Variable bei der Zuweisung ist einfach dafür, daß ich mir weniger Variablennamen ausdenken muß. :cool: Bei VBS kann sich der Datentyp der Zielvariablen bei jeder Zuweisung ändern, daher kann man auch einer Variable zuerst ein Date zuweisen und danach einen String, und danach noch ganz was anderes wenn man will.
Bei der ersten Zuweisung an d oder t sollte der Variablenname möglichst kurz sein, weil die Variable danach noch mehrmals verwendet wird. Bei der zweiten Zuweisung hätte ich mir nun einen weiteren Variablenname ausdenken können, oder einfach die selbe Variable wiederverwenden, weil deren erster Inhalt danach nicht mehr gebraucht wird.

Harald

Wer lesen kann ist klar im Vorteil.
"DB_TP900_Daten_Speichern_Uhrzeit" ist vom Format Time_Of_Day
"DB_TP900_Daten_Speichern_Datum" ist Date

Danke für die Erklärung mit den Variablen. Könnte man den Code dann auch so schreiben?:
d = Year(SmartTags("DB_TP900_Daten_Speichern_Datum")) & Right("0" & Month(SmartTags("DB_TP900_Daten_Speichern_Datum")), 2) & Right("0" & Day(SmartTags("DB_TP900_Daten_Speichern_Datum")), 2)
 
Danke für die Erklärung mit den Variablen. Könnte man den Code dann auch so schreiben?:
d = Year(SmartTags("DB_TP900_Daten_Speichern_Datum")) & Right("0" & Month(SmartTags("DB_TP900_Daten_Speichern_Datum")), 2) & Right("0" & Day(SmartTags("DB_TP900_Daten_Speichern_Datum")), 2)
Kann man. Meinst Du, das wäre leichter lesbar/verstehbar als "d = Year(d) & Right("0" & Month(d), 2) & Right("0" & Day(d), 2)" ?
Außerdem ist der Code vermutlich auch langsamer als meine Variante: mehr Text zu parsen und Zugriffe auf globale HMI-Variablen (SmartTags) anstatt Skript-interne Variablen.

Kompromiss-Vorschlag:
Code:
d = SmartTags("DB_TP900_Daten_Speichern_Datum")
Datum = Year(d) & Right("0" & Month(d), 2) & Right("0" & Day(d), 2)

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kann man. Meinst Du, das wäre leichter lesbar/verstehbar als "d = Year(d) & Right("0" & Month(d), 2) & Right("0" & Day(d), 2)" ?
Außerdem ist der Code vermutlich auch langsamer als meine Variante: mehr Text zu parsen und Zugriffe auf globale HMI-Variablen (SmartTags) anstatt Skript-interne Variablen.

Kompromiss-Vorschlag:
Code:
d = SmartTags("DB_TP900_Daten_Speichern_Datum")
Datum = Year(d) & Right("0" & Month(d), 2) & Right("0" & Day(d), 2)

Harald


Die Frage war nur zum Verständniss. Den Code werde ich so übernehmen. Leichter lesbar ist es sicher nicht und ich bin gerne bereit zu lernen :cool:
 
Könnte man den Code dann auch so schreiben?:
d = Year(SmartTags("DB_TP900_Daten_Speichern_Datum")) & Right("0" & Month(SmartTags("DB_TP900_Daten_Speichern_Datum")), 2) & Right("0" & Day(SmartTags("DB_TP900_Daten_Speichern_Datum")), 2)
Könnte man, aber dann ist man nicht sicher, dass bei allen drei Abfragen von SmartTags("DB_TP900_Daten_Speichern_Datum") dieselbe Info drin steht. ;)
Haralds Schreibweise ist doch ausserdem übersichtlicher.

PS:
da war wieder einer schneller und hat mich zum VizeSieger gemacht. :D
 
Zuletzt bearbeitet:
Könnte man, aber dann ist man nicht sicher, dass bei allen drei Abfragen von SmartTags("DB_TP900_Daten_Speichern_Datum") dieselbe Info drin steht. ;)
Ja, dieses Problem kommt außerdem noch dazu. Ähnlich schlimm wie der typische (Anfänger-)Fehler, daß für jeden Datumsbestandteil erneut "Now" oder "Date" oder "Time" abgefragt wird.

Manche Sachen mache ich mit > 20 Jahren Erfahrung ganz intuitiv richtig, und weiß gar nicht mehr genau warum ... ;) :D

Harald
 
Zurück
Oben