WinCC - C-Scripte in Grafikobjekten via VBS bearbeiten

ThomasMaulwurf

Level-1
Beiträge
41
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!


Folgende Herausforderung:

Ein Grafikobjekt enthält eine C-Dynamisierung der Art 'diverser C-Code... "Bild01.PDL" '

Das aufgerufene Bild muss umbenannt werden in "Bild01_B.PDL" ... dabei würden mir dann alle C-Funktionen besagter Art nutzlos werden.

Da diverse Bilder umbenannt werden müssen und das ganze 100+ Grafikobjekte betrifft ist die Idee ein kleines Tool mit VB zu basteln, das mir die entsprechende Umbenennung in allen betroffenen Bildern - oder zumindest je Bild in allen betroffenen Objekten vornimmt.

Jetzt kommt der Clou: Ich habe keine Ahnung von VB und habe hier bisher nur eine Möglichkeit zum Auslesen von C-Scripten gefunden, nicht zum bearbeiten. (http://www.sps-forum.de/hmi/50592-c-script-mit-vba-auslesen.html)

Würde mich über Hilfe freuen!
Gruß, Thomas
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit "Umverdrahten" komm ich leider nicht an den Inhalt von C-Dynamisierungen innerhalb der Grafikobjekte ran. Würde es nur um Variablenanbindung oder Texte gehen, gäbe es garkein Problem.

Leider müssen Änderungen in den jeweiligen Programmzeilen vorgenommen werden
 
Hallo,

vielleicht helfen diese Skripte als Beispiele.
Da damals schnell hingeschmiert, leider ohne viele Kommentare, hoffe Du steigst trotzdem durch.
Anhang anzeigen VBA für WinCC.txt

In meinem Skript lese ich aber auch nur aus. Ich bin mir nicht sicher, ob man C-Skripte auch per VBA editieren kann....
Mal geguckt, ob Du auf Dateiebene diese Ersetzung vornehmen kannst?

Gruß
JS
 
Zuletzt bearbeitet:
Mit "Umverdrahten" komm ich leider nicht an den Inhalt von C-Dynamisierungen innerhalb der Grafikobjekte ran. Würde es nur um Variablenanbindung oder Texte gehen, gäbe es garkein Problem.

Leider müssen Änderungen in den jeweiligen Programmzeilen vorgenommen werden
Das geht schon, man muss die Skripte halt WinCC-konform schreiben.
Code:
// WINCC:TAGNAME_SECTION_START
// syntax: #define TagNameInAction "DMTagName"
// next TagID : 1
#define SkriptVar1 "WinCC_Variable1"
// WINCC:TAGNAME_SECTION_END


// WINCC:PICNAME_SECTION_START
// syntax: #define PicNameInAction "PictureName"
// next PicID : 1
#define Bild1 "WinCC_Bild1.pdl"
// WINCC:PICNAME_SECTION_END


SetTagFloat( SkriptVar1, 10.0);
Dann kannst du die "WinCC_Variable1" umverdrahten.
Nächster Vorteil: Die Verwendung des TAGS in diesem Skript scheint dann auch in der Cross-Reference auf.

Für das Bild muss man aber anmerken dass dieses, wenn es in der PIC_NameSection drin ist, nicht vom Variablen-Umverdaten-Dialog erfasst wird.
Man kann das #define des Bildes aber auch in der TAGNAME_SECTION machen, dann geht es.
Meistens handelt es bei mir dann eh um ein Anwenderobjekt. Dann löse ich solche Dinge auch gern über Eigenschaften und Texte-Umverdrahten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn ich hier nicht mit einem großen Elend von Fremdsoftware sitzen würde ... :D

Wir selbst machen das auch sinnvoller. Nur leider hab ich hier jetzt einen Berg von C-Funktionen und werd mich hüten das alles umzuprojektieren, bzw. würde diese Änderung auch nur darauf Hinauslaufen, dass ich die Aktuellen Skripte ändern müsste, wenn ich das recht verstehe.



Danke, JSEngineering - leider reichen meine Kompetenzen nur dafür aus grob zu verstehen, was in deinem Programm passiert - so super es seinen Job auch macht.

Im Endeffekt bräuchte ich eine Art "Suchen & Ersetzen" - Funktion für den Inhalt ( = "HMIScriptInfo.SourceCode" ? ) der Dynamisierung ( = "HMIScriptTypeCScript" wie mir scheint )
 
Danke, JSEngineering - leider reichen meine Kompetenzen nur dafür aus grob zu verstehen, was in deinem Programm passiert - so super es seinen Job auch macht.

Ich hab Dir mal das Skript aufgeräumt und kommentiert, vielleicht hilft das dann mehr.:

Code:
'Eine Liste aller Objekte im Dokument holen
Set colObjects = Application.ActiveDocument.HMIObjects
'FOR-Schleife durch alle Objekte in der Liste
For Each objObject In colObjects
    'Eine Liste aller Eigenschaften des Objekts holen
    Set colProperties = objObject.Properties
    'FOR-Schleife für alle Eigenschaften des Objekts
    For Each objProperty In colProperties
        'Ist das Objekt mit einem Skript dynamisiert?
        If objProperty.DynamicStateType = 3 Then
          'Hole die Info über die Dynamisierung
          Set objHMIScriptInfo = objProperty.Dynamic
          'Tu irgendwas mit dem SourceCode
             'objHMIScriptInfo.SourceCode --> Diese Eigenschaft müßte sich auch beschreiben lassen. Somit kannst Du das Skript auslesen. Das gesamte Skript steht Dir nun in dieser Variable zur Verfügung.
             ' --> Ist ja nicht mehr als ein großer String. Da kannst Du dann mit Suchen/Ersetzen durchgehen und in dem String Deine Namen ersetzen.
        End If
    Next objProperty

    'Jetzt eine Liste aller Events vom Objekt holen
    Set colEvents = objObject.Events
    'FOR-Schleife durch alle Events
    For Each objEvent In colEvents
        'Wenn irgendeine Action gefunden wurde
        If objEvent.Actions.Count > 0 Then
            'FOR-Schleife für alle Actions in den Events
            For Each objHMIActionDynamic In objEvent.Actions
                'Ist es ein Skript?
                If objHMIActionDynamic.ActionType = hmiActionTypeScript Then
                    'Objekt holen
                    Set objHMIScriptInfo = objHMIActionDynamic
                    'Ist es ein C-Skript?
                    If objHMIScriptInfo.ScriptType = hmiScriptTypeCScript Then
                        objHMIObject.Selected = True
                        'objEvent.EventName --> Event-Name
                        'objHMIScriptInfo.SourceCode --> Skript-Inhalt
                    End If
                End If
            Next
        End If
    Next objEvent
Next objObject
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Durch einen abenteuerlichen Zufall bin ich auf einen externen Beitrag gestoßen (https://support.industry.siemens.co...t-triggers-auslesen/66700/?page=0&pageSize=10)

Und habe nun mit vereintem Wissen und wenig gesteigerter Kompetenz Folgendes Konstrukt, welches aber kein "codealt bzw "codeneu" kennt/erkennt/generiert; Sprich diese Daten nicht in den MsgBoxes ausgibt oder verarbeitet, wie das vom Schöpfer wohl geplant war.

_______________________________________________________________

Sub Ersetzen()

On Error Resume Next
Dim objHMIObject As HMIObject
Dim objHMIProperty As HMIProperty
Dim objHMIScriptInfo As HMIScriptInfo
Dim objHMIEvent As HMIEvent
Dim a As HMISelectedObjects
Dim i
Dim codealt
Dim codeneu
Dim suchen As String
Dim Ersetzen As String



suchen = "Kontakt_0.pdl"
'MsgBox (suchen)
Ersetzen = "KontaktP_0.pdl"
'MsgBox (ersetzen)
For Each objHMIObject In ActiveDocument.Selection

MsgBox (objHMIObject.ObjectName)

Set objHMIScriptInfo = objHMIObject.Events(2).Actions.Item(1)
codealt = objHMIScriptInfo.SourceCode
MsgBox (codealt)
codeneu = Replace(codealt, suchen, Ersetzen)
MsgBox (codeneu)

objHMIScriptInfo.SourceCode = codeneu

Next objHMIObject

End Sub


_______________________________________________________________
 
Eigentlich brauchst Du dann nur den Code von mir
Code:
          'Tu irgendwas mit dem SourceCode
             'objHMIScriptInfo.SourceCode --> Diese Eigenschaft müßte sich auch beschreiben lassen. Somit kannst Du das Skript auslesen. Das gesamte Skript steht Dir nun in dieser Variable zur Verfügung.
             ' --> Ist ja nicht mehr als ein großer String. Da kannst Du dann mit Suchen/Ersetzen durchgehen und in dem String Deine Namen ersetzen.
nur durch
Code:
objHMIScriptInfo.SourceCode = Replace(objHMIScriptInfo.SourceCode, suchen, Ersetzen)
ersetzen.

Dann sollte ;) das funktionieren...
 
Inzwischen hab ich's wieder kaputtgespielt, aber gestern hat's dann noch ein paar Runden ohne Fehler funktioniert - sprich: Es ist durchgerattert ohne zu meckern. Leider ohne den gewünschten Effekt.

Ich befürchte, er schreibt zwar rein, was er reinschreiben soll, kann die Information aber nicht übernehmen / die aktion nicht erzeugen / den Code dann nicht von allein übersetzen nach dem Schreiben.

Ich spiel mal trotzdem noch etwas mit rum.


(prinzipiell kann ich PDLs auch mit dem Editor öffnen, dort liegen nebst Hiroglyphen die C-Skripte halbwegs offen; Dort Suchen&Ersetzen, abspeichern. Nur danach mag WinCC die Modifizierte Datei nichtmehr - nichtmal, wenn ich die Änderung rückgängig mache und die Datei quasi im Ausgangszustand wieder speichere)
 
Problem war, dass wir mit der Aktuellen Idee nur in den Properties gesucht haben, man aber eine Stufe tiefer - in die Events - reinschauen muss, um an den eigentlichen Code zu kommen.

Der Kollege Praktikant war heut mal da und hat's entdeckt und zurechtgebastelt - sieht nicht viel anders aus als vorher aber klappt jetzt :cool:

Ich stell das fertige Konstrukt dann nachher mal hier rein.

Besten Dank nochmals für die engagierte Hilfe!
 
Inhalt von C-Skripten "Umverdraten"


Sub SuchenErsetzen()

'On Error Resume Next 'Fahre trotz Fehler erstmal fort

Dim objHMIObject As HMIObject
Dim objEvent As HMIEvent
Dim objHMIScriptInfo As HMIScriptInfo

Dim suchen
Dim Ersetzen
Dim count

suchen = "Kontakt_0"
Ersetzen = "KontaktP_0"
count = 0

For Each objHMIObject In ActiveDocument.HMIObjects 'Durchlaufe alle Objekte im aktivem Bild
If objHMIObject.Type = "HMICustomizedObject" Then 'Überprüfe ob es ein Anwenderobjekt ist

For Each objEvent In objHMIObject.Events 'Durchlaufe alle Ereignisse im Objekt
If objEvent.EventName = "OnClick" Then 'Überprüfe ob es ein Maus-Ereignis ist

For Each objHMIActionDynamic In objEvent.Actions 'Durchlaufe die Aktionen im Ereignis
If objHMIActionDynamic.ActionType = hmiActionTypeScript Then 'Überprüfe ob ein Script in den Aktionen hinterlegt ist
Set objHMIScriptInfo = objHMIActionDynamic

If objHMIScriptInfo.ScriptType = hmiScriptTypeCScript Then 'Überprüfe ob dieses Script ein C-Script ist
objHMIObject.Selected = True 'zur Sicherheit dieses Objekt nochmals anwählen
objHMIScriptInfo.SourceCode = Replace(objHMIScriptInfo.SourceCode, suchen, Ersetzen) 'Durchsuche den SourceCode nach dem Schlüsselwort "suchen" und ersetze dieses mit "Ersetzen"
count = count + 1

MsgBox (objHMIScriptInfo.SourceCode) 'beliebige Ausgabe, die zeigt ob auch wirklich der Sourcecode geändert wurde
End If
End If
Next
End If
Next objEvent
End If
Next objHMIObject

MsgBox ("Geänderte C-Scripte: " & count)

End Sub


Ersetzt in einem Bild (Funktioniert in "ThisDocument (BILDNAME.pdl)" im Makro-Editor) in allen Objekten einen Teil des C-Codes im Mausklick-Event durch einen beliebigen neuen.
Und gibt aus welche Skripts gefunden werden und erzählt einem am Ende, in wievielen Skripts die Ersetzung vorgenommen wurde.

... im Groben also das, was JSEngineering hier bereitgestellt hat.

Der Kollege hat da seinen Spaß dran, daher kamen noch kleine Nettigkeiten dazu - ich werd versuchen das jetzt noch zu erweitern auf das Ersetzen verschiedener Einträge pro Bild.


Falls es sonst noch wer gebrauchen kann: Viel Vergnügen damit. Freut mich, dass sich alle, die sofort meinten "Pah.. geht nich." oder (auch gelesen) "Du willst Apfelkompott aus Birnen machen...." geirrt haben :ROFLMAO:


Danke und

Problem gelöst!
 
Zuletzt bearbeitet:
Zurück
Oben