TIA TIA v16 WinCC Script: Arrays adressieren und Script zyklisch aufrufen

saarlaender

Level-1
Beiträge
94
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
TIA v16, WinCC Runtime Advanced, VB Script

Servus,

ich habe eine Array-Verschachtelung die ich via Bildbaustein-Script adressieren möchte.
Das Array sieht in etwa so aus:
Array_1[1].Array_2[1].Array_3[1]

Das letzte Array ist Array of bool, daher kommt da nichts mehr nach


Direkt adressieren geht natürlich. Aber alle Versuche, die jeweiligen Array-Indexnummern variabel zu gestalten gingen bisher schief.
Es gab zwar nie eine Meldung beim Übersetzen, aber später in der Runtime beim Script-Aufruf kommt eine Meldung "xyz no Tag ...", obwohl die Variable korrekt zusammengesetzt wurde (das wird in der Fehlermeldung mit angezeigt).


Hat jemand eine Idee, wie genau ich die verschiedenen Array-Indexnummern über Schnittstellenvariablen (Int) des Bildbausteins steuern kann?

Dazu soll das Script zyklisch aufgerufen werden. Der Trick mit der Übergabe eines Taktmerkers funktioniert nicht - das Script wird nur aufgerufen, wenn ich z.B. eine Tastenaktion verwende - nicht aber die Schnittstellenvariable auf Änderungen überwache.




### Schnittstelle Bildbaustein ###
Nummer_1: Int
Nummer_2: Int
Nummer_3: Int
Daten: UDT mit Arrays




### interne Variablen im Bildbaustein ###
Int_1: Int
Int_2: Int
BG_Taste_1: Bool (Variable für die Hintergrund-Animation zum Test - soll vom Array gelesen werden)




### Script im Bildbaustein ###
Dim Int1
Dim Int2
Dim Name

Set Int1 = SmartTags("Properties\Nummer_1")
Set Int2 = SmartTags("Properties\Nummer_2")


SmartTags("Int_1") = Int1
SmartTags("Int_2") = CInt(Int2)
Beide Varianten gehen - die Variablen Int_1 und Int_2 tragen die entsprechende Nummer die über die Schnittstelle dem Bildbaustein übergeben wird.

