HI !
Please tell me, is it possible to make a function to clear an arbitrary group with arrays?
Or are the limitations of the Clarion language preventing this from being done? Thanks !
PrintList Group
Task Group,Dim(3)
Flag Long,Dim(3)
Doc Group,Dim(3)
Page Long,Dim(3,3)
end
end
end
Code
ClearGroup(PrintList) ???
PROGRAM
PrintList Group
Task Group,Dim(3)
Flag Long,Dim(3)
Doc Group,Dim(3)
Page Long,Dim(3,3)
end
end
end
MAP
END
CODE
PrintList.Task[1].Doc[1].Page[1,1] = 1
message( PrintList.Task[1].Doc[1].Page[1,1] ) ! Show 1 (one)
clear( PrintList )
message( PrintList.Task[1].Doc[1].Page[1,1] ) ! Show 0 (zero)
A feature I don’t think is well know is you can Deep Assign an entire Numeric Array as a Constant. E.g. the below Message will show 123. It is shown in the Help on Deep Assign.
What can cause a problem with GROUPs is a Deep assign :=: between 2 GROUP’s that are not identical i.e. different child fields. The GROUP’s are assigned First as Strings. If there are new Child fields that are Numeric they left as the String values but assigned as binary so garbage. You need to Clear them. This is often an issue converting records.
In the first test, there is binary garbage in the strings (an array structure filled with spaces).
In large data structures, you need to clear each array separately - this is very inconvenient.
Question: is there any way to go through the structure of an arbitrary GROUP and clear the arrays?
clear( PrintList ) clears only first Task item, not 2nd and third. Add this line at the end and get an interesting result. message( PrintList.Task[2].Doc[2].Page[2,2] ) ! I see 538976288
It did not work to iterate through the Group elements and clear the arrays.
Another Easter egg from the developers of Clarion ?
We need to write it down somewhere …
I am not at my Clarion machine to test this, but give it a try. For some data types, this might not be appropriate (such as STRING), but it’s OK for CSTRING.:
Data
gBarCode Group
height Long
Print Bool(False)
overlay Group,Dim(3)
type CString( 21)
text CString(129)
end
end
OverString STRING(SIZE(gBarCode)),OVER(gBarCode)
Code
Clear(OverString,-1) ! Should clear entire buffer to zeros.
Message('TEST1: Clear(gBarCode)||' & |
'Len(overlay[1].text) = ' & Len(gBarCode.overlay[1].text) & '|' & |
'Len(overlay[2].text) = ' & Len(gBarCode.overlay[2].text) & '|' & |
'Len(overlay[3].text) = ' & Len(gBarCode.overlay[3].text))
Clear(gBarCode.overlay)
Message('TEST2: Clear(gBarCode.overlay)||' & |
'Len(overlay[1].text) = ' & Len(gBarCode.overlay[1].text) & '|' & |
'Len(overlay[2].text) = ' & Len(gBarCode.overlay[2].text) & '|' & |
'Len(overlay[3].text) = ' & Len(gBarCode.overlay[3].text))
Another option could be to optionally allow the caller to provide a properly initialized buffer that you can just replace your working buffer with as needed.
It’s called a crutch. I can make them up too. There is no way to correctly clear an arbitrary Group structure. This would be a disaster even for a free programming language. Note that we get a Group filled with binary garbage without an error message.
OK, I guess you just have to choose which crutch you’re going to use. You might be able to use Capesoft Reflection’s ClearGroup method, but I’m guessing that it would need some assistance via the extended name() attribute.
Is the only thing you want to do with this array is properly clear it?
Are you not also writing/reading the data somehow?
PROGRAM
PrintList Group
Task Group,Dim(3)
Flag Long,Dim(3)
Doc Group,Dim(3)
Page Long,Dim(3,3)
end
end
end
ClearArray byte,dim(size(PrintList)),over(PrintList)
MAP
END
CODE
PrintList.Task[1].Doc[2].Page[1,1] = 1
message( PrintList.Task[1].Doc[2].Page[1,1] ) ! Show 1 (one)
!clear( PrintList )
clear( ClearArray )
message( PrintList.Task[1].Doc[2].Page[1,1] ) ! Show 0 (zero)
It’s quite easy to write custom DeepClear(*GROUP) recursive procedure which clears all nested dimmed groups using standard ISGROUP, GETGROUP and HOWMANY procedures.
EasyClear Procedure(*Group MyGroup)
lCount Long,Auto
aFieldRef Any,Auto
pGroupRef &Group
Code
Loop lCount = 1 to 9999
aFieldRef &= What(MyGroup,lCount)
If aFieldRef &= Null then Break. ! End of Group
If Not IsGroup(MyGroup,lCount) then Clear(aFieldRef)
else
pGroupRef &= GetGroup(MyGroup,lCount)
EasyClear(pGroupRef)
end
end
If you show me your version, I’ll try to explain why it won’t work…
if you have StringTheory look at the code for SerializeGroup. Bruce wrote the original version and then some time later I updated it to allow dimensioned fields using howmany() which was added in version 3.06 in March 2019.
While you are doing a different thing here, that code will show you the basic method to traverse the structure recursively, including arrays.
Sorry it is late here and I have an early start in the morning so I thought I’d just point you in the right direction. If you have no joy I can have a look at it later in the week - but just search for howmany in the code.
! --------------------------------------------------------------------------
! The algorithm by brute force.
! --------------------------------------------------------------------------
loop i = 1 to maximum( PrintList.Task, 1 )
loop j = 1 to maximum( PrintList.Task[ i ].Flag, 1 )
PrintList.Task[ i ].Flag[ j ] = value_to_set
loop k = 1 to maximum( PrintList.Task[ i ].Doc, 1 )
loop l = 1 to maximum( PrintList.Task[ i ].Doc[ k ].Page, 1 )
loop m = 1 to maximum( PrintList.Task[ i ].Doc[ k ].Page, 2 )
PrintList.Task[ i ].Doc[ k ].Page[ l, m ] = value_to_set
end !* loop *
end !* loop *
end !* loop *
end !* loop *
end !* loop *
! --------------------------------------------------------------------------
! Testing Messaging.
! --------------------------------------------------------------------------
loop i = 1 to maximum( PrintList.Task, 1 )
loop j = 1 to maximum( PrintList.Task[ i ].Flag, 1 )
s = '|Tag[' & i & '] Flag[' & j & '] -->' & PrintList.Task[ i ].Flag[ j ] &'|'
loop k = 1 to maximum( PrintList.Task[ i ].Doc, 1 )
loop l = 1 to maximum( PrintList.Task[ i ].Doc[ k ].Page, 1 )
loop m = 1 to maximum( PrintList.Task[ i ].Doc[ k ].Page, 2 )
s = s & 'Tag['&i&'] Doc['&k&'] Page['&l&','&m&'] -->' & PrintList.Task[ i ].Doc[ k ].Page[ l, m ] & '|'
end !* loop *
end !* loop *
end !* loop *
message( s )
end !* loop *
end !* loop *