# Visualisierung programmieren in VBS und Objekten per For Schleife bearbeiten



## spsqem (25 Juli 2021)

Hallo zusammen,
ich bin im Moment dabei eine Visualisierung mit verschiedenen Diagrammen zu programmieren.
In meinem aktuellen Fall habe ich 10 Säulendiagramme, die gleich ausschauen und in Abhängigkeit der Instanzen einen "Füllstand" darstellen.

Jetzt zu meiner Frage:
Gibt es eine Möglichkeit die Objekte in einer For Schleife eine nach der anderen zu bearbeiten? Das würde mir eine Menge Zeit ersparen.
Ich habe die Objekte alle gleich benannt bis auf die letzte Ziffer, die meinen Index darstellt.
Grundsätzlich hat es schon funktioniert die Objektnamen in einem String zusammen zu bauen und dann mit dem String zu bearbeiten.

Wenn ich das ganze dann aber in einer For Schleife probiere ist das Skript fehlerhaft.

Viele Grüße
spsqem


----------



## Thomas_v2.1 (25 Juli 2021)

Sinnvoll wäre es zu wissen, was für eine Visualisierungssoftware du genau verwendest.


----------



## spsqem (25 Juli 2021)

Sorry..
WinCC Professional V14


----------



## Thomas_v2.1 (25 Juli 2021)

Du kannst mal versuchen ob es noch so wie bei WinCC 7.x funktioniert, aber wie ich letztens gelesen habe hat Siemens obwohl die Runtime identisch ist da doch etwas geändert.

In WinCC 7.x funktioniert das grundsätzlich so in der Art:


```
Dim i
Dim objBalken

For i = 1 To 3
    Set objBalken  = HMIRuntime.ActiveScreen.ScreenItems("Balken" & i)
    objBalken.Max = 100.0
    objBalken.Min = 0.0
Next
```

Wenn du im Bild drei Balkenobjekte "Balken1", "Balken2" und "Balken3" hast. Wenn du nur eine Eigenschaft verändern möchtest, dann kannst du dir das zusätzliche objBalken auch sparen und direkt die Eigenschaft hinter das Screenitem stellen.


----------



## spsqem (26 Juli 2021)

Vielen Dank für deinen Tipp. Es hat einwandfrei funktioniert


----------



## spsqem (26 Juli 2021)

Ich habe mein Skript jetzt auf diese Weise umgebaut und es funktioniert bei dem Klick Ereignis einwandfrei.
Ich hab jetzt beim Aufruf Ereignis des selben Bildes mehr oder weniger das selbe Skript drin mit leichten Veränderungen drin und es wird nicht ausgeführt. Es ist aber auch nicht fehlerhaft, die Dynamik der Objekte wurde einfach nicht verändert.
Ich habe dann zu Testzwecken das gleiche Skript wie im Button verwendet und das wird auch nicht ausgeführt.

Kann es sein, dass die Methode nicht beim Aufruf des Bildes funktioniert?


----------



## Larry Laffer (26 Juli 2021)

Erstmal wäre es hilfreich dein Script zu sehen ... 
Unabhängig davon ist es mir schon öfter mal passiert, das ActiveScreen noch nicht korrekt zugewiesen war (beim Bildwechsel z.B.). Kannst du hier nicht direkt den Screen-Namen adressieren ?

Gruß
Larry


----------



## spsqem (26 Juli 2021)

> Dim i
> Dim objBalken
> 
> For i = 1 To 3
> ...


Dieses Skript hier kann als Beispiel verwendet werden.
Wenn ich es im Bild_1 per Klickereignis von einem Button ausführe funktioniert es einwandfrei.
Sobald ich es im Ereignis Aufgerufen von Bild_1 einfüge wird es nicht ausgeführt..
Das ist mein Problem


----------



## Larry Laffer (26 Juli 2021)

OK ... dann verwende mal in deinem Script anstelle von ActiveScreen deinen Screen - also Screen("dein ScreenName")

Gruß
Larry


----------



## Thomas_v2.1 (26 Juli 2021)

Falls es das bei WinCC Prof. noch gibt, kannst du in das Bild mal ein Diagnose-Objekt einfügen und sehen ob dort ein Fehler aufläuft.
Und ggf. in dem Skript ein Debug.Print um zu sehen ob es überhaupt angestoßen wird.


----------



## spsqem (26 Juli 2021)

Das ist schon seltsam, bis zu dieser Deklarierung: 


> Set objBalkenT = HMIRuntime.ActiveScreen.ScreenItems("T_" & i)
> Set objBalkenP = HMIRuntime.ActiveScreen.ScreenItems("P_" & i)
> Set objTextT = HMIRuntime.ActiveScreen.ScreenItems("TextT_" & i)
> Set objTextP = HMIRuntime.ActiveScreen.ScreenItems("TextP_" & i)
> ...


Funktioniert das Skript einwandfrei..
Ab da wird es nicht mehr ordentlich ausgeführt.
Das selbe Fehlerbild ergibt sich, wenn ich statt dem "ActiveScreen" -> "Screens("abc") eingebe..

