Users often create circular references and are not aware of it. To find circular references in a structure, use the following grid. It is a general solution which lists all circular references to a predefined level in a structure. The reason to control the level (recursion) is to avoid exceeding the limit on nested calls. The grid uses:
ForEachPartGroup, which is used to iterate over all part groups.
Template with Parameters, which always to pass parameter value to a next iteration.
Bashar Nassar
Hi,
<Grid> <Options> <CellAutoHeight/> </Options> <Columns> <ItemNameColumn width="200" objectName="CircularReferences"/> <ItemTypeColumn width="100" objectName="CircularReferences"/> <TextColumn caption="Path to Circular References" objectName="Depth" width="350" multiValueStyle="Bullets"> <Value>#{Name} (#{Type.Name})</Value> </TextColumn> </Columns> <!-- To control the number of recursion calls--> <Variable name="PartGroupDepth" as="Integer" select="10"/> <ApplyTemplate name="PartGroup"> <WithParam name="p1" select="$PartGroupDepth"/> <WithParam name="p2" select="[]"/> </ApplyTemplate> <Template name="PartGroup"> <Parameter name="p1" as="Integer"/> <Parameter name="p2" as="[Item]"/> <Variable name="PreviousItems" as="Items" select="$p2"/> <If test="$p1 != 0"> <ForEachPartGroup> <ForEachPart> <DefObj> <Variable name="CurrentItem" as="Items" select="."/> <Variable name="Accumulated" as="Items" select="$CurrentItem union $PreviousItems"/> <Choose> <When test="not $CurrentItem in $PreviousItems"> <ApplyTemplate name="PartGroup"> <WithParam name="p1" select="$p1 - 1"/> <WithParam name="p2" select="$Accumulated"/> </ApplyTemplate> </When> <Otherwise> <Row> <RowObject name="CircularReferences"> <ForEach select="$PreviousItems"> <RowObject name="Depth"/> </ForEach> </RowObject> </Row> </Otherwise> </Choose> </DefObj> </ForEachPart> </ForEachPartGroup> </If> </Template> </Grid>