With WHAT
and WHO
one can loop through a GROUP, but can the same be done for an ITEMIZE
?
No
You’d have to scan the CLW / INC code or change to a Group
I know that .Net allows it because … it does everything. In Clarion Itemize is a Compiler directive to number Equates.
It’s not the same thing but you can use this construct.
Depends on what you are trying to accomplish.
! Field equate labels for toolbar buttons
Toolbar ITEMIZE(3000),PRE
First EQUATE
Toolbar EQUATE(Toolbar:First)
Insert EQUATE
Change EQUATE
Delete EQUATE
Select EQUATE
Bottom EQUATE
Top EQUATE
PageDown EQUATE
PageUp EQUATE
Down EQUATE
Up EQUATE
Locate EQUATE
History EQUATE
Help EQUATE
ToolbarGroup EQUATE
FrameEditGroup EQUATE
FrameNavigateGroup EQUATE
FrameHistoryGroup EQUATE
FrameSelectGroup EQUATE
FrameHelpGroup EQUATE
Last EQUATE(Toolbar:FrameHelpGroup)
END
Then you can use a loop to go through all of the equates:
LOOP curEquate = Toolbar:First to ToolbarLast
END
I’ve used this idea a few times.
If there are gaps in your equates or the values are not sequential, then you might need to choose a different way to enumerate your stuff.
Typescript enums are pretty nice when you need to do this kind of thing.
Would love to be able to do that with ITEMIZE(), but it is my current understanding that there isn’t any actual internal structure to enumerate other than the linguistic one that we type in, so the best way is to just create specific methods.
Seems it’s not possible and just requires handcoding - the thing I needed it for was to show a dropdown based on the ITEMIZE
- so having an way to loop through the ITEMIZE and fill a queue with VALUE and KEY would have been amazing
I usually write an enumeration class for each itemize
Here’s the .inc of the base class
!ABCIncludeFile
INCLUDE( 'ABError.inc'),ONCE !for Validate
INCLUDE( 'ErrorLevel.EQU'),ONCE !for Validate
PropFromFlag:HumanReadable EQUATE(1)
EnumError EQUATE('Error')
!Enum:BlankOnError EQUATE(TRUE)
!Region Interfaces
iEnum INTERFACE
ToDescription PROCEDURE(LONG xCode,BYTE BlankOnError=FALSE),STRING
ToCode PROCEDURE(STRING xDescription),LONG
PropFrom PROCEDURE(LONG xFlag=0),STRING
END
iEnumStr INTERFACE
ToDescription PROCEDURE(STRING xCode,BYTE BlankOnError=FALSE),STRING !From Code to Description
ToCode PROCEDURE(STRING xDescription),STRING !From Description to Code
PropFrom PROCEDURE(LONG xFlag=0),STRING
END
!EndRegion Interfaces
!Region Base Classes
ctEnumBase CLASS,TYPE,IMPLEMENTS(iEnum),MODULE('ctEnumBases.clw'),LINK('ctEnumBases.clw',_ABCLinkMode_),DLL(_ABCDllMode_)
ToDescription PROCEDURE(LONG xCode ,BYTE BlankOnError=FALSE),STRING,VIRTUAL
ToCode PROCEDURE(STRING xDescription),STRING,VIRTUAL !From Description to Code
PropFrom PROCEDURE(LONG xFlag=0 ),STRING,VIRTUAL
Validate PROCEDURE(LONG xCode, BYTE xHandleErrors, ErrorClass xErrors, STRING xLabel, LONG xFlag),BYTE
END
ctEnumStrBase CLASS,TYPE,IMPLEMENTS(iEnumStr),MODULE('ctEnumBases.clw'),LINK('ctEnumBases.clw',_ABCLinkMode_),DLL(_ABCDllMode_)
ToDescription PROCEDURE(STRING xCode ,BYTE BlankOnError=FALSE),STRING,VIRTUAL !From Code to Description
ToCode PROCEDURE(STRING xDescription),STRING,VIRTUAL !From Description to Code
PropFrom PROCEDURE(LONG xFlag=0 ),STRING,VIRTUAL
Validate PROCEDURE(STRING xCode, BYTE xHandleErrors, ErrorClass xErrors, STRING xLabel,LONG xFlag),BYTE
END
!EndRegion Base Classes
and the .clw
MEMBER
MAP
END
INCLUDE('ctEnumBases.inc'),ONCE
!Region Base Classes
!Region ctEnumBase
ctEnumBase.ToDescription PROCEDURE(LONG xCode,BYTE BlankOnError=FALSE)!,STRING,VIRTUAL !From Code to Description
CODE
RETURN ''
ctEnumBase.ToCode PROCEDURE(STRING xDescription)!,STRING,VIRTUAL !From Description to Code
CODE
RETURN ''
ctEnumBase.PropFrom PROCEDURE(LONG xFlag=0)!,STRING,VIRTUAL
CODE
RETURN ''
ctEnumBase.Validate PROCEDURE(LONG xCode, BYTE xHandleErrors, ErrorClass xErrors, STRING xLabel, LONG xFlag)!,BYTE
ReturnValue BYTE,AUTO
CODE
ReturnValue = CHOOSE( SUB( SELF.ToDescription(xCode), 1,SIZE(EnumError)) = EnumError, Level:Invalid, Level:OK)
IF ReturnValue <> Level:OK AND xHandleErrors
xErrors.SetField(xLabel)
ReturnValue = xErrors.ThrowMessage(Msg:FieldNotInList, SELF.PropFrom(xFlag))
END
RETURN ReturnValue
ctEnumBase.iEnum.ToDescription PROCEDURE(LONG xCode,BYTE BlankOnError=FALSE)!,STRING,VIRTUAL !From Code to Description
CODE
RETURN SELF.ToDescription(xCode,BlankOnError)
ctEnumBase.iEnum.ToCode PROCEDURE(STRING xDescription)!,STRING,VIRTUAL !From Description to Code
CODE
RETURN SELF.ToCode(xDescription)
ctEnumBase.iEnum.PropFrom PROCEDURE(LONG xFlag=0)!,STRING,VIRTUAL
CODE
RETURN SELF.PropFrom(xFlag)
!EndRegion ctEnumBase
!Region ctEnumStrBase
ctEnumStrBase.ToDescription PROCEDURE(STRING xCode,BYTE BlankOnError=FALSE)!,STRING,VIRTUAL !From Code to Description
CODE
RETURN ''
ctEnumStrBase.ToCode PROCEDURE(STRING xDescription)!,STRING,VIRTUAL !From Description to Code
CODE
RETURN ''
ctEnumStrBase.PropFrom PROCEDURE(LONG xFlag=0)!,STRING,VIRTUAL
CODE
RETURN ''
ctEnumStrBase.Validate PROCEDURE(STRING xCode, BYTE xHandleErrors, ErrorClass xErrors, STRING xLabel, LONG xFlag)!,BYTE
ReturnValue BYTE,AUTO
CODE
ReturnValue = CHOOSE( SUB( SELF.ToDescription(xCode), 1,SIZE(EnumError)) = EnumError, Level:Invalid, Level:OK)
IF ReturnValue <> Level:OK AND xHandleErrors
xErrors.SetField(xLabel)
ReturnValue = xErrors.ThrowMessage(Msg:FieldNotInList, '|' & SELF.PropFrom(xFlag))
END
RETURN ReturnValue
ctEnumStrBase.iEnumStr.ToDescription PROCEDURE(STRING xCode,BYTE BlankOnError=FALSE)!,STRING,VIRTUAL !From Code to Description
CODE
RETURN SELF.ToDescription(xCode,BlankOnError)
ctEnumStrBase.iEnumStr.ToCode PROCEDURE(STRING xDescription)!,STRING,VIRTUAL !From Description to Code
CODE
RETURN SELF.ToCode(xDescription)
ctEnumStrBase.iEnumStr.PropFrom PROCEDURE(LONG xFlag=0)!,STRING,VIRTUAL
CODE
RETURN SELF.PropFrom(xFlag)
!EndRegion ctEnumBase
!EndRegion Base Classes
Here’s an example of a class that is derived form ctEnumBase
INCLUDE('ctEnumBases.inc'),ONCE
! This is used to control the Material on an Opening Jamb Return when an Odd Course intersects the opening
! this is material that extends back from the outside wythe
! it's not what's on the outside wythe itself
OddReturns:OddSpecial EQUATE(0) ! Odd:Open_[L|R]_[1|2]
OddReturns:OddPrimary EQUATE(1) ! Odd:Band_Mat
OddReturns:OutsideRegular EQUATE(2) ! Wal:Outside OR OPN:Jamb (the override regular material )
ctEnumOddReturns CLASS(ctEnumBase),TYPE,MODULE('ctEnumOddReturns.clw'),LINK('ctEnumOddReturns.clw',_ABCLinkMode_),DLL(_ABCDllMode_)
ToDescription PROCEDURE(LONG xCode ,BYTE BlankOnError=FALSE),STRING,DERIVED
ToCode PROCEDURE(STRING xDescription),STRING,DERIVED !From Description to Code
PropFrom PROCEDURE(LONG xFlag=0 ),STRING,DERIVED
END
and it’s clw
MAP
END
INCLUDE('ctEnumOddReturns.inc'),ONCE
ctEnumOddReturns.ToDescription PROCEDURE(LONG xCode ,BYTE BlankOnError=FALSE) !,STRING,DERIVED
Retval ANY
CODE
CASE xCode ! I asked baynar about these 2022-Mar-9, he liked the existing names
OF OddReturns:OddSpecial ; RetVal = 'Odd Special' ! Same as Jamb
OF OddReturns:OddPrimary ; RetVal = 'Odd Primary'
OF OddReturns:OutsideRegular ; RetVal = 'Outside Regular' ! Override or Outside Regular
ELSE Retval = CHOOSE( BlankOnError=FALSE, EnumError&'['& xCode &']', '')
END
RETURN Retval
ctEnumOddReturns.ToCode PROCEDURE(STRING xDescription) !,STRING,DERIVED !From Description to Code
RetVal LONG(-1)
CODE
CASE UPPER(CLIP(xDescription))
OF 'ODD SPECIAL' ; Retval = OddReturns:OddSpecial
OF 'ODD PRIMARY' ; Retval = OddReturns:OddPrimary
OF 'OUTSIDE REGULAR' ; Retval = OddReturns:OutsideRegular
END
RETURN Retval
ctEnumOddReturns.PropFrom PROCEDURE(LONG xFlag=0 ) !,STRING,DERIVED
Retval ANY
Value LONG,AUTO
HumanReadable LONG,AUTO
CODE
HumanReadable = CHOOSE( (xFlag % 2) = PropFromFlag:HumanReadable)
Retval = CHOOSE(HumanReadable=TRUE,'|','')
LOOP Value = OddReturns:OddSpecial TO OddReturns:OutsideRegular
Retval = Retval |
& SELF.ToDescription(Value) |
& CHOOSE( HumanReadable = TRUE, '|', '|#'& Value & '|')
END
Retval = SUB(Retval, 1, LEN(CLIP(Retval)) - 1) !strip off last '|'
RETURN Retval