Step 7 Struktur eines Globalen DB in FB zuweisen

SPS-EK

Level-1
Beiträge
68
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Tag Kollegen und Freunde der Step7-Welt ;)

Ich steh irgendwie auf dem Schlauch und hoffe einer von Euch kann mir ein Tipp geben.
Ich möchte wie der Titel schon andeutet, eine Struktur eines Globalen DBs auf die Lokalenvariablen eines FBs zuweisen.
Der Gloable DB ist als Array of Struct angelegt und die jeweilige Struktur als UDT. Ebenso ist der Lokalbereich aufgebaut.
Den Globalen DB bzw. dessen Nummer möchte ich aber erst über einen Eingangsparameter definieren. Das ganze soll in SCL geschehen.

Die feste Zuweisung im Codeteil wie folgt ist kein Problem:
Code:
Struktur_local[1] := DBxx.Struktur[1]
aber ich möchte "DBxx" als Eingangsparameter des FB vorgeben, nur definiere ich den Übergabeparameter um im Codeteil keine feste DBNummer zu verwenden?:confused:

Danke schonmal im voraus
 
Hallo. Ich nehme an du bist in S7 Classic und der 300er Welt unterwegs oder?
Möchtest du die DB-Nummer wirklich zur Laufzeit ändern oder soll der Baustein einfach mit allen möglichen DBs parametrierbar sein ? Bei ersterem musst du wohl über Anypointer arbeiten, ansonsten würd ich einfach das Array of Struct als Inout deklarieren und im FB kopieren ider direkt damit arbeiten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo TP-Inc,

ja bin gerade in der Classicwelt unterwegs.
Nein, zur Laufzeit wird die DBNummer nicht geändert. Mein Fehler das hätte ich erwähnen sollen. :ROFLMAO:
Der Baustein bzw. die DBNr soll nur von ausserhalb parametrierbar sein, da er mehrmals verwendet wird.

Das Problem ist, dass mit Array of Struct als Inout der IDB zu groß wird, da die einzelne Struktur bzw. UDT schon sehr umfassend ist. Welche Möglichkeit gäbe es noch?
 
Guten Morgen,

wenn ich das als
Code:
Daten : ARRAY [1..x] OF STRUCT;
anlege bekomme ich beim Aktualisieren des Bausteintypen die Fehlermeldung: "F: <FB> kann nicht importiert werden, da der Parametertyp S7_ARRAY nicht unterstüzt wird."
Mache ich was falsch? Wenn Nein, welche Möglichkeit gibt es noch?
 
Zuletzt bearbeitet:
Hallo Erich,

Für das Array einen UDT definieren und den dann als Typ für den IN/OUT benutzen.
Gruß
Erich

Das geht leider auch nicht, da ich ja in dem Array noch ein Array habe. Ich kann dann den FB nicht über Bausteintypen aktualisieren. Da kommt immer der selbe Fehler.

Gibt es irgendwie die Möglichkeit die DBNr als Eingangsparameter zu nutzen um intern, wie folgt, darauf zuzugreifen?
Code:
Daten :=[B] DBNr[/B].Struct[1];
 
Zuletzt bearbeitet:
Ich habe in einigen Projekten sehr komplexe Datenstrukturen in einem MeinUDT definiert.
Die Daten liegen als UDT in einem DB (MeinDB.MeinUDT). Die FBs die diese Daten bearbeiten haben einen IN/OUT-Parameter vom Typ MeinUDT.
Beim Aufruf übergebe ich dann MeinDB.MeinUDT. Was soll da nicht klappen?
Gruß
Erich
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja genau das habe ich auch vor. Wie gesagt ich bekomme die Obige Fehlermeldung. Ich habe jetzt testweise das Array OF UDT2 aus dem UDT1 aufgebröselt auf ein UDT1 mit den ganzen Strukturen aber dann habe ich das Problem das ich am Bausteineingang in FUP nur die jeweilige Struktur auswählen kann aber nicht komplett.
Die Datenstrukturen sind auch relativ komplex da auch der IDB 49800 Byte im Arbeitsspeicher aufweist. Ich kann leider nicht noch die ganzen Strukturen entfernen, dann würde sich der Sinn und Zweck verfremden. Was es an sich ejtzt schon tut.

GIbt es nicht einfach die Möglichkeit in SCL über ein Eingangsparameter mit TYP INT die DBNr reinzuschreiben und im FB dies da so zugenerieren, dass man auf "DBxx" kommt, um dies dann mit der Jeweiligen Struktur weiterzuverwenden?
 
Zuletzt bearbeitet:
Ich glaube er möchte die Nr. des zu bearbeitenden DBs mit übergeben.
Ansonsten wie largod das beschrieben hat.
Code:
Var_Input
DBNr:Block_DB;
End_var
------------------------------------------
Daten :=[SIZE=5][B] [SIZE=2]DB[DBNr][/SIZE][/B][/SIZE].Struct[1];
 
Hallo Bapho,

da das andere nicht klappt, möchte ich genau diesen Weg gehen:

Ich glaube er möchte die Nr. des zu bearbeitenden DBs mit übergeben.
Ansonsten wie largod das beschrieben hat.
Code:
Var_Input
DBNr:Block_DB;
End_var
------------------------------------------
Daten :=[SIZE=5][B] [SIZE=2]DB[DBNr][/SIZE][/B][/SIZE].Struct[1];

Den Code
Code:
Daten_struct[1] := DB[NR].DB_struct[1];
klappt leider nicht, da wirft er mir die Fehler aus:
"Der Bezeichner (DB) existiert nicht." sowie "Ungültiger Datentyp eines ARRAY-Ausdrucks (NR)" sowie " Fehlerhafte Variable, der Punkt ist nicht zulässig".
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich bilde mir ein das mal so ähnlich gemacht zu haben, aber ist schon eine Weile her und ich habe hier gerade kein S7. Ich weiß nur das ich da auch ne Weile geknobelt habe. Die Variable Block_DB ist meines Wissens für sowas gedacht, aber wie jetzt die genau Syntax ist weiß ich nichtmehr. :(
 
Ich bilde mir ein das mal so ähnlich gemacht zu haben, aber ist schon eine Weile her und ich habe hier gerade kein S7. Ich weiß nur das ich da auch ne Weile geknobelt habe. Die Variable Block_DB ist meines Wissens für sowas gedacht, aber wie jetzt die genau Syntax ist weiß ich nichtmehr. :(


Ich hab sowas mal in AWL mit Pointern gemacht, aber ich suche eben die passende Lösung für SCL :)

Danke dir trotzdem schonmal, zumindest können jetzt andere lesen worauf ich hinaus will so dass ich die absolute Adressierung des GlobalenDB im FB über die Eingangsparameter leiten kann um dei Funktion mehrmals zu nutzen ohne diese intern anzupassen.
 
Moin,
wir verstehen schon was du möchtest, das geht eben aber nicht so wie du dir das vorstellst.
Man kann einem Baustein keine Nummer übergeben und dann via Bausteinnummer.Struct[1] symbolisch zugreifen, weil der Compiler ja überhaupt nicht wissen kann, wie die symbolische Struktur hinter deiner DB-Nummer aussieht. Stell dir vor, das würde so funktionieren und du schreibst außen nun eine andere DB-Nummer von einem völlig anders strukturierten DB dran - was sollte der Compiler dann tun?
Du kannst im Classic mit WORD_TO_BLOCK_DB auf einen variable DB zugreifen - das geht dann aber nur noch absolut, nicht symbolisch.
Die bereits vorgeschlagenen Lösungen mit der Übergabe einer UDT sind da meiner Meinung nach schon zielführender bzw. lesbarer.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Howard,

Moin,
wir verstehen schon was du möchtest, das geht eben aber nicht so wie du dir das vorstellst.
Man kann einem Baustein keine Nummer übergeben und dann via Bausteinnummer.Struct[1] symbolisch zugreifen, weil der Compiler ja überhaupt nicht wissen kann, wie die symbolische Struktur hinter deiner DB-Nummer aussieht. Stell dir vor, das würde so funktionieren und du schreibst außen nun eine andere DB-Nummer von einem völlig anders strukturierten DB dran - was sollte der Compiler dann tun?

Ja und? Das wäre super und würde viele Probleme lösen. Abgesehen davon hat keiner was zu verändern der unfähig ist, das richtige Vorgehen in der Bausteininfo nachzulesen, so dass dann nur die DBNr dran gehört zu dem entsprechenden GlobalenDB. Da seh ich kein Problem und mittels Pointern in AWL gibt es ja auch Möglichkeiten. Nur ist das nunmal SCL und das soll auch konform sein.

Du kannst im Classic mit WORD_TO_BLOCK_DB auf einen variable DB zugreifen - das geht dann aber nur noch absolut, nicht symbolisch.
Die bereits vorgeschlagenen Lösungen mit der Übergabe einer UDT sind da meiner Meinung nach schon zielführender bzw. lesbarer.

Es wäre zielführender keine Frage. Leider ist es aber nunmal so, dass das nicht funktioniert weil entweder der Bausteintyp nach dem Compilieren nicht aktualisiert werden kann oder man keine Eingabe am Eingangsparameter tätigen kann. Daher der Zugang zu den Variablen über Absoluteadressierung, nur auch das muss gehen um die DB Nr von aussen einzugeben.
 
nochmal kurz aus der Siemens-Hilfe (Classic) zusammengetragen
Indizierter Zugriff DB:
Code:
STATUS_1:= DB11.DW[ZAEHLER]; 
STATUS_2:= DB12.DX[WNR, BITNR]; 
STATUS_1:= Datenbasis1.DW[ZAEHLER]; 
STATUS_2:= Datenbasis2.DX[WNR, BITNR]; 
[COLOR=#0000ff]STATUS_1:= WORD_TO_BLOCK_DB(INDEX).DW[ZAEHLER]; [/COLOR]
 
nochmal kurz aus der Siemens-Hilfe (Classic) zusammengetragen
Indizierter Zugriff DB:
Code:
STATUS_1:= DB11.DW[ZAEHLER]; 
STATUS_2:= DB12.DX[WNR, BITNR]; 
STATUS_1:= Datenbasis1.DW[ZAEHLER]; 
STATUS_2:= Datenbasis2.DX[WNR, BITNR]; 
[COLOR=#0000ff]STATUS_1:= WORD_TO_BLOCK_DB(INDEX).DW[ZAEHLER]; [/COLOR]

Jetzt bräuchte man nur noch eine Möglichkeit wie man die gesamte Struktur/das gesamte UDT auswählen und übertragen kann :)
Gabs da nicht sowas wie Read/Writebausteine? Blockmove? oder sowas?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jetzt bräuchte man nur noch eine Möglichkeit wie man die gesamte Struktur/das gesamte UDT auswählen und übertragen kann :)
Gabs da nicht sowas wie Read/Writebausteine? Blockmove? oder sowas?

Also jetzt nicht verwechseln - der oben von mir zitierte, indizierte DB-Zugriff geht natürlich nur Bit, Byte, Word oder DWord-weise.
Wenn du dein Problem mit einem BLKMOV Lösen willst, dann brauchst du natürlich wieder Pointer ;)
Code:
      CALL  "BLKMOV"
       SRCBLK :=#qany // Quell-Any
       RET_VAL:=#intRet
       DSTBLK :=#zany  // Ziel-Any
 
Also jetzt nicht verwechseln - der oben von mir zitierte, indizierte DB-Zugriff geht natürlich nur Bit, Byte, Word oder DWord-weise.
Wenn du dein Problem mit einem BLKMOV Lösen willst, dann brauchst du natürlich wieder Pointer ;)
Code:
      CALL  "BLKMOV"
       SRCBLK :=#qany // Quell-Any
       RET_VAL:=#intRet
       DSTBLK :=#zany  // Ziel-Any

Mhhh...naja ich will mein Problem so lösen das es zum einen SCL-Konform und zum anderen der DB von Aussen auswählbar ist.
 
Zurück
Oben