Processing Tree Items in the order that they are displayed (Version 11 only)

Date:26 August 2005
Product/Release:Visual LANSA V11
Abstract:SelectList processes tree items in the order that they were added, not the order in which they are displayed. Use this method to process items in the correct order (Version 11 only)
Submitted By:LANSA Technical Support

Note: The code is in this tip assumes full RDMLX has been enabled. It can be modified to work in RDML forms if necessary.

Typically, a tree will show data in the order it’s added to the list. However, the SortPosition property for specific tree columns, and the flexibility of columnar trees, introduced in LANSA V11 (see previous tip), can mean that tree items are displayed in a sequence that does not match the underlying list.

Functional requirements, such as Find and Find Next, require that the tree data be processed in the order it is displayed in the tree. The SelectList command processes the data in the order it was added to the underlying list, which is pointless if the sort order has been changed.

The other option is to use the For command to process the tree items themselves. A Tree View has an Items property that will return all tree items at the root level. However each tree item at the root level also has an Items property that in turn will return a the child items for that branch. For this reason, to adequately step through the entire tree view contents some lateral thinking is required

The solution is to iterate over the multi-level tree view using a recursive method, which will  “flatten” the tree and return it as a single level collection of tree items. The Flatten_Tree routine below does exactly that. To use this routine, you would write the following:

Mthroutine name(My_Method)
For each(#Tree_Item) in(#Com_owner.Flatten_tree( #My_tree ))

* Get the entry to ensure that currentitem is correctly set.
Get_Entry Number(#Tree_item.Entry) from_list(#My_tree)

* Process Tree item here
EndFor
Endroutine

The Flatten_Tree routine has a Define_Map of type *Result, that returns a collection of tree items. The expression handling introduced in LANSA V11 means that it is possible to write a For command that iterates over the result of a method, assuming the result is a collection.
The routine has no reference to a specific tree. Because of this, it does not have to be in the component that is using it. It could be written once in a “utilities” component and simply invoked when required.

Mthroutine Name(Flatten_Tree) Help('Convert from a tree to a flat structure and return in a list a collection of tree items')
Define_Map For(*Input) Class(#prim_trvw) Name(#i_Tree) Pass(*by_reference)
Define_Map For(*Input) Class(#prim_tvit) Name(#i_Tree_item) Mandatory(*null) Pass(*by_reference)
Define_Map For(*Result) Class(#prim_lcol<#prim_tvit>) Name(#o_Tree_items) Pass(*by_reference)

Set_Ref Com(#o_tree_items) To(*create_as #prim_lcol<#prim_Tvit>)

If (#i_tree_item *Is *Null)

* Work for whole tree
For Each(#item) In(#i_tree.items)

* Add child items
#o_tree_items.Append( #com_owner.Flatten_Tree( #i_tree #item ) )
Endfor
Else

* Add the tree item to the tree
#o_tree_items.insert( #i_tree_item )

* Just the supplied branch
For Each(#item) In(#i_tree_item.items)

* Add child items
#o_tree_items.Append( #com_owner.Flatten_Tree( #i_tree #item ) )
Endfor
Endif
Endroutine