I think this is a better approach :

Code:
Use Windows.pkg

// changes in STRUCT and END_STRUCT to get a constant NameOfStruct_N
// with the number of members of the struct.
// new commands are STRUCT_ and END_STRUCT_ ,
// also STRUCT_SCALAR_MEMBER and STRUCT_ARRAY_MEMBER are modified.
// only DAW can change the originals in Fmac
// these commands can be used, but CodeSense is lost
//

// original name in FMAC = STRUCT_SCALAR_MEMBER
// sentence added = #SET M$ ! M
#COMMAND STRUCT_SCALAR_MEMBER_ R R
  #PUSH !q
  #DTYPE Q$ !1        // get the property type in q
  #IF (!q =-1)
    #ERROR DFERR_COMP_INVALID_DATATYPE (!1)
  #ELSE
    #SET M$ !M
    #IF (!q=19)
      #PUSH !h
      #STRG H$ !1
      #STRM Struct |CI!h !2
      #POP H$
    #ELSE
      #STRM SCALAR |CI!q !2
    #ENDIF
  #ENDIF
  #POP Q$
#ENDCOMMAND

// original name in FMAC = STRUCT_ARRAY_MEMBER
// sentence added = #SET M$ ! M
#COMMAND STRUCT_ARRAY_MEMBER_ T R R
  #SET M$ !M
  #DATA
  ARRAY_DIM_SIZE_HELPER !2 !3 !4 !5 !6 !7 !8 !9
  STRUCT_ARRAY_TYPE_HELPER !1
  #SET Q$ 0
  ARRAY_DIM_COUNT_HELPER !2 !3 !4 !5 !6 !7 !8 !9 // sets !q to num of dims
  #DPUSH |CI!q //Push the number of dimensions
  STRUCT_ARRAY_MEMBER_HELPER !2 !3 !4 !5 !6 !7 !8 !9
#ENDCOMMAND

// this replacements are needed to use the modified commands ... 
// not necessary If the originals were modified (only DAW can do it !!!)
#Replace STRUCT_SCALAR_MEMBER STRUCT_SCALAR_MEMBER_
#Replace STRUCT_ARRAY_MEMBER STRUCT_ARRAY_MEMBER_

// original name in FMAC = Struct
// sentences added =     #SPUSH          // save value of !$
//                      #SPUSH !1       // save name of struct
//                      #SET M$ 0       // set counter of members of struct 
#COMMAND Struct_ R
  #IFDEF __@INSIDE_STRUCT@__
    #ERROR DFERR_COMP_ILLEGAL_CODE_PLACEMENT "STRUCT command within a STRUCT. Structs cannot be Nested"
  #ELSE
    #STRU !1
    #SREP __@INSIDE_STRUCT@__   |CI1   // lets other commands check that they are inside a struct scope.
    #SPUSH          // save value of !$
    #SPUSH !1       // save name of struct
    #SET M$ 0       // set counter of members of struct 
  #ENDIF
#ENDCOMMAND

// original name in FMAC = End_Struct
// sentences added =     #SPOP                  // retrieve name of struct
//                      Define !$_N for !m     // define constant with number of members of struct
//                      #SPOP                  // retrieve previous value of !$  
#COMMAND End_Struct_
  #IFNDEF __@INSIDE_STRUCT@__
    #ERROR DFERR_COMP_ILLEGAL_CODE_PLACEMENT "END_STRUCT command without STRUCT"
  #ELSE
    #STRE
    #UNDEF __@INSIDE_STRUCT@__ // Leaving struct declaration
    #SPOP                  // retrieve name of struct
    Define !$_N for !m     // define constant with number of members of struct
    #SPOP                  // retrieve previous value of !$  
  #ENDIF
#ENDCOMMAND

// new COMMAND : LOADSTRUCT
// to load a struct from an array
// ==============================
// first parameter : name of the structure
// second parameter : constant with the Number of members of the structure
// (you can use the constant from the previous modified structure commands or ...
//  set a constant of yourself using the standard Struct command)
// (do not use a variable ...)
// third parameter : from
// fourth parameter : array with the data
// fifth parameter (optional) : ordinal Number of member in the structure, which is an array or another structure
// sixth parameter (optional) : name of the array or structure to copy on the member mentioned in the fifth parameter
// 7th/8th , 9th/10th, ..., parameters (optionals) : pairs of parameters similar to 5th and 6th parameters
#COMMAND LOADSTRUCT R R "FROM" R
    #SET J$ 0
    LOADSTRUCT1 !1 !2 !1CI!j !4 !5 !6 !7 !8 !9
#ENDCOMMAND

