I. Introduction to the tree
Developer 6.0 The above version provides the concept of hierarchy trees, and the Htree control is very convenient and only a small amount of programming can realize the purpose of displaying hierarchies.
The unique properties of the tree are more important:
l Multi-Selection: Do you allow multiple nodes of the tree to be selected. If you are not allowed, then the second node is selected, the first selected node will deselect.
l Recording Group: Specifies the name of the record group that generates the tree.
Briefly introduce the trigger (Built-in) related to the tree:
l Function get_tree_node_property (item_name varcha2, node node, printy number);
Function: Take the properties of the tree node
Among them, Property has the following:
Node_State: expanded_node (extension node)
Collapsed_node (shrink node)
Leaf_node - Note: Cannot Expand or shrink
Node_Depth: Hierarchy of the node in the tree.
Node_Label: Node display text
Node_ICON: Node icon
Node_Value: The value of the node.
example:
Declare
Htree item;
Node_Value varcha2 (100);
Begin
- Get the tree
Htree: = find_item ('Tree_Block.htree3');
- Get the value of the currently selected node
Node_Value: = ftree.get_tree_node_property (htree,: system.trigger_node, ftree.node_value);
...
END;
Note: Where: system.trigger_node refers to the currently selected tree node.
l Function get_tree_property (item_name varcha2, printy number);
Function: Take the property of the tree
Among them, Property has the following:
DataSource
RECORD_GROUP
Query_Text
Node_count: Returns the number of nodes in the tree.
Selection_count
Allow_empty_branches
Allow_Multi-select SELECT
l Procedure set_tree_node_property (item_name varcha2, node ftree.node, property number, value varcha2);
Function: Set the properties of the tree node
l Procedure set_tree_property (item_name varcha2, printy number, value varchar2);
Procedure set_tree_property (item_name varcha2, property number, value recordgroup);
Function: Set the properties of the tree
l Procedure populate_tree (item_name varchar2);
Function: The data existing in the empty tree is replaced according to the record group or data query.
l Procedure add_tree_data (item_name varchar2, node ftree.node, offset_type number, offset number, data_source number, data varchar2);
Function: Add a tree to the tree under the specified node
Note: It is more troublesome to use.
l Function Find_Tree_Node (item_name varcha2, eArch_string varcha2, search_type number, search_by number, search_root node, start_point node);
Function: Find the display text or value that meets the search_string node.
parameter:
Search_type: Find_Next
Find_next_child
Search_by: Node_Label
Node_Value
Search_Root: The root node of the query is generally ftree.Root_Node
START_POINT: Find the start node, usually ftree.Root_Node
l Function add_tree_node (item_name varcha2, node ftree.node, offset_type number, offset number, state number, label varcha2, icon varchar2, value varchar2);
Function: Add a tree node.
Offset_type: Specify the branch type, Parent_offset, and Sibling_offset
Offset: Specify the location of the new node,
Parent_offset: 1..n
Last_Child
Sibling_offset: Next_Node
Previous_Node
State: expanded_node (extension node)
Collapsed_node (shrink node)
Leaf_node (leaf node)
l Procedure delete_tree_node (item_name varcha2, node node);
Function: Delete tree node
l Function get_tree_node_parent (item_name varcha2, node node);
Function: Get the parent node of the specified node.
l function get_tree_selection (item_name varcha2, selection number);
Function: Get the node in the selected state.
l Procedure set_tree_selection (item_name varchar2, node node, selection_type number);
Function: Specify the selected state of a single node
parameter:
Selection_Type: SELECT_ON
SELECT_OFF
SELECT_TOGGLE
FORM running status related trigger:
l when-tree-node-activated: Users double-click the node or press the [ENTER] button when the node is selected.
l when-tree-node-expanded: Trigger when the node is expanded or contracted
l when-tree-node-selected: Trigger when the node is selected or deselected
Second, the way the tree is generated
Tree control is typically placed in a control block (Note: It cannot be placed in the data block), and it is easy to place the tree on the canvas, and if necessary, the attribute of the tree does not need to be set. There are several ways to generate trees:
l Generate by setting the record group or data query attribute before running
l Implemented by add_tree_data triggers
l Run state, realize triggers such as add_tree_node
l Run state, implement the data elements of the record group to be added or deleted
analysis:
First, the tree is directly
Description: find_tree_node finds the specified node, add_tree_node to add its lower node.
Disadvantages: More programming is complicated, the operation is not flexible, and it is easier to erode.
Advantages: The process of adding nodes can be controlled to implement some special requirements.
example:
--DEPT_CUR is the cursor of the unit, EMP_CUR is the employee's CURSOR
Htree: = find_item ('Tree_View.Tree_EMP');
Open dept_cur;
loop
Fetch dept_cur into aa;
EXIT WHEN Dept_cur% Notfound;
Del_node: = ftree.find_tree_node (htree, aa.kjmc, ftree.find_next, ftree.Root_Node, ftree.Root_Node);
- Delete unit nodes and their child nodes
If not ftree.id_null (del_node) THEN
Ftree.delete_tree_node (htree, del_node);
END IF;
End loop;
Close dept_cur;
- Depending on the first layer node that generates trees obtained with Cursor
Open dept_cur;
loop
Fetch dept_cur into aa;
EXIT WHEN Dept_cur% Notfound;
New_node: = ftree.add_tree_node (htree, ftree.root_node, ftree.parent_offset, ftree.last_child, ftree.expanded_node, aa.dname, '', aa.deptno);
End loop;
Close dept_cur;
- underlying the lower node of the employee cursor
Open EMP_CUR;
loop
FETCH EMP_CUR INTO BB;
EXIT WHEN EMP_CUR% NOTFOUND;
Find_node: = ftree.find_tree_node (htree, bb.kjbh, ftree.find_next,
FTree.Node_Value, ftree.root_node, ftree.root_node;
New_node: = ftree.add_tree_node (htree, find_node, ftree.Parent_offset, ftree.last_child, ftree.expanded_node, bb.ename, '', bb.empno);
End loop;
Close EMP_CUR;
- Get the root node of the tree
SS: = ftree.get_tree_property (htree, ftree.node_count);
- Cycle until all nodes of the tree are expanded
For J in 1..SS loop
Exp_node: = ftree.find_tree_node (htree, ''); state: = ftree.get_tree_node_property (htree, j, ftree.node_state);
If state = ftree.collapsed_node thein
Ftree.set_tree_node_property (htree, j, ftree.node_state, ftree.expanded_node);
END IF;
End
Loop
;
Second, dynamic record group
The data format of the recording group used in the hierarchium:
- Car
|
- AirPlane
| - BOEING
| - BOEING
Initial state layer display text icon value -1 (shrink node) 1 'car' '' 'car' 0 (leaf node) 2 'Honda' '' 'CIVIC' 1 (Expand Node) 1 'AirPlane' '' 'PLANE '0 2' Boeing '' '' 747 '0 2' BoEing '' '' 757 '
The way the record group is generated is divided into two.
1. Generate record groups from query
Description: Generate a record group using a tree query statement (Connect By ... PRIOR ... START WITH ...) to generate the properties of the tree.
Advantages: simple programming, convenient.
Disadvantages: Only for a tree query statement can be constructed.
example:
v_ignore number;
RG_EMPS Recordgroup;
Begin
RG_EMPS: = FIND_GROUP ('EMPS');
- Clear data if not empty
IF not id_null (rg_emps) THEN
DELETE_GROUP (RG_EMPS);
END IF;
- Construction record group
RG_EMPS: = CREATE_GROUP_FROM_QUERY ('EMPS',
'SELECT 1, Level, ENAME, NULL, TO_CHAR (EMPNO) ||
'from EMP' ||
'Connect by prior Empno = mgr' ||
'Start with job =' 'PRESIDENT' ');
v_ignore: = populate_group (rg_emps);
ftree.set_tree_property ('Tree_View.tree_Emp ", ftree.record_group, rg_emps);
END;
2. Direct construct record group with rantrifugation data
Description: The record group is typically a row structure to add unit data to the record group in a loop manner.
Advantages: The style of the record group can be directly controlled.
Disadvantages: For multi-layer structure, programming is also complicated.
example:
- Unit Cursor
CURSOR CURSOR_DEPT IS
SELECT DNAME, Deptno from Dept Order by DName
- Employee CURSOR
CURSOR CURSOR_EMP (p_dno number) IS
SELECT ENAME, Empno from Emp where deptno = p_dno order by ename; v_i number;
v_ignore number;
RG_EMPS Recordgroup;
RG_DEPTS Recordgroup;
v_init_state groupcolumn;
v_level groupcolumn;
v_label groupcolumn;
v_icon groupcolumn;
v_value groupcolumn;
Begin
RG_DEPTS: = FIND_GROUP ('DEPTS');
- If there is data, empty the record group
IF not id_null (rg_depts) THEN
DELETE_GROUP (RG_DEPTS);
END IF;
RG_DEPTS: = CREATE_GROUP ('DEPTS');
- Customize the data type and length you need in the record group you need
- Initial state (refer to the deployment, shrink or leaf node)
v_init_state: = add_group_column (rg_depts, 'init_state', number_column);
--Current unit
v_level: = add_group_column (rg_depts, 'level', number_column);
- Display text
v_label: = add_group_column (rg_depts, 'label', char_column, 40);
--icon
v_icon: = add_group_column (rg_depts, 'icon', char_column, 20);
--value
v_value: = add_group_column (rg_depts, 'value', char_column, 5);
v_i: = 1;
For DePTREC in Cursor_Dept loop
Add_group_row (rg_depts, v_i);
SET_GROUP_NUMBER_CELL (v_init_state, v_i, 1);
Set_group_number_cell (v_level, v_i, 1);
SET_GROUP_CHAR_CELL (V_Label, V_i, DePTREC.DNAME);
SET_GROUP_CHAR_CELL (V_ICON, V_I, NULL);
SET_GROUP_CHAR_CELL (V_Value, V_i, TO_CHAR (DEPTREC.DEPTNO);
v_i: = v_i 1;
For EmpRec IN CURSOR_EMP (DEPTREC.DEPTNO) LOOP
Add_group_row (rg_depts, v_i);
SET_GROUP_NUMBER_CELL (v_init_state, v_i, 1);
SET_GROUP_NUMBER_CELL (v_level, v_i, 2);
SET_GROUP_CHAR_CELL (V_Label, V_i, EmpRec.ename);
SET_GROUP_CHAR_CELL (V_ICON, V_I, NULL);
Set_group_char_cell (v_value, v_i, to_char (emprec.empno);
v_i: = v_i 1;
End loop;
End loop;
ftree.set_tree_property ('Tree_View.Tree_org', ftree.record_group, rg_depts);
END;
Conclusion: When performing a database design, try to put the parent son structure in a table, so that the way to generate record groups to generate record groups is the simplest and practical. If it is not possible, the direct constructing record group can also generate a tree. If there is no special requirement, it is generally not taken directly to the tree.
Note: The author typically places the process of spanning the tree in the "program unit" of the Form Builder, and the call is called in real time to refresh the tree in real time.
Reference: Developer 6.0 comes with a PL / SQL library: Navigate.PLL
Third, legacy issues
Since developer simplifies the design of the tree, some operations such as the transfer, copying, etc. are not easy to implement. This topic also needs to continue research.