Page 1 of 1
Pass name of field to subroutine and then refer to real field
Posted: Tue Jun 30, 2020 6:57 pm
by Joop
Hi all,
I'm wondering if it is possible in some way to pass the
name of a (repository) field to a subroutine and in that subroutine do something with the
actual field (i.e. make it readonly):
Code: Select all
Execute Subroutine(Set_Field) With_Parms('GRANAV' 'Y')
Execute Subroutine(Set_Field) With_Parms('GRAHAN' 'N')
Subroutine Name(Set_Field) Parms((#FIELDNAME *RECEIVED) (#READONLY *RECEIVED))
If (#READONLY = 'Y')
/* Make real field read only */
#FIELDNAME.ReadOnly := True
Else
#FIELDNAME.ReadOnly := False
Endif
Endroutine
Re: Pass name of field to subroutine and then refer to real field
Posted: Wed Jul 01, 2020 2:23 am
by caseywhite
You can't use a subroutine but you can use a method routine. You can pass in the object to a method and have the method manipulate the object. If all objects will be of the same type use the approach in umSetReadOnly2 otherwise you could use the approach in umSetReadOnly where you receive a PRIM_OBJ and then check the type to see how you will set it to read only. Sounds like in your case you can use the umSetReadOnly2 approach but wanted to show that you can do more than just pass a single class type to a method.
Code: Select all
Begin_Com Role(*EXTENDS #PRIM_WEB) Theme(#SYS_THEME<MaterialDesignBlue>)
Define_Com Class(#PRIM_MD.RaisedButton) Name(#Button) Caption('PRIMARY') Displayposition(1) Left(48) Parent(#COM_OWNER) Tabposition(1) Themedrawstyle('MediumTitle') Top(45)
Define_Com Class(#PRIM_MD.RaisedButton) Name(#Button1) Caption('ACCENT') Displayposition(2) Left(160) Parent(#COM_OWNER) Tabposition(2) Themedrawstyle('MediumAccent') Top(52)
Define_Com Class(#PRIM_MD.FlatButton) Name(#Button2) Caption('PRIMARY') Displayposition(3) Left(80) Parent(#COM_OWNER) Tabposition(3) Themedrawstyle('Borders1+BorderTheme500+ForegroundMediumPrimary') Top(161)
Evtroutine Handling(#Com_owner.Initialize)
Endroutine
Evtroutine Handling(#Button2.Click)
#com_owner.umSetReadOnly( #Button True )
#com_owner.umSetReadOnly( #Button1 False )
Endroutine
Mthroutine Name(umSetReadOnly)
Define_Map For(*INPUT) Class(#PRIM_OBJT) Name(#pObj) Pass(*BY_REFERENCE)
Define_Map For(*INPUT) Class(#PRIM_BOLN) Name(#pReadOnly)
Case Of_Field(#pobj.ComponentTypeName)
When Value_Is(= 'PRIM_MD.RaisedButton')
(#pobj *As #prim_md.RaisedButton).Enabled := #pReadOnly
Endcase
Endroutine
Mthroutine Name(umSetReadOnly2)
Define_Map For(*INPUT) Class(#PRIM_MD.RaisedButton) Name(#pObj) Pass(*BY_REFERENCE)
Define_Map For(*INPUT) Class(#PRIM_BOLN) Name(#pReadOnly)
#pObj.Enabled := #pReadOnly
Endroutine
End_Com
Re: Pass name of field to subroutine and then refer to real field
Posted: Wed Jul 01, 2020 4:44 pm
by Joop
Hi Casey,
Thanks for your input! I will try if that works for me. I was also considering using a keyed collection of fields (with the key being the name of the field).
Re: Pass name of field to subroutine and then refer to real field
Posted: Wed Jul 01, 2020 7:35 pm
by Joop
Hi Casey,
I don't think your solutions works for me. I'm using a reusable part with some fields on it. Not every user can view and/or update the fields. I wanted to make a generic subroutine / mthroutine to determine if a passed field should be read-only or visible at all. The code below does not work.
Code: Select all
Define_Com Class(#GRANAV.Visual) Name(#GRANAV) ComponentVersion(1) DisplayPosition(12) Left(16) Parent(#Panel_Algemeen_Top) TabPosition(6) Top(76) MarginLeft(120) Width(350)
Define_Com Class(#GRAHNM.Visual) Name(#GRAHNM) DisplayPosition(13) Left(16) Parent(#Panel_Algemeen_Top) TabPosition(7) Top(98) Width(350) MarginLeft(120) Height(19)
Mthroutine Name(uExecute) Options(*Redefine)
#COM_OWNER.uSetField( #GRANAV )
Value #GRANAV is not valid for parameter pField
#COM_OWNER.uSetField( #GRAHNM )
Value #GRAHNM is not valid for parameter pField
Endroutine /* uExecute */
Mthroutine Name(uSetField)
Define_Map For(*Input) Class(#FIELDNAME.Visual) Name(#pField) Pass(*By_Reference)
#RMARD #RMAUPD := J
#FIELDNAME := #pField.Name
* Check field authority for *USER
Fetch Fields(#RMARD #RMAUPD) From_File(ZNPRMA) With_Key(*USER *Z03_RMSTPA_C *COMPONENT #FIELDNAME)
If (#RMARD = N)
#pField.Visible := False
Endif
If (#RMAUPD = N)
#pField.Enabled := False
#pField.VisualStyle <= #ZVSRDONLY
Endif
Endroutine /* uSetField */
I'm going to look into the keyed collection but not sure if that would work either.
Re: Pass name of field to subroutine and then refer to real field
Posted: Thu Jul 02, 2020 1:20 am
by caseywhite
I think you just need to change the class of the define_map in uSetField. It should be #PRIM_EVEF not #FIELDNAME.Visual. You can figure out the class to use by going to the Outline view. Right click on the fields and you will see the PRIM class for the fields is PRIM_EVEF. See the simplified code below.
Code: Select all
Define_Com Class(#STD_TEXT.Visual) Name(#STD_TEXT) Componentversion(1) Displayposition(1) Left(16) Parent(#COM_OWNER) Tabposition(1) Top(76) Marginleft(120) Width(350) Height(21) Usepicklist(False)
Define_Com Class(#STD_TEXTS.Visual) Name(#STD_TEXTS) Displayposition(2) Left(16) Parent(#COM_OWNER) Tabposition(2) Top(98) Width(350) Marginleft(120) Height(19) Usepicklist(False)
Mthroutine Name(uExecute)
#COM_OWNER.uSetField( #STD_TEXT )
#COM_OWNER.uSetField( #STD_TEXTS )
Endroutine /* uExecute */
Mthroutine Name(uSetField)
Define_Map For(*INPUT) Class(#PRIM_EVEF) Name(#pField) Pass(*BY_REFERENCE)
#pField.Visible := False
#pField.Enabled := False
#pField.VisualStyle <= #STD_VS
Endroutine /* uSetField */
Re: Pass name of field to subroutine and then refer to real field
Posted: Thu Jul 02, 2020 4:59 pm
by Joop
Hi Casey,
You are right! The class needed to be changed. Now it works.
Thanks again for your input.