Reputation: 485
I have an array of a structure: myStructure[0..100]
I would like to index that structure by name.
It works by giving each index a name:
P101_AI := 9
P102_AI := 10
P103_AI := 11
P104_AI := 12
So indexing a member in the structure: myStructure[P103_AI].value
(i.e. indexing myStructure[11].value)
However, is it possible to index this indirectly?
i.e. if delcaring TempString : STRING[30];
altering TempString at runtime to index the array.
Here is some pseudocade to describe what I would like to do:
FOR i:=101 TO 104 DO
TempString := CONCAT('P',i);
TempString := CONCAT(TempString,'_AI');
MyStructure[ indirect(TempString)].value := 'some value';
END_FOR;
Upvotes: 0
Views: 2240
Reputation: 485
This is how i solved it.
TYPE infoType: STRUCT
name: STRING[20];
END_STRUCT
END_TYPE
TYPE sensorType: STRUCT
value: INT;
info: infoType;
END_STRUCT
END_TYPE
TYPE IO_Type: STRUCT
AI: ARRAY[1..100] OF sensorType;
END_STRUCT
END_TYPE
TYPE E_AnalogInput :
(
P101_AI := 9,
P102_AI,
P103_AI,
P104_AI
);
END_TYPE
PROGRAM PLC_PRG:
VAR
IOs: IO_Type;
END_VAR
IOs.AI[P101_AI].info.name := 'P101_AI';
FOR i:=101 TO 104 DO
TempString := CONCAT('P',i);
TempString := CONCAT(TempString,'_AI');
FOR i:=0 TO SIZE_OF(ADR(IOs.AI)) / SIZE_OF(ADR(IOs.AI[0])) DO
IF TempString = IOs.AI[i].info.name THEN
IOs.AI[i].value := 123; // Some value
EXIT;
END_IF;
END_FOR;
END_FOR;
END_PROGRAM
Upvotes: 0
Reputation: 98
What about creating an enum?
{attribute 'qualified_only'}
TYPE E_AnalogInput :
(
P101_AI := 9,
P102_AI,
P103_AI,
P104_AI
);
END_TYPE
Then you can declare:
analogInputs : ARRAY[E_AnalogInput.P101_AI..E_AnalogInput.P104_AI] OF INT;
Running a for loop:
FOR inputCount:=E_AnalogInput.P101_AI TO E_AnalogInput.P104_AI BY 1 DO
//Do something
END_FOR
Hope this helps
Upvotes: 1
Reputation: 3080
I would use pointers and mapping. First, change your structure to the pointer.
TYPE MyType: STRUCT
input: POINTER TO INT;
value: INT;
// other properties
END_STRUCT
END_TYPE
Then, create a global array.
VAR_GLOBAL
MyStructure: ARRAY[1..100] OR MyType;
END_VAR
Now in a program create one time running code.
PROGRAM PLC_PRG:
VAR
xInit:= FALSE;
END_VAR
IF NOT xInit THEN
xInit := TRUE;
mMap();
END_IF
END_PROGRAM
Now in a method or action mMap
do this for every array element.
MyStructure[1].input:= ADR(AI_Name);
MyStructure[2].input:= ADR(P102_AI);
MyStructure[3].input:= ADR(%ID0.1);
I used 3 different ways to bind pointer. The order is not important I think. Then in a program, you can do this.
FOR i := 1 TO 100 DO
MyStructure[i].value := 'MyStructure[i].input^;
END_FOR;
Upvotes: 0