TIA programmatisches Durchlaufen einer Struktur (STRUCT)

HelixX23

Level-2
Beiträge
23
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,
ich brauche die Funktionalität von:

dim element as variant
for each (element in myStruct)
if typeof(element) = "UDT Name" then
element.UdtStrukturPfad = Wert
end if
next

in AWL...

jemand eine Idee?

In meinem Struct habe ich eine Sammlung von UDTs hinterlegt.
Möchte jetzt in einer Schleife alle Elemente dieses Structs durchlaufen und überprüfen ob das Element vom Datentyp her einem bestimmten UDT entspricht.
Falls das der Fall ist, möchte ich dort Daten entnehmen und einfügen.

In einem Array könnte ich die einzelnen Elemente über die Index Nummer erreichen.
Ein Array kann aber nur einen DatenTyp beinhalten.

die Realität sieht so aus, dass ich all meine Drucksensoren (mit und ohne Filterüberwachung; 2 verschiedene UDTs) in ein Struct in ein DB gepackt hab.
 
Habe mir jetzt die passenden Elemente von Hand in ein anderes Array ge"MOVE"d...
Diesen Schritt möchte ich einsparen...

Nachteil: ich kann nur Werte lesen aber nicht beschreiben...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kannst du die UDT noch um 1 Element erweitern oder die Struckt ein wenig anders aufbauen?
Dann würde ich die Nummer der UDT als Element in die UDT schreiben oder (wenn nciht möglich) die UDT nochmal in eine "Wrapper"-UDT packen mit dem zusätzlichen Element mit der UDT-Nummer.
Dann das Array durchlaufen und jeweils die UDT-Nummer vergleichen, bei Gleichheit auf die Struct zugreifen.

PS: SCL ist für so etwas sicher Besser geeignet.
 
Eine Wrapper UDT hört sich sehr gut an!!!
nur bei einer Wrapper UDT muss ich ja auch in die "Unterelemente" "rein schauen" und den Index checken...
Meine UDTs in dem Struct haben zusätzlich auch noch verschiedene Größen von Speicherplatz her

kann ich in SCL den Variablen Namen (symbolisch) generieren? (habe gehofft ich komme um die rumpointerrei endlich herum)

Wenn zum Beispiel die Variable folgenden Namen hat...


DB STRUCT UDT(STRUCT) REAL
NameDesDBs.NameDesStructsWelchesDieGesuchtenElementeEnthält.NameDesElementsInnerhalbDesStructsMitDerNummer_1.WertDenIchZbÄndernMöchte
kann ich dann den Namen der Variable (Symbol) an dieser Stelle-------------------------------------------------------^ so abändern, dass dann da eine zwei(2) steht?

Hmmmm.... geht auch nicht... dazu müsste die Symboltabelle ja in der CPU sein... Habe übrigens eine 1500er CPU


Vielleicht gehe ich da auch falsch ran...
-Ich habe in meiner Anlage mehrere Druckaufnehmer
-Für die einzelnen Druckaufnehmer habe ich einen FC der die Daten ausliest...
--...die Messergebnisse und Parameter entnimmt und speichert der FC an seinem InOut in ein UDT
-Ausserhalb des FCs ist das InOut UDT mit seinem Gegenstück in einem Struct innerhalb eines DBs gekoppelt (in dem Struct innerhalb des DBs sind alle Druckaufnehmer drin)

Bis dahin funktioniert alles optimal und höchst komfortabel.
Auch im Zusammenhang mit WinCC, da anscheinend der Import eines kompletten Structs nur ein Powertag kostet ;) << kleiner Tip am Rande
Also kann ich, wenn ich in der HMI die Druckdosen visualisieren muss, ALLE Infos aus der Steuerung ziehen und muss nicht immer alle Variablen einzeln anlegen
Und in AWL kann ich mit unter 10 Tastenanschlägen meinen gesuchten Wert ran ziehen


