Set Reference to Group Field; Assign a Value

Have to believe I’ve done this before, but no memory now. Little hair left to scratch.
Need something like:
MyGroup GROUP
A CSTRING(31)
B CSTRING(31)
C CSTRING(31)
END
MyRef &CSTRING

CODE
MyRef &= WHAT(MyGroup,1)
MyRef = ‘Some string value’

Gives an illegal reference assignment. What am I missing?

Change
MyRef &CSTRING
to
MyRef ANY

Thank you. Amazing what a small change can do.

If you really need it as the original data type, you can get at it with my private class https://github.com/jslarve/PrivateClass

But otherwise, the ANY is simpler.

For educational purposes, at the least, I will give it a look. Thanks for pointing it out.

A GROUP acts as a STRING not a CSTRING. I Think it would work if you made MyRef a STRING.

WHAT is returning a reference to the field in the group. Not the group itself.

Witches are made of wood.

WHAT() doesn’t return a specific data type.

Like with an ANY, you can get a value or a reference of a particular field within the structure. The overall GROUP being similar to a STRING is irrelevant to what WHAT() returns.

e.g.

MyValue = WHAT(MyGroup,xx) !Just reading the value
or
MyAny &= WHAT(MyGroup,xx) !Getting an ANY reference
MyAny = 'Yada' !Writing the value

I entered a PTSS for browses not being able to handle arrays in a list. Yesterday, I noticed that this MAY also include group fields. While I haven’t looked further yet, I’m wondering if the details you note might be involved, perhaps in something like the FieldPairsClass not referencing and then assigning the values?

Have you got an example of your suspicion/wonderment?

No simple example yet. Yesterday, as a work around for the array issue, I tried using a group instead.

For the particular browse, the group (or array) is passed to a function to receive formatted strings.
The debugger showed that the group field values were correct just prior to the parent call in BrowseClass.SetQueueRecord. However, the corresponding queue field values were only a single character after the parent call. Because the FieldPairsClass does the assignment, my “wonderment” is placed there.

Looks like the problem occurs because the templates do not correctly generate queue field declarations when a group field is included. For instance:

MyGroup GROUP,PRE(My)
A CSTRING(21)
B CSTRING(21)
END

Generates in the queue as:
My:A STRING(1)
My:B STRING(1)

Leaving out the prefix also creates an error because dot syntax can’t be included within the queue:
BrowseQueue QUEUE
MyGroup.A STRING(1)
MyGroup.B STRING(1)
END

If you or anyone knows the template fix, I’d be happy to hear it.

Can try PRE() then put the Pre: on each variable:

MyGroup GROUP,PRE()
My:A CSTRING(21)
My:B CSTRING(21)
   END

What’s wrong with generating in the queue as

My:A  STRING(1)
My:B  STRING(1)

String length gets cut to 1. Makes for a very brief display value.

ah, that would matter

Gotta believe a template fix is not too difficult. Doubt SV will ever get around to it.

This issue was analysed in the OpenClarion webinar for Wednesday October 28, 2020 - and can be viewed on YouTube here at https://www.youtube.com/watch?v=O2usIu93A0g

I’ve also reported it in the PTSS system (PTSS #43130). In that PTSS I’ve submitted the recommended template change (by downloading the ZIP attached to that PTSS you’ll see the change.) The correct change is somewhat extensive, but a “simple” change you can apply in the meantime is to change the String(1) to String(255).

In ABOOP.TPW search for the lines;

  #SET(%FComment, %FComment & ' - unable to determine correct data type')
  #SET(%RVal, 'STRING(1)')

And replace the 1 with 255. As in

  #SET(%FComment, %FComment & ' - unable to determine correct data type')
  #SET(%RVal, 'STRING(255)')

cheers
Bruce

I believe the “somewhat extensive correct template change” involves corrections to the INLIST lines that attempt to find a variable in local, module, or global data. Just wondering if you or anyone else has yet gone down this path?

Bruce is offline. I suggested %LocalDataFull and he came with the below code. I’m not sure how much he has tested it, I have not. Note Global and Module are not coded the same as Local, but I think it would work because %GlobalDataStatement should be blank

#FIND(%LocalDataFull, %FLabel)
#IF(%LocalData)
  #SET(%Declr, %LocalDataStatement)
  #SET(%FComment, %FComment & ' - type derived from local data')
#ENDIF
#IF(%Declr='')
  #FIND(%GlobalDataFull, %FLabel)
  #SET(%Declr, %GlobalDataStatement)
  #SET(%FComment, %FComment & ' - type derived from global data')
#ENDIF
#IF(%Declr='')
  #FIND(%ModuleDataFull, %FLabel)
  #SET(%Declr, %ModuleDataStatement)
  #SET(%FComment, %FComment & ' - type derived from module data')
#ENDIF
#IF(%Declr='')
  #FIND(%Field, %FLabel)
  #IF(%Field = %FLabel)
    #IF(SUB(%FieldType, 1, 5) = 'GROUP')
      #SET(%FComment, %FComment & ' - STRING defined to hold GROUP''s contents')
    #ELSIF(%FieldType = 'MEMO')
      #SET(%FComment, %FComment & ' - STRING defined to hold MEMO''s contents')
    #ELSE
      #SET(%FComment, %FComment & ' - type derived from field')
    #END
    #SET(%Declr, %FieldStatement)
  #ENDIF
#ENDIF