Komischerweise funktioniert ein und das selbe Skript beim Klick Ereignis ohne Probleme.. da bin ich etwas ratlos


----------



## Larry Laffer (26 Juli 2021)

Ist denn "Abc" der Name deines Screens ?
Dann weiterer Vorschlag :
Arbeite mit Zwischen-Objekten - also :

```
set objScreen =  HMIRuntime.Screens("abc")
set objBalkenT = objScreen.ScreenItems("T_" & i)
```


----------



## spsqem (26 Juli 2021)

Zwischenobjekte führen leider auch nicht ans Ziel.. Das Problem muss irgendwo anders liegen
Trotzdem danke, werde mich morgen weiter damit beschäftigen


----------



## Thomas_v2.1 (26 Juli 2021)

Hast du schon mal nachgesehen ob es irgendwo eine Fehlermeldung gibt? Also entweder in das Bild zum Test ein Diagnosefenster einfügen, oder über apdiag falls es das bei WinCC Prof. so in der Art noch gibt.


----------



## hucki (26 Juli 2021)

spsqem schrieb:


> Wenn ich es im Bild_1 per Klickereignis von einem Button ausführe funktioniert es einwandfrei.
> Sobald ich es im Ereignis Aufgerufen von Bild_1 einfüge wird es nicht ausgeführt.



Braucht Deine Seite vielleicht ein wenig, bevor Du auf diese Objekte zugreifen kannst?
Füg' doch beim Aufruf über Ereignis "Aufgerufen von Bild_1" mal versuchsweise eine kleine Verzögerung ein (z.B. mit vbDelay).


----------



## spsqem (26 Juli 2021)

vbDelay funktioniert nicht..

im Diagnosefenster bekomme ich folgende Meldung:



> Picture        : Übersicht_Taktzeit.pdl_Events
> Function        : Sub Document_OnGenerateScreen()
> Line        : 69
> Error        : get_Item:Falscher Parameter.



ab Zeile 69 beginnt meine Deklaration für den Loop mit denen ich die Objekte bearbeiten möchte:


> 69 Set objBalkenT = HMIRuntime.Screens("Übersicht_Taktzeit").ScreenItems("T_1" & i)
> Set objBalkenP = HMIRuntime.Screens("Übersicht_Taktzeit").ScreenItems("P_" & i)
> Set objTextT = HMIRuntime.Screens("Übersicht_Taktzeit").ScreenItems("TextT_" & i)
> Set objTextP = HMIRuntime.Screens("Übersicht_Taktzeit").ScreenItems("TextP_" & i)
> ...



Es scheint so, als wäre das eine Eigenart des Ereignisses Aufgebaut..
wie gesagt, der selbe Code funktioniert bei einem Klick Ereignis problemlos


----------



## Thomas_v2.1 (26 Juli 2021)

Also in WinCC 7.4 funktioniert das so im Ereignis "Bildanwahl", auch mit ActiveScreen.
Ist das evtl. das falsche Erengnis? "OnGenerateScreen" hört sich irgendwie danach an, also ob das da wirklich noch nicht fertig ist. Bei WinCC 7.4 heißt das Ereignis bei Bildanwahl oder auf englisch "Open Picture" dann in VBS OnOpen().


----------



## hucki (26 Juli 2021)

spsqem schrieb:


> vbDelay funktioniert nicht..


Funktioniert das Script unter WinCC Pro nicht (ist ja eigentlich für Advanced) oder bringt die Verzögerung keine Änderung?


----------



## Larry Laffer (26 Juli 2021)

Ich denke mal, dass es eher ist wie von Thomas vermutet ...
Allerdings muss dann die direkte Anwahl der Seite (wie im Beitrag #16 zu sehen) funktionieren ...
Mal eine "dumme" andere Frage :  was wird beim ScreenItem aus "T_1" & i ?  Wird daraus "T_11" wenn i=1 ist ... oder wird daraus "T_1 1" ?
Wie heißt der Item wirklich ?


----------



## spsqem (27 Juli 2021)

Thomas_v2.1 schrieb:


> Also in WinCC 7.4 funktioniert das so im Ereignis "Bildanwahl", auch mit ActiveScreen.
> Ist das evtl. das falsche Erengnis? "OnGenerateScreen" hört sich irgendwie danach an, also ob das da wirklich noch nicht fertig ist. Bei WinCC 7.4 heißt das Ereignis bei Bildanwahl oder auf englisch "Open Picture" dann in VBS OnOpen().


 Also bei mir in der Programmieroberfläche heißt das Ereignis zu deutsch "Aufgebaut".. >"OnGenerateScreen" steht dann im Skript als sub.. Das ist das Ereignis, dass beim Aufruf des Bildes das Skript ausführt, was ich auch so haben möchte..



hucki schrieb:


> Funktioniert das Script unter WinCC Pro nicht (ist ja eigentlich für Advanced) oder bringt die Verzögerung keine Änderung?


Das Skript funktioniert gar nicht, und dann habe ich einen Test Loop zum warten vorauf dann beim Runtime abschmiert...


Larry Laffer schrieb:


> Ich denke mal, dass es eher ist wie von Thomas vermutet ...
> Allerdings muss dann die direkte Anwahl der Seite (wie im Beitrag #16 zu sehen) funktionieren ...
> Mal eine "dumme" andere Frage :  was wird beim ScreenItem aus "T_1" & i ?  Wird daraus "T_11" wenn i=1 ist ... oder wird daraus "T_1 1" ?
> Wie heißt der Item wirklich ?


Das war ein Fehler der sich beim Testen eingeschlichen hat.. habe ich schon korrigiert. Das Ergebnis von "T_" & i soll sein
- T_1
- T_2
- T_3
- etc...



Ich bin ratlos..

Weshalb ich möchte, dass das Skript beim Aufruf des Bildes ausgeführt wird ist, dass in diesen Diagramm schon beim Aufruf Werte dargestellt werden sollen.
Ich habe auch einen Button "Aktualisieren" mit dem ich das gleiche Skript ausführe und da funktioniert es ohne Probleme..
Da gibt mir das Diagnose Fenster auch keinen Fehler aus..

Wenn ich das Skript beim Aufruf nicht ausführe, werden mir unbearbeitete Objekte angezeigt, was nicht schön ist.
Wenn ich das Skript ohne die Deklaration für den Loop ausführe funktioniert es ebenfalls:


> Set objBalkenT = HMIRuntime.Screens("Übersicht_Taktzeit").ScreenItems("T_" & i)
> Set objBalkenP = HMIRuntime.Screens("Übersicht_Taktzeit").ScreenItems("P_" & i)
> Set objTextT = HMIRuntime.Screens("Übersicht_Taktzeit").ScreenItems("TextT_" & i)
> Set objTextP = HMIRuntime.Screens("Übersicht_Taktzeit").ScreenItems("TextP_" & i)
> ...


Dann muss ich aber wiederum jedes einzelne Diagramm separat bearbeiten was einen Arbeitsaufwand Faktor 10 darstellt, weil 10 Diagramme vorhanden..

Trotzdem danke bis hierhin, leider habe ich noch keine Lösung auf dieses Problem


----------



## Larry Laffer (27 Juli 2021)

nur um das mal klarzukriegen :
Mach doch mal ein Script, dass dir den Textinhalt von ActiveScreen auf dem Bildschirm in einem Ausgabefeld darstellt. Vielleicht auch noch ob und wann HMIRuntime.Screens("Übersicht_Taktzeit") ein Objekt zurückgibt ...
Dieses Script rufst du SPS-getriggert zyklisch (z.b. alle 250 ms) auf und dann schau mal ob und wann sich der Wert anpasst / ändert.

Das erklärt allerdings noch nicht warum die direkte Adressierung mit Screens nicht funktioniert. Vielleicht benennst du die Seite noch einmal um damit der Umlaut verschwindet - also vielleicht "Uebersicht_Taktzeit" statt "Übersicht_Taktzeit". Obwohl ... es funktioniert ja, wie du schreibst, wenn du das Script über einen Button aufrufst.

Hast du mal kontrolliert, ob das Script wirklich beim Bildwechsel komplett durchlaufen wird (z.B. mit einer Zählvariable) ?

Gruß
Larry


----------



## spsqem (27 Juli 2021)

Hab das Bild umbenannt, funktioniert auch nicht.
Das Skript wird nicht komplett durchlaufen. Ab der Zeile 69 mit der Deklarierung für den Loop ist Schluss.


----------



## spsqem (27 Juli 2021)

Gibt es denn die Möglichkeit einen Button per Skript zu klicken? Falls ja, würde ich das mal versuchen..


----------



## Thomas_v2.1 (27 Juli 2021)

Schau dir doch mal die Debug-Ausgaben von apdiag oder dem WinCC Prof. entsprechenden an.
Dann baust du in dein Script Debug Ausgaben ein, kannst sehen wie weit es kommt.
Vor allem bei solchen Problemen erstmal das Script auf das minimalste kürzen, also nur eine einzige Eigenschaft setzen (oder auch nur lesen) und prüfen wie sich das verhält. Das kannst du alles selbst machen. Irgendwelche Warteschleifen einbauen führt aber garantiert nicht zum Ziel.


----------



## spsqem (30 Juli 2021)

Hallo zusammen,
zur Information, in der Hoffnung, dass somit zukünftige HMI Künstler schneller ans Ziel kommen.

Die Lösung für das Skript im Ereignis "Aufgebaut" ist es, die Deklaration folgendermaßen zu definieren:



> Set objBalkenT = ScreenItems("T_" & i)
> Set objBalkenP = ScreenItems("P_" & i)
> Set objTextT = ScreenItems("TextT_" & i)
> Set objTextP = ScreenItems("TextP_" & i)
> ...



Anscheinend kommt dieses Ereignis nicht klar mit der Syntax "hmiruntime.screens("bild_1")."


Mit freundlichen Grüßen
spsqem


----------