Folgenden Scriptteil habe ich auch ohne SmartTags versucht (dh mit Int1 und Int2 statt SmartTags("Int_1") etc.

If SmartTags("Properties\Daten.Array_1[" & SmartTags("Int_1") & "].Array_2[" & SmartTags("Int_2") & "].Array_3[0]") = True Then
SmartTags("BG_Taste_1") = True
End If
 
Zuletzt bearbeitet:
Hallo,

wird die zusammengesetzte Variable in diesem Script
das erste UND einzige Mal
verwendet?

Wenn ja, dann ist diese Variable -obwohl in der Variablentabelle angelegt- zum Zeitpunkt der Scriptbearbeitung noch nie initialisiert worden, sprich: die Variable ist unbekannt!.
Bin auch schon darauf reingefallen und musste dann eine solche Variable
ENTWEDER in einem Bild an ein Control projektieren,
ODER in einem Startscript mit vollständigem Namen aufrufen.
Erst danach konnte ich dann mit der Vareiable in der von dir versuchten Art und Weise arbeiten.


Gruß, Fred
 
Danke, das habe ich eben auch irgendwo so gelesen. Die Frage ist, welche Variable genau ich dann initialisieren muss?

Ich habe ja unzählige Variablen in dem Daten_DB durch die vielen Arrays.

Testweise habe ich eben mal jeweils Array-Nr 0 einer Variablen zugewiesen (Dim x und dann Set x = SmartTags... ) aber das half auch nichts.



Ich frage mich daher aktuell, wie überhaupt nun die genaue offizielle und richtige Vorgehensweise ist um ein verschachteltes Array indirekt zu adressieren in einem HMI Script.
Offenbar soll man eigentlich das Ganze so machen:

SmartTags("Array_Variable")(Index_Nr)

Da finde ich aber nur Beispiele für ein einzelnes Array. Wie wird ein verschachteltes Array so adressiert?

SmartTags("Array_1")(Index_1).SmartTags("Array_2")(Index_2).SmartTags("Array_3")(Index_3) ???
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Für den Fall das es ein VB Script ist:
Für das HMI ist der Variablenname erstmal ein String... daher auch keine Fehlermeldung.
1. Variablennamen korrekt zusammenbasteln: ...["&i&"]... mit i als Index. also:
Code:
SmartTags("Array_1["&x&"].Array_2["&y&"].Array_3["&z&"]")
2. Variablenname muss am HMI deklariert sein, also jedes einzelne anzusprechende Element.
3. In den Einstellungen vorsicht mit den Ersetzungen... Hier werden gerne die Punkte gegen Unterstriche ausgetauscht. (kann man abwählen)
 
Danke.

Also der Daten_DB ist als UDT eingebunden. Es gibt also eine Variable vom Typ UDT. Darin sind alle 3 Arrays enthalten.
Dieser UDT mit allen 3 Arrays wird dem Bildbaustein übergeben.
In diesem Bildbaustein ist das Script.

Die Index-Variablen der 3 Arrays kommen ebenfalls über die Bildbaustein-Schnittstelle als INT rein und sind daher ja auch erstmal SmartTags.


Versucht hab ich jetzt so langsam alle Varianten .. inkl. der von NBerger hier.
Es kommt immer der Fehler "no tag " in der Runtime, obwohl danach dann die korrekt zusammengesetzte Variable erscheint (also mit den "Berechneten" Array-Indexnummern).
Auch wenn genau diese Variable zusätzlich direkt verwendet wird, gehts nicht.

Ich werde jetzt aufgeben und das Ganze per Hand kopieren etc. statt mit Scripten
 
Zuletzt bearbeitet:
Mit den eckigen Klammern im Variablen-Name bastelt man den Name EINER HMI-Variable zusammen, aber nicht den Name eines Array-Elementes. Ich meine, das WinCC Advanced kann nur eindimensionale Arrays (die immer mit Index 0 beginnen). Schreibweise: SmartTags("myArray")(Index) Du müsstest für jedes Array-Element eine eigene HMI-Variable anlegen. Deren Namen kannst Du dann zusammenbasteln. Nächstes Problem: bei Bildbausteinen weiß ich nicht, ob/wie der Wert einer Variable aktualisiert wird, deren Name erst zusammengebastelt wird. Da wirst Du wohl was eigenes stricken müssen, evtl mit Variablen-Multiplexen und/oder unterstützenden Code in der SPS-CPU
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke, das habe ich eben auch irgendwo so gelesen. Die Frage ist, welche Variable genau ich dann initialisieren muss?
Du musst genau die Variablen, deren Name du zusammengesetzt hast, mindestens einmal im Projekt mit dem vollständigen Namen verwenden.

Beispielsweise in einem Startscript die Zeilen
Javascript:
Dim varInitDummy
varInitDummy = SmartTags("Properties\Daten.Array_1[0].Array_2[0].Array_3[0]")
varInitDummy = SmartTags("Properties\Daten.Array_1[0].Array_2[0].Array_3[1]")
usw.
eintragen.
Erst danach kannst du weitere Arbeitsschritte mit dieser Variable (dann auch mit zusammengesetzter "Adressierung") ausführen.


Gruß, Fred

PS: Welche Sprache stellt man sinnvollerweise für das Codingfenster ein, wenn man VBScript darstellen will? Die Forumssoftware bietet diese Sprache nicht an, deshalb habe ich ersatzweise JavaScript eingestellt...
 
Der Witz ist, dass ich genau das vorhin versucht hatte - sprich die 0er-Arrays habe ich einmal einer anderen Variablen zugewiesen bzw. (und das funktioniert ja) ohne Zusammensetzen direkt in der Scriptlogik verarbeitet.

Sobald ich aber etwas Zusammengesetztes benutzen möchte, wird es zwar korrekt zusammen gesetzt (laut Fehlermeldung), aber es kommt die Meldung "no Tag "


Ich machs jetzt mal anders und hoffe es geht, auch wenns so mehr arbeit sein wird (Animation - Sichtbarkeit und eben alles per Hand)
 
Kannst du vielleicht mal einen Screenshot der zugehörigen HMI-Variablentabelle und deinem Versuchscode machen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kannst du vielleicht mal einen Screenshot der zugehörigen HMI-Variablentabelle und deinem Versuchscode machen?
Dafür müsste ich noch alles ändern bzw neu programmieren - da das ein aktives Projekt ist.

Vielleicht hat ja jemand eine funktionierende Logik für mehrfache bzw. verschachtelte Arrays die ich versuchen kann.
 
Du musst genau die Variablen, deren Name du zusammengesetzt hast, mindestens einmal im Projekt mit dem vollständigen Namen verwenden.

Beispielsweise in einem Startscript die Zeilen
Javascript:
Dim varInitDummy
varInitDummy = SmartTags("Properties\Daten.Array_1[0].Array_2[0].Array_3[0]")
varInitDummy = SmartTags("Properties\Daten.Array_1[0].Array_2[0].Array_3[1]")
usw.
eintragen.
Erst danach kannst du weitere Arbeitsschritte mit dieser Variable (dann auch mit zusammengesetzter "Adressierung") ausführen.
Wieso das?

Welchen Unterschied macht es, wenn man im Skript den Wert einer Variable erhält, die das letzte Mal vor ein paar Stunden oder noch nie aktualisiert/eingelesen wurde (und erst nach dem Zugriff aktualisiert wird)?

Harald
 
Hallo Harald,

eine Variable ist in einem Script erst dann verwendbar (sprich: keine Systemmeldung "No tag..."), wenn sie beim Starten der Runtime sauber initialisiert wird.
Siemens scheint dies nur zu machen, wenn diese Variable entweder an ein Control gebunden oder VORHER mit vollen Namen in einem Script verwendet wurde.

Ich habe genau diesen Umstand folgendermaßen herausgefunden:
+ Variable in der Variablentabelle TagTable.png

+ EINZIGE Verwendung der Variablen im Projekt (Script, Name zusammengesetzt):
TagInScript.png

Wenn das Script bei gestarteter Runtime zum ersten Mal aufgerufen wurde, kam an dieser -und allen ähnlichen Stellen- immer eine RuntimeException "No tag...".

Ich habe dann in einem Script, welches zum Runtimestart genau einmal ausgeführt wird, folgendes eingetragen:
TagInit.png

Seitdem ist dieses Problem Geschichte.

Alternativ hatte ich die Variable mal an ein Dummy-Control in einem Hilfsbild projektiert. Hätte auch zum Erfolg geführt.

Glücklicherweise betrifft es nur eine Handvoll Statusvariablen, diese kann ich aber nicht direkt an ein Control im Statusbild projektieren, da das zugehörige Maschinenbild dynamisch zusammengebaut wird.


Gruß, Fred


PS:
Bevor Fragen aufkommen: Das o.g. Codefragment steht nur beispielhaft für mehrere ähnliche (aber ungleich aufwändigere) Script-Konstrukte, die ich häufig einsetze, um den Code lesbarer und kürzer zu halten. Im obigen Fall hätte ich tatsächlich darauf verzichten können.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
eine Variable ist in einem Script erst dann verwendbar (sprich: keine Systemmeldung "No tag..."), wenn sie beim Starten der Runtime sauber initialisiert wird.
Siemens scheint dies nur zu machen, wenn diese Variable entweder an ein Control gebunden oder VORHER mit vollen Namen in einem Script verwendet wurde.
Hallo Fred, von einem solchen Verhalten habe ich noch nie gehört. Um welches WinCC geht es bei Dir?
Sind das WinCC-interne Variablen oder mit PLC-Variablen verbundene HMI-Variablen? Nur bei symbolischem Zugriff auf bestimmte CPUs oder generell?

PS: Du verwechselst auch nicht mit dem Problem, daß man bei zusammengebastelten Variablennamen die Variablen mit Zeitabstand zweimal lesen muß, damit man den aktualisierten Wert erhält?

Harald
 
Hallo Harald,

zu deinen Fragen:
+ Ich setze WinCC Advanced V15 ein.
+ Es sind -soweit ich bis jetzt getestet habe- nur Variablen mit Steuerungsanbindung UND basierend auf PLC-Datentypen betroffen.
+ Ich greife ausschließlich symbolisch auf die einzige vorhandene Steuerung zu.
(EDIT: Ist ein OpenController PC2, ist aber nicht relevant, da gleiches Verhalten auch bei 1512 o.ä.)

Das Problem ist nicht, dass der Variablenwert bei erster Lesung nicht aktuell ist. Ich erhalte direkt eine Exception mit der Meldung "No tag..." mit dem korrekt zusammengesetzten Variablennamen.


Kurzer Hintergrund:
Ich baue bei meinen HMIs das Maschinenbild konfigurationsabhängig und vor allem DYNAMISCH ZUR LAUFZEIT zusammen.
Dazu habe ich in einem Bild sogenannte Kacheln projektiert (14 Stück), jede Kachel besteht im Wesentlichen aus einem grafischem E/A-Feld (Modulbild), mehreren Rechtecken (Modulalarm/-warnung), einigen E/A-Feldern (Modulstatuswerte) und einer unsichtbaren Schaltfläche.
Habe ich weniger Module als Kacheln konfiguriert, so "zentriere" ich das Maschinenbild, indem ich per Script die Werte der eigentlichen Nutzvariablen passend auf die (an die o.g. Controls gebundenen) Hilfsvariablen umkopiere (Man könnte auch kurz "Mapping" dazu sagen ;)).

Bestimmte Nutzvariablen werden so niemals direkt verwendet (also an ein Control gebunden oder mit vollständigem Klarnamen in einem Script adressiert).


Gruß, Fred
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ist es denn so, dass dieses Verhalten auch auftritt wenn man zwar die zusammengesetzte Variable vorher direkt adressiert hat - aber eben nicht alle dazu gehörigen Variablen?

Ich habe ja ein Array in einem Array in einem Array (um genau zu sein) und das letzte Array ist ein Array of Bool. Testweise habe ich mal die Array-Einträge "0" direkt adressiert und danach dann zusammen gebastelt. Ging dennoch nicht.
Wenn ich das ganze Array mit allen Einträgen der jeweiligen Unter-Arrays einmal direkt adressieren muss, spare ich 0 Zeit und lass es lieber gleich :)

Ich denke, da bringen die Unified Panels Vorteile (hoffentlich). Aber dann muss man JavaScript lernen ;)
 
Hallo saarlaender,

könntest du vielleicht doch mal einen Screenshot der HMI-Variablentabellen posten (Projekt und Bildbaustein) ?
Reicht ja, wenn es temporäre Tabellen sind; mir geht es nur um die GENAUE Variablentyp-Aufdröselung, ähnlich meinem Screenshot on Post #14.


EDIT:
Eine grundsätzliche Frage (da ich bis jetzt nicht mit Bildbausteinen gearbeitet habe): Kann ich aus einem Bildbaustein heraus überhaupt Variablen außerhalb des Bausteins ansprechen? Das Script ist ja im Bildbaustein projektiert, richtig?
EDIT2:
Ziehe die Frage zurück, hatte übersehen, dass die betroffenen Variablen ja an die Baustein-Schnittstelle projektiert sind.


Gruß, Fred
 
...
Ich denke, da bringen die Unified Panels Vorteile (hoffentlich). Aber dann muss man JavaScript lernen ;)

Dann müsste das Backend (also Steuerungsanbindung und interne Bereitstellung der Variablen) grundsätzlich einer anderen Architektur folgen.
Ist dies so? Ich kenne mich beim Thema "WinCC Unified" noch gar nicht aus (Bin mir auch nicht sicher, ob ich das überhaupt möchte...)
 
Zurück
Oben