TIA Array of String füllen mit String

volker

Supermoderator
Teammitglied
Beiträge
5.805
Reaktionspunkte
1.027
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich mchte gerne ein Array of String mit einem String füllen aber gekapselt in einem FC/FB. Ähnlich dem sfc21 fill

Also als Eingangsparameter.
In diesem Fall "DB_Allgemein".ID_reset (string[10]) und "DB_L2_HU".diese.ID array [1..30] of string[10] und Anzahl der Wiederholungen.


Das funktioniert ist aber halt nicht gekapselt
Code:
//IF #hilfsbit THEN
//    FOR #index := 1 TO 30 DO
//        "DB_L2_HU".diese.ID[#index] := "DB_Allgemein".ID_reset;
//    END_FOR;
//    "DB_L2_HU".diese.Anzahl := 0;
//END_IF;
 
Als In1 Variable MyString vom Typ String[10].
Als In2 Variable Anzahl vom Typ Int
Als InOUT3 Variable MyStringArray vom Typ Array[1..10] of String[10]

Aufruf dann:

Code:
"MyFB_IDB"(MyString := "DB_Allgemein".ID_reset,
           Anzahl := 10
           MyStringArray :="DB_L2_HU".diese.ID);


Meinst du so etwa?

Das Array[1..10] of String[10] sollte man eigentlich als Datentyp definieren, dann kann man diesen in den DB und an den INOUT des FC/FC schreiben und hat bei Äbderungen nicht so viele Fehlerquellen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
ja so in etwa.
so wie du das geschrieben hast funktioniert das. ist aber völlig unflexibel man müsste dann jedesmal den fc anpassen wenn sich die stringlänge oder die anzahl der arrayelemante ändert. dann kann man genausogut ein scl-netzwerk einfügen.
problematisch ist halt der inout.
 
Du kanst für die Stringlänge und die Arraylänge Konstanten einsetzen, die du in der Variablentabelle unter Konstanten (Reiter oben) mit Namen und Wert einträgst.
Dann reicht es einmal beim Projektstart oder, wenn man das Projekt anpassen muß, dies zu ändern und die Software zu übersetzen. Während der Laufzeit kann man die Länge nicht ändern, aber da erzähle ich dir sicher nichts Neues.

Hier haben wir wirklich mal ein nettes Gimmick vom TIA-Portal, aber Step7 konnte das ähnlich, nur mit viel mehr Aufwand.
 
Hallo Volker,

wenn du die String- bzw. Array-Parameter als Variant deklarierst, und von außen bei beiden ARRAYs übergibst, dann kannst du im Baustein MOVE_BLOCK_VARIANT ganz einfach in einer Schleife aufrufen. Der Kompromiss wäre, den zu übergebenden Init-String in z.Bsp. ein Array[1..1] of String[x] zu verpacken. Die Länge 'x' muss mit der Stringlänge der Strings des Arrays übereinstimmen, muss aber nicht bekannt sein. Weitere Typ-Prüfungen und RET_VAL-Auswertungen sind eventuell zu empfehlen.

Code:
IF IS_ARRAY(#STRING_ARRAY) THEN
    #ANZAHL_ELEMENTE := CountOfElements(#STRING_ARRAY);
END_IF;

FOR #n := 0 TO UDINT_TO_DINT(#ANZAHL_ELEMENTE-1) DO
    #TEMP_INT := MOVE_BLK_VARIANT(SRC := #INIT_STRING, COUNT := 1, SRC_INDEX := 0, DEST_INDEX := #n, DEST => #STRING_ARRAY);
END_FOR;


Gruß, Onkel
 
Das wäre meine Lösung:

Code:
FUNCTION "StrFill" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      n : DInt;
   END_VAR

   VAR_IN_OUT 
      dest : Array[*] of String;
      source : String;
   END_VAR

   VAR_TEMP 
      lb : DInt;
      i : DInt;
   END_VAR


BEGIN
	#lb := LOWER_BOUND(ARR:=#dest, DIM:=1);
	FOR #i := #lb TO (#lb+#n-1) DO
	    #dest[#i] := #source;
	END_FOR;
	
END_FUNCTION
 
auch ok.

an onkelz lösung gefällt mir, dass ich nicht die anzahl derr elemente eingeben muss.
deine variante hätte den vorteil, dass man auch nur einen teil des arrays beschreiben kann.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich mchte gerne ein Array of String mit einem String füllen aber gekapselt in einem FC/FB. Ähnlich dem sfc21 fill

Also als Eingangsparameter.
In diesem Fall "DB_Allgemein".ID_reset (string[10]) und "DB_L2_HU".diese.ID array [1..30] of string[10] und Anzahl der Wiederholungen.


Das funktioniert ist aber halt nicht gekapselt
Code:
//IF #hilfsbit THEN
//    FOR #index := 1 TO 30 DO
//        "DB_L2_HU".diese.ID[#index] := "DB_Allgemein".ID_reset;
//    END_FOR;
//    "DB_L2_HU".diese.Anzahl := 0;
//END_IF;

Gemäß dem ursprünglichen Eintrag war ich davon ausgegangen, dass die Anzahl der Wiederholungen eingebbar sein muss.
Das gesamte Array füllt natürlich dann der folgende Code:
Code:
FUNCTION "StrFill" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_IN_OUT 
      dest : Array[*] of String;
      source : String;
   END_VAR

   VAR_TEMP 
      lb : DInt;
      ub : DInt;
      i : DInt;
   END_VAR


BEGIN
	#lb := LOWER_BOUND(ARR:=#dest, DIM:=1);
	#ub := UPPER_BOUND(ARR:=#dest, DIM:=1);
	FOR #i := #lb TO #ub DO
	    #dest[#i] := #source;
	END_FOR;
	
END_FUNCTION
 
@maxder2te

Wollte gerade mal deine Variante testen.
Funktioniert leider nicht.
 

Anhänge

  • Zwischenablage02.jpg
    Zwischenablage02.jpg
    127,2 KB · Aufrufe: 35
Zuviel Werbung?
-> Hier kostenlos registrieren
.. PERFEKT. Genau das was ich haben wollte ..
Gern geschehen. Das bringt ja deine ".. Definition von TIA: Total Inakzeptable Applikation" total ins Wanken.
Vor gut zwanzig Jahren gab es mal einen Volker, der hatte sich vor SCL gesträubt. Kennst du den?

:ROFLMAO:ROFLMAO:ROFLMAO:
 
Früher (TM) bei Step7 konnte man sich mit zwei Any-Pointern noch eine Universal-Array-Initialisierungsfunktion schreiben, die Arrays beliebigen Datentyps initialisieren konnte.

Wenn man hier so liest was die Verwendung von Variant für seltsame Effekte und Bugs mitbringt, würde ich die Finger davon lassen.
 
Was ich mich schon öfter gefragt habe wenn ich CountOfElements benutzt habe...
Gibt es eine Möglichkeit den StartIndex dynamisch zu bestimmen wenn das Array mal nicht bei 0 beginnt, so ala LBound?
Wenn man mit Variant arbeitet, beginnt der Array-Index immer bei "0", egal wo der Bereich des Aktualparameters beginnt und endet. Das hat aber auch Vorteile bezüglich der Flexibilität.
 
Ich fange Array grundsätzlich mit 0 an. Bleibt die 0 eben ungenutzt, wenn nicht benötigt. Hat Vorteile, falls eine Index-Variable nach Initialisierung auch mal 0 sein kann. Ansonsten immer Bereiche abfragen.
Will man ein Array auch an die HMI übergeben bzw. dort nutzen (Stichwort Multiplex) fängt das HMI-Array immer (intern) mit 0 an, man merkt es dann an einer Verschiebung der Daten im Array und wundert sich.
 
Zurück
Oben