WinCC flexible: Indirekte Adressierung innerhlab eines Skriptes / Schleife

Markus

Administrator
Teammitglied
Beiträge
6.323
Reaktionspunkte
2.340
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe hier ein etwas aufgeblasenes Skript gehabt das 30 mal das selbe macht, ich habe die Funktion nun in eine Schleife gepackt und alles indirekt addressiert.

und jetzt - oh wunder - es geht nicht mehr... :ROFLMAO:

so wie ich das nachvollziehen konnte werden die variablen nicht aktualisiert, da steht im debugger bei manchen "0" drin obwohl das nicht sein darf...

da ich jetzt nicht so der vb-skript profi bin, mache ich sicher nur irgendwas falsch, oder geht das so wirklich nicht?

hier das skript:

Code:
' Erstelle Variablen
Dim Mitte, D 
Dim Rolle
Dim Schnittnummer
Dim vonLinks 
Dim vonRechts
Dim Position 
Dim i
'setzte Festevariable
vonLinks = 340 
vonRechts = (340 + (SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Header.Mutterrollenbreite") / 7))
Mitte = 596 - ((SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Header.Rollendurchmesser")/10)/2)
D = SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Header.Rollendurchmesser")/10

' Höhe + Breite der Mutterrolle anpassen
HmiRuntime.Screens("B_Editor").ScreenItems("Mutterrolle").Height= D
HmiRuntime.Screens("B_Editor").ScreenItems("Mutterrolle").Width = SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Header.Mutterrollenbreite") / 7
' Position der Mutterrolle anpassen
HmiRuntime.Screens("B_Editor").ScreenItems("Mutterrolle").Left = 340
HmiRuntime.Screens("B_Editor").ScreenItems("Mutterrolle").Top = Mitte
'####################
' S C H L E I F E - 1   Alle Schnitte auf Unsichtbar setzen
'####################
For i = 1 To 30  ' Schleife - (Maximal 30 Schnitte möglich)
HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&i).Visible = False
HmiRuntime.Screens("B_Editor").ScreenItems("FRL_"&i).Visible = False
HmiRuntime.Screens("B_Editor").ScreenItems("FRR_"&i).Visible = False
HmiRuntime.Screens("B_Editor").ScreenItems("SCL_"&i).Visible = False
HmiRuntime.Screens("B_Editor").ScreenItems("SCR_"&i).Visible = False
Next
 

'####################
' S C H L E I F E - 2   Bestimmung der Position und Größe - Nur nenötigte Schnitte Sichtbar setzen
'####################

For Schnittnummer = 1 To SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Header.Schrittnummer_MAX")
' Schnitttyp-2 ist ein Sauberschnitt (eine Sägeblattbreite)
If SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Schnittyp") = 2 Then 
 vonLinks = vonLinks + (10/7)
End If
'Positon und Größe wenn der Schnitt auf der LINKEN Seite ist (Schnittseite-1)
If SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Schnittseite") = 1 Then
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Left = vonLinks
 Position = vonLinks
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Top = Mitte
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Height = D
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Width = SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Rollenbreite_SOLL")/7
 vonLinks = vonLinks + ((SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Rollenbreite_SOLL")/7) + 10/7)

'Positon und Größe wenn der Schnitt auf der RECHTEN Seite ist (Schnittseite-2)
Else 
 vonRechts = vonRechts - (SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt[1].Rollenbreite_SOLL")/7)
 Position = vonRechts
 
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Height = D
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Width = SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Rollenbreite_SOLL")/7
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Left = vonRechts
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Top = Mitte
  
 ' sieht komisch aus ist es auch aber, dadurch das die Darstellung am Äußeren Rand vom Panel ist 
 ' kann es Vorkommen das jenach Richtung das Bild erst die Größe ändert und dann so groß wird, das es nicht mehr auf 
 ' das Panel passt und somit gar nicht erst dargesstellt wird. Deswegen diese Doppelt Programmierung egal wie das Bild liegt so passt es immer
 
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Left = vonRechts 
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Top = Mitte
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Height = D
 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Width = SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Rollenbreite_SOLL")/7 
End If 
' Darstellung der Schnittypen in Unterschiedlichen Farben
Select Case SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Schnittyp")
 Case 0 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Visible = False
 Case 1 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).BackColor = vbBlack
      HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Visible = True  
 Case 2 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).BackColor = vbWhite
   HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Visible = True
 Case 3 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).BackColor = vbGreen
   HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Visible = True
 Case 4 HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).BackColor = vbBlue
   HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&Schnittnummer).Visible = True
End Select

' Darstellung von Fräs und Schneid Einstellungen
' Fräsen links 
If SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Fraesen_LINKS") = True Then 
 HmiRuntime.Screens("B_Editor").ScreenItems("FRL_"&Schnittnummer).Visible = True
    HmiRuntime.Screens("B_Editor").ScreenItems("FRL_"&Schnittnummer).Left = Position
    HmiRuntime.Screens("B_Editor").ScreenItems("FRL_"&Schnittnummer).Top = Mitte
    HmiRuntime.Screens("B_Editor").ScreenItems("FRL_"&Schnittnummer).Height = D
    HmiRuntime.Screens("B_Editor").ScreenItems("FRL_"&Schnittnummer).Width = 4
End If

' Schleifen links 
If SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Schleifen_LINKS") = True Then 
 HmiRuntime.Screens("B_Editor").ScreenItems("SCL_"&Schnittnummer).Visible = True
 If SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Fraesen_LINKS") = True Then
  HmiRuntime.Screens("B_Editor").ScreenItems("SCL_"&Schnittnummer).Left = Position + 4
 Else
  HmiRuntime.Screens("B_Editor").ScreenItems("SCL_"&Schnittnummer).Left = Position
 End If 
 HmiRuntime.Screens("B_Editor").ScreenItems("SCL_"&Schnittnummer).Top = Mitte
 HmiRuntime.Screens("B_Editor").ScreenItems("SCL_"&Schnittnummer).Height = D
 HmiRuntime.Screens("B_Editor").ScreenItems("SCL_"&Schnittnummer).Width = 4
End If

' Fräsen rechts 
If SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Fraesen_RECHTS") = True Then 
 HmiRuntime.Screens("B_Editor").ScreenItems("FRR_"&Schnittnummer).Visible = True
 HmiRuntime.Screens("B_Editor").ScreenItems("FRR_"&Schnittnummer).Left = Position + ((SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Rollenbreite_SOLL")/7) - 4)
 HmiRuntime.Screens("B_Editor").ScreenItems("FRR_"&Schnittnummer).Top = Mitte
 HmiRuntime.Screens("B_Editor").ScreenItems("FRR_"&Schnittnummer).Height = D
 HmiRuntime.Screens("B_Editor").ScreenItems("FRR_"&Schnittnummer).Width = 4
End If

' Schleifen rechts 
If SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Schleifen_RECHTS") = True Then 
 HmiRuntime.Screens("B_Editor").ScreenItems("SCR_"&Schnittnummer).Visible = True
 If SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt[1].Fraesen_RECHTS") = True Then
  HmiRuntime.Screens("B_Editor").ScreenItems("SCR_"&Schnittnummer).Left = Position + ((SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Rollenbreite_SOLL")/7) - 8)
 Else
  HmiRuntime.Screens("B_Editor").ScreenItems("SCR_"&Schnittnummer).Left = Position + ((SmartTags("Rezeptur_Var\Rollendaten_EDIT.Schnittdaten.Schnitt["&Schnittnummer&"].Rollenbreite_SOLL")/7) - 4)
 End If 
 HmiRuntime.Screens("B_Editor").ScreenItems("SCR_"&Schnittnummer).Top = Mitte
 HmiRuntime.Screens("B_Editor").ScreenItems("SCR_"&Schnittnummer).Height = D
 HmiRuntime.Screens("B_Editor").ScreenItems("SCR_"&Schnittnummer).Width = 4
End If
Next
 
Nur mal son Gedanke,
hast Du alle Variablen auf immer lesen und nicht "nur bei Verwendung gesetzt"?
Durch das indirekte werden die ja für WinCC nicht verwendet.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich habe hier ein etwas aufgeblasenes Skript gehabt das 30 mal das selbe macht, ich habe die Funktion nun in eine Schleife gepackt und alles indirekt addressiert.
Das heißt davor hat es Funktioniert?
, da steht im debugger bei manchen "0" drin obwohl das nicht sein darf...
Sind das immer die gleichen Werte bei denen eine "0" drin steht?
Werden die Daten richtig geschrieben wenn Du die Schleife auf 1 anstatt auf 30 setzt?
Damit Du siehst ob es an der indirekten Adressierung oder an der Schleife liegt.
ich habe die Funktion nun in eine Schleife gepackt und alles indirekt addressiert.
...
so wie ich das nachvollziehen konnte werden die variablen nicht aktualisiert, da steht im debugger bei manchen "0" drin obwohl das nicht sein darf...
Und wie Jabba auch schreibt, werden die Variablen für die indirekte Adressierung "Zyklisch gelesen"?
 
Anstatt:
HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&i).Visible = False

Vielleicht:
HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_" & CStr(i)).Visible = False
 
Hi,
ehrlich gesagt bin ich ein Verfechter wenn es darum geht Variablennamen zusammenzubauen... Aber so mach ich das in der Regel wenn ich auf "Indizierte Strings" zugreife... Nur über die Zwischenvariable kann man auf den SmartTag zugreifen. Ich nehme mal an dass es auch bei den ScreenItems so ist.

DIM Test, VarName

VarName = xyz + i
Test = SmartTags(VarName)

und so sollte es auch mit dem Zugriff auf deine Screen Items funktionieren.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Markus,
nach meiner Meinung fügt dedie Verkettung ("Schritt_" & i) das so zusammen : "Schritt_ 17" wobei ich für i mal 17 angenommen habe. Das solltest du dir mal seperat ausgeben lassen. Wenn dem so ist, dann könntest du das führende Leerzeichen (vor der 17) mit dem Befehl LTRIM beseitigen lassen. Das Ganze ggf. mit dem von Jesper schon angebotenem CSTR aus Wandlungs-Befehl.Das sähe dann so aus :
Code:
"Schritt_" & LTrim(Cstr(i))
Gruß
LL
 
hallo, sorry für die späte antwort.

also grundsätzlich war das probelem das die variablen nicht auf ständig lesen gesetzt waren. war ein denkfehler meinerseits, was ihr sagt stimmt, woher soll flex wissen das zugegrifen wird wenn der zugriff indirekt ist...



Anstatt:
HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_"&i).Visible = False

Vielleicht:
HmiRuntime.Screens("B_Editor").ScreenItems("Schritt_" & CStr(i)).Visible = False

was bringt das?


das skript läuft jetzt zwar, aber als schleife EXTREM viel langsamer als mit 3000 zeilen direkt adressiert... warum?
 
Das ist klar! Weil du jedes mal (Schleifendurchlauf) das komplette Array liest bzw. schreibst!
Kopiere am Anfang des Skriptes alle Daten in ein internens Array und zum Schluss wieder zurück!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das ist klar! Weil du jedes mal (Schleifendurchlauf) das komplette Array liest bzw. schreibst!
Kopiere am Anfang des Skriptes alle Daten in ein internens Array und zum Schluss wieder zurück!

danke dir!

kann ich das den auch in form einer schleife ohne das selbe problem zu haben? für mich ist das leider nicht so klar, habe nicht soviel erfahrung mit vbskript...
 
Hallo Markus,
das kannst du dann wie in SCL tun :

myZielArray = myQuellArray

Flex kann das ganze Array in einem Rutsch übergeben ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So in etwa sieht das bei mir aus...

Code:
Dim AblaufDatensatzArray(500)
 
' A B L A U F     
'Alle Daten in eine Interne Struktur kopieren! Dann die Interne der 'Externen Struktur zuweisen damit nur einmal die Verbindung zur Stuerung 'belastet wird   

For i = 0 To (UBound(AblaufDatensatzArray)-1)
    AblaufDatensatzArray(i) = SmartTags("xyz")(i)
Next

SmartTags("SteuerungArray") = AblaufDatensatzArray
 
so ganz begriffen habe ich es noch nicht...

du kopirst die variablen der sps in einer schleife in das lokale array im skript?

also variable für variable?

die müssen auf ständig lesen sein wel sie ja indirekt sind?


und wie siht das dann am ende aus?
sollte doch auch wieder ne schleife zum umkopieren her, zumindest verstehe ich das hier nicht:

SmartTags("SteuerungArray") = AblaufDatensatzArray



bzw. ich verstehe es schon, aber sollte es dann am anfang nicht auch gehen? wozu dann die schleife?

bei mir ist das mit der zuweisng des array etwas blöd.
in der sps ist das ein array of udt.
ich brauche aus jedem udt aber nur bestimmte werte, wenn ich den kompletten array of udt hochkopiere, müssen ja mehrere variablen kpert werden.

aber mit weniger verbindungen, da sonst die schleife für jede variable eine neue verbindung auf machen muss? habe ich das so verstanden?

danke euch!
 
Hallo Markus,
der Trick an dieser Stelle ist, dass es für die Visu deutlich einfacher ist, einen kompletten Datenblock zu laden (auch wenn er eine Menge unbenötigte Informationen enthält) als Variable für Variable einzeln - daß müßte im Grunde auch Rainer (Hönle) bestätigen können.

Warum xHasx erst Einzel-Elemete in sein Temp-Array schreibt habe ich auch nicht richtig verstanden. Entscheidend bei der Array-Kopiererei ist aber ein identischer Aufbau - deshalb mein Hinweis "wie bei SCL".

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
also die cpu kann je nach typ einen block bestimmter größe mit einer verbindung übertragen, das sind irgendwas mit so ca. 250byte soweit ich weiß (bin mir da aber nicht sicher!). alles was innerhalb dieses blockes liegt kommt mit, somit brauche ich weniger verbindungen.
aber ich ging da von aus das wincc flexible so schlau ist und das selber optimiert, also wenn ich auf mehrere variablen in einem block zugreife diese auch zusammen holt...

kann ich in vb skript sowas wie einen udt anlegen? also das lokale array gleich definieren wie das in der sps? da muss ich doch dann die datentypen mit angeben.
 
Hallo Markus,
soweit ich sehen konnte kann man in VB-Script (bei Siemens) keine TYPE's deklarieren. Es geht also nur mit ARRAY's gleichen Datentyp's - hier möglicherweise (das habe ich noch nie probiert) mit eindimensionalen ARRAY's ... Sorry ... :(

Gruß
LL
 
Sorry bin spät dran!

Ich muss gestehen dass es sich bei mir zuerst um Interne Variablen Handelt. Hier muss man Variablen in ner Schleife kopieren (anders hat es bei mir nicht funktioniert).
Auf das Externe Variablenarry kann man dann mit = zuweisen.

Ich lass mich aber gerne eines besseren belehren - mich würd's auch freuen wenn ich die Zählschleife nicht brauchen würde!!!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
VB Script..

Hi,
nur mal am Rande: muss man sich irgendwelche Gedanken darüber machen, wie die Variablen gelesen/aktualisiert werden(im Script, nicht als Variable allegemein, zyklisch usw.!)? Es gibt da einige Methoden:

Dim Var1
Set Var1 = HMIRuntime.Tags("BlaBla").Read

If Var1.Value = 5 then.........

Oder:
Set Var1 = HMIRuntime.Tags("BlaBla")
Var1.Read
Var1.Value = 666
Var1.Write

Kann man diesbezüglich Etwas optimieren?

Gruss: V.
 
der Trick an dieser Stelle ist, dass es für die Visu deutlich einfacher ist, einen kompletten Datenblock zu laden (auch wenn er eine Menge unbenötigte Informationen enthält) als Variable für Variable einzeln - daß müßte im Grunde auch Rainer (Hönle) bestätigen können.
So ganz pauschal stimmt das nicht. Es hängt davon ab, wie groß die Lücken sind, die mitgelesen werden. Bei kleinen Lücken (ca. 10 Bytes) ist es auf jeden Fall besser, diese mitzulesen. Bei großen Lücken hängt es davon ab, wie groß die Anfrage bereits ist. Ist diese gering, dann nicht mitlesen. Ist diese schon relativ voll, dann mitlesen. Im AGLink gibt es hierzu spezielle Optimierungsfunktionen, die genau dies erledigen und eine für die SPS optimale Anfrage zusammenstellen.
 
@Rainer:
Als hoch-wissenschaftlich sollte meine Aussage hier auch nicht verstanden werden. Ich weiß, dass verschiedenene Link-Tool's (ich nenne das hier mal so) den Datenverkehr recht unterschiedlich handhaben ... und ich weiß, dass sich Siemens hier in Sachen Optimierung nicht unbedingt viel Mühe gegeben hat - ich kann meißtens eine Profilkurve mit 200 REAL's schneller einlesen/aktualisieren als 10 Einzel-Variablen beliebigen Typ's, die ein bißchen verstreut sind.
Mein Verweiß hier auf dich/euch sollte sich eher auf die Kenntnis des genauen Protokolls im Hintergrund für die Abfrage von Variablen von der SPS beziehen ...

Gruß
LL
 
Zurück
Oben