Das Thema mit den Array-Grenzen kann man eigentlich recht gut abfangen, indem man konsequent mit PLC-Konstanten oder lokalen Konstanten arbeitet, die die auch im Code verwendet. Das Thema Array-Überläufe kenne ich seit TIA V13 eigentlich gar nicht mehr.
Zum Thema FOR EACH - das ganze Konstrukt setzt einfach auf der Idee der Objektorientierung auf, die S7 einfach fehlt. Es macht einfach einen riesen Unterschied, ob man
- eine Funktion aufruft, welche über Datentypen bzw. deren Instanzen (also Variablen) iteriert oder
- über Objekte iteriert, die ihren eigenen Code mitbringen
Das Konstrukt mit AT auf unterschiedliche STRUCT ist ein Ansatz, den man mit C-89 gemacht hat, und der damals schon nicht gerne gesehen war. STRUCT ist ein Relikt und gehört imho eigentlich verboten - kein Wunder dass es sowas bei Rockwell oder B&R nicht gibt.

IMHO ist doch ein UDT letztendlich auch nur eine
global bekannt gemachte STRUCT.
Wenn man die Quelle davon exportiert, steht es ja auch am Beginn und Ende der eigentlichen Deklaration, z.B.:
...
Zunächst mal ein udt für die Motorendaten:
Code:
TYPE "typeMotorControl"TITLE = MOTOR CONTROL
VERSION : 0.1
STRUCT
...
END_STRUCT;
END_TYPE
...
Also
ich sehe da jetzt nicht den Unterschied in der Verwendung, nur in der Deklaration.
Davon ab, bei mir sind es immer UDT.
Im gewünschten Fall halt UDT, die reine (namentliche) Auflistungen eines anderen UDTs enthalten, aber eben kein ARRAY.
Das Array hat Vor- und Nachteile, genau wie die namentliche (Einzel-) Auflistung.
(Arraygrößen werden bei mir auch nur per Konstanten angegeben.)
Ich hab' statt der namentlichen Auflistung auch mit ARRAY und dann anstatt der Nummer mit "sprechenden" Konstanten für die einzelnen Member gearbeitet.
Aber die globalen Konstanten widersprechen wieder der Bausteinkapselung und die überall lokal zu deklarieren ist (zumindest für mich) auch nicht der Hit.
Die globalen Konstanten über die Bausteinschnittstelle zu übergeben geht auch nicht. Ganz davon abgesehen, dass man für Konstanten auch keine STRUCT/UDT deklarieren kann.
Per AT versuche ich nun mir ein wenig von beiden Vorteilen was zu ergaunern, nehme aber dafür wieder neue Nachteile in Kauf:
Warum muss ich mich z.B. um die Größe des überlagerten Arrays kümmern?
Könnte doch die Übersetzung genau wie bei Array[*] selbständig so groß festlegen, dass alle Daten reinpassen. Das findet ja schließlich alles außerhalb der PLC und nicht zur Laufzeit statt.
Und wenn die Größe der Originaldaten und die errechnete Größe des Array nicht zusammen passen, kann der Übersetzer einen Fehler rauswerfen, wie er es jetzt bei falscher Konstante für die Arraygröße auch nur macht.
Und wie gesagt, der Übersetzer kann IMHO doch schon offline prüfen: an der Stelle geht EACH - an der Stelle ist der Einsatz nicht möglich.