Jetzt kam die neue Idee und nu hängts an einer kleinen Stelle...
Die neue Idee war folgende:
Ein Filter wird am Eingang und am Ausgang mit Drucküberwacht.
Durch den Differenzdruck (unter Anderem) kann man den Verschmutzungsgrad ermitteln.
Da der Arbeitsdruck auf den es ankommt der gleiche ist (und der Andere nur die Drucküberwachung übernimmt) wollte ich nun aus den beiden Sensoren eine logische Einheit machen
>> neuer FC - der beide Druckaufnehmer aufnimmt
>> neues UDT - mit detaillierten Filter Infos
>> Alles rein in das Struct in dem die Anderen DruckSensoren auch drin sind

---- bis hier hin funktioniert alles prima ----

Jetzt will ich in der HMI die Filterkurve die aus den zusätzlichen Parametern entsteht anzeigen lassen.
Da WinCC keine internen Arrays nutzen kann (wie jeder Andere auch) muss ich die Kurve in der CPU generieren und wertvolle Ressourcen dafür opfern.
Das generieren funktioniert prima und die Kurve kann ich bitgetriggert in der CPU abholen...

Das ganze funktioniert nun mit einem Filter. Jetzt nöchte ich die anderen Filter auch visualisieren. aber nicht alle einzeln!!

Daher die Idee:
Ich baue für die HMI Seite die die Kurven anzeigt eine Datenschnittstelle (auch ein UDT)
Wenn die Seite in der HMI aufgebaut ist, wird Code in der CPU ausgeführt der die Datenschnittstelle füttert
Jetzt möchte ich auf dieser HMI Seite vorgeben welchen Sensor ich beobachten will
Dazu muss ich erstmal auf der HMI Angezeigt bekommen welche meiner Überwachungs-Punkte ein solches Feature besitzt

Und da hängts, weil ich innerhalb des Structs nicht differenzieren kann


Ich könnte mich in dem Struct entlang "pointern" und immer unterschiedliche offsets nehmen wenn ich einen UDT erkann habe. Will ich aber im Jahre 2016 nicht mehr machen

Oder ich baue die "Filter Geschichte" auf dem "Überwachungspunkt" aus... Habe aber bei defekten Filterelementen ein Abschaltkriterium generiert welches gut an die Stelle passen würde...
 
Variablen symbolisch generieren geht leider nicht, daran scheitert auch bei mit immer die vielgerühmte "vollsymbolische" Programmierung. Man muß dann doch irgendwann wieder mit Any Pointern und Moven ;-)
 
Für die 1500er CPUs gibt es einen neuen SFC...

"TypeOf"
OPERANT:=[VARIANT]
Ret_Val:= [TYPE_ID; AOM_IDENT]

[TABLE="class: table_sourcecode, width: 100%"]
[TR]
[/TR]
[TR]
[/TR]
[TR]
[/TR]
[/TABLE]
Jetzt brauche ich noch einen SFC der durch eine Struktur wandern kann... :cool:
 
dim element as variant
for each (element in myStruct)
if typeof(element) = "UDT Name" then
element.UdtStrukturPfad = Wert
end if
next

Sowas ist (glaube ich) nicht wirklich machbar, da alles mit Variant auf die Verwendung von Arrays abzielt. MOVE_BLK_VARIANT und Konsorten.

Wenn du ein Array aus UDT_Druckaufnehmer machst und dieses als Variant übergibst könntest du zuerst auf TypeOf(Array) und TypeOfElements(UDT_Druckaufnehmer) prüfen. Wenn das OK ist kannst du die Elemente einzeln mit MOVE_BLK_VARIANT in einen Arbeitsbereich vom Typ UDT_Druckaufnehmer kopieren, die Daten bearbeiten, und wieder zurückschreiben. Mit CountOfElements weißt du wie viele Elemente im Array sind (for each).

Problem mit dem Array ist aber dass es keine Symbolik mehr gibt und du die Einträge nur mehr am Arrayindex unterscheiden kannst .
Hier scheitert für mich das "Vollsymbolisch Arbeiten mit Variant"-Konzept immer ein wenig wenn man Array verwenden muss und die gewünschte Symbolik verliert.

Hier gibt's ein paar nützliche Anwendungsbeispiele zu Variant
https://support.industry.siemens.co...-in-tia-v13-s71500/105159/?page=0&pageSize=10

Jetzt brauche ich noch einen SFC der durch eine Struktur wandern kann... :cool:
Genau den gibt es aber nicht.
Kenne keine Lösung wie man via Variant auf einen einzelnen Struct in "Struct-of-multiple-UDT" käme.
Hätte ich selber gerne.

Vollsymbolisch und mit optimierten Dbs wird das wohl nix...

Eine "Variante" der "indirekten Adressierung", mit der man es machen könnte, stellt dir Siemens dafür zumindest zur Verfügung....
https://support.industry.siemens.com/cs/mdm/109096785?c=69382039563&lc=de-WW
*ROFL*
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich bin gerade vor dem gleichen Problem und bin auf eine pragmatische Lösung gestoßen:

1. Codezeilen in SCL für die Übergabe vorbereiten

zb.

struct.druckumformer1.wert := ...


2. Kopieren des Codes in Word dann ist es möglich sämtliche Variablen mittels VBA Skript zu beschreiben

sieht dann so aus:

struct.druckumformer1.wert := ...
...
struct.druckumformer10.wert := ...
...
struct.druckumformer1000.wert := ...

usw.

3. wieder zurückkopieren

Das ist dann natürlich beliebig erweiterbar
 
Moin RONIN,

Mit CountOfElements weißt du wie viele Elemente im Array sind (for each).

Man kann auch eine Anwenderkonstante anlegen. Diese kann man dann bei der Array-deklaration eintragen.
Beispiel:
X_min; X_max als int
Im DB ein Array so anlegen:
TAG Array["X_min".."X_max"] of byte
Dann kann man eine for-Schleife mit den Anwenderkonstanten aufbauen. Natürlich gibt es da Einschränkungen (es gehen halt nur Anwenderkonstanten für die Arraydimension und die kann ich nicht zur Laufzeit ändern).



Problem mit dem Array ist aber dass es keine Symbolik mehr gibt und du die Einträge nur mehr am Arrayindex unterscheiden kannst .

Das stimmt nicht ganz, da man noch die einzelnen Array-Elemente separat kommentieren kann. Bei der Symbolik ist das natürlich richtig. Wir haben z.T. eine Structur mit der gleichen Anzahl an Elementen aufgebaut. Diese haben wir von der Structur in das Array kopiert.

VG

MFreiberger
 
Gruß, Retour.
Hmm.. schon ein wenig her der Beitrag. ;)

Man kann auch eine Anwenderkonstante anlegen...
Globale Anwenderkonstranten waren eine Möglichkeit.
Der Vorschlag mit dem CountofElements kam von der Vorlage des TE mit dem "for each" da dies eine Möglichkeit ist die Array-Dimensionen zur Laufzeit zu bestimmen.
Ob die Info zur Array-Dimmension nun von CountofElements oder Global-Konstante kommt hätte ab der Anwendung wohl nichts geändert.
...da man noch die einzelnen Array-Elemente separat kommentieren kann...
Arrays kann man einzeln kommentieren. Im Code steht aber trotzdem bei jeder Verknüpfung/Verwendung "Druckaufnehmer[12].Messwert" bzw. "Antriebe[92].Betrieb" etc.
Für mich hat das nicht viel mit Symbolik zu tun. Man könnte die Betriebsmittelbezeichnung als Globalkonstanten eintragen und als Array-Indizes verwenden... Von Doppelter Datenhaltung halte ich wenig. Um mit solchen Arrays eine schöne Symbolik zu bekommen ist viel Umweg nötig, soll aber nicht heißen dass sich das nicht für den Anderen lohnt.
 
Zuletzt bearbeitet:
Zurück
Oben