#COMMAND LOADSTRUCT1 R R R R
  #IF !j<!2
    #IF !0>4
      #SET K$ (!5 - 1) 
      #IF !j=!k
        Move (!6) to !3
      #ELSE
        Move !4[!j] to !3
      #ENDIF  
    #ELSE
      Move !4[!j] to !3
    #ENDIF   
    #SET J$ !J
    #IF !0>4
      #IF !j=!5
        LOADSTRUCT1 !1 !2 !1CI!j !4 !7 !8 !9
      #ELSE
        LOADSTRUCT1 !1 !2 !1CI!j !4 !5 !6 !7 !8 !9
      #ENDIF  
    #ELSE
      LOADSTRUCT1 !1 !2 !1CI!j !4
    #ENDIF   
  #ENDIF 
#ENDCOMMAND
    
Struct_ tarray
    String sname
    String ssurname
End_Struct_

Struct_ tTest 
    String sName
    Integer iYear
    tarray[] gentes
End_Struct_

Struct_ tTestXX 
    String sCod
    Integer iNum
    tTest stTest
    String[] cadenas
    Integer ixxx
End_Struct_

    Procedure DoTest Global
        Integer i
        tTest   MyData
        tTest[] MyDataArray
        String[] sData
        String[][] sDataArray
        String[] scads
        tTestXX otroTest
        tarray[] tgente
        tarray[][] tgentes
        
        Send loadData (&sData) (&sDataArray) (&scads) (&tgente) (&tgentes)
        
        Showln "single struct"
        loadstruct MyData tTest_N from sData 3 tgente
        Showln MyData.sName " " MyData.iYear " " MyData.gentes[0].sname " " MyData.gentes[0].ssurname " " tTest_N
        
        loadstruct otroTest tTestXX_N from sData 3 MyData 4 scads
        Showln otroTest.sCod " " otroTest.iNum " " otroTest.stTest.sName " " otroTest.stTest.iYear " " otroTest.stTest.gentes[2].sname " " otroTest.stTest.gentes[2].ssurname " " otroTest.cadenas[2] " " otroTest.ixxx " " tTestXX_N 
        
        Showln     
        Showln "array struct"
        
        For i from 0 to 3
           loadstruct MyDataArray[i] tTest_N from sDataArray[i] 3 tgentes[i]
           Showln MyDataArray[i].sName " " MyDataArray[i].iYear " - " MyDataArray[i].gentes[1].sname " " MyDataArray[i].gentes[1].ssurname " - " MyDataArray[i].gentes[2].sname " " MyDataArray[i].gentes[2].ssurname " - " tTest_N
        Loop
        
    End_Procedure
    
    Procedure loadData String[] ByRef sData String[][] ByRef sDataArray String[] ByRef scads tarray[] ByRef tgente tarray[][] ByRef tgentes
        Move "Juan Diego" to tgente[0].sname
        Move "Flórez" to tgente[0].ssurname
        Move "Luciano" to tgente[1].sname
        Move "Pavarotti" to tgente[1].ssurname
        Move "José" to tgente[2].sname
        Move "Carreras" to tgente[2].ssurname

        Move "pancho" to sData[0]
        Move 1790 to sData[1]
        Move 1877 to sData[4]

        Move "cad01" to scads[0]
        Move "cad02" to scads[1]
        Move "cad03" to scads[2] 

        Move "juan" to sDataArray[0][0]
        Move 1907 to sDataArray[0][1]
        Move "pedro" to sDataArray[1][0]
        Move 1908 to sDataArray[1][1]
        Move "martin" to sDataArray[2][0]
        Move 1909 to sDataArray[2][1]
        Move "luis" to sDataArray[3][0]
        Move 1910 to sDataArray[3][1]

        Move tgente to tgentes[0]
        Move "Peter" to tgentes[1][0].sname
        Move "Parker" to tgentes[1][0].ssurname
        Move "Julia" to tgentes[1][1].sname
        Move "Roberts" to tgentes[1][1].ssurname
        Move "Robert" to tgentes[1][2].sname
        Move "Redford" to tgentes[1][2].ssurname
        Move "George" to tgentes[2][0].sname
        Move "Handel" to tgentes[2][0].ssurname
        Move "Johann" to tgentes[2][1].sname
        Move "Bach" to tgentes[2][1].ssurname
        Move "Frédéric" to tgentes[2][2].sname
        Move "Chopin" to tgentes[2][2].ssurname
        Move "Leonardo" to tgentes[3][0].sname
        Move "da Vinci" to tgentes[3][0].ssurname
        Move "Pablo" to tgentes[3][1].sname
        Move "Picasso" to tgentes[3][1].ssurname
        Move "Vincent" to tgentes[3][2].sname
        Move "van Gogh" to tgentes[3][2].ssurname
    End_Procedure
   
Send DoTest
Send Info_Box "end of loop"
best regards
Ivan Schoof