Oracle Form Builder中使用树的心得

一、树的简介

Developer 6.0 以上版本提供了 hierarchy tree (层次树)的概念, htree 控件非常方便,只需要少量的编程即可实现显示层次结构的目的。

树的特有属性中如下几个较为重要:

l 多项选择( Multi-Selection ):是否允许一次选中树的多个节点。如果不允许,那么 选中第二个节点时,第一个被选中的节点会取消选择。

l 记录组( Record Group ):指定生成树的记录组的名字。

简单介绍一下跟树相关的触发子( Built-in ):

l FUNCTION GET_TREE_NODE_PROPERTY (item_name VARCHAR2, node NODE, property NUMBER);

功能:取得树节点的属性

其中 property 有如下几种:

NODE_STATE : EXPANDED_NODE (扩展节点)

COLLAPSED_NODE (收缩节点)

LEAF_NODE (叶节点) -- 注:不能展开或收缩

NODE_DEPTH :既节点在树中的层级。

NODE_LABEL :节点的显示文本

NODE_ICON :节点的图标

NODE_VALUE :节点的值。

例子:

DECLARE

htree ITEM;

node_value VARCHAR2(100);

BEGIN

-- 得到树

htree := Find_Item('tree_block.htree3');

-- 得到当前选中节点的值

node_value := Ftree.Get_Tree_Node_Property(htree, :SYSTEM.TRIGGER_NODE, Ftree.NODE_VALUE);

...

END;

注释:其中 : SYSTEM.TRIGGER_NODE 指当前选中的树节点。

l FUNCTION GET_TREE_PROPERTY (item_name VARCHAR2,property NUMBER);

功能:取得树的属性

其中 property 有如下几种:

DATASOURCE

RECORD_GROUP

QUERY_TEXT

NODE_COUNT :返回树中节点的个数。

SELECTION_COUNT

ALLOW_EMPTY_BRANCHES

ALLOW_MULTI-SELECT

l PROCEDURE SET_TREE_NODE_PROPERTY (item_name VARCHAR2,node FTREE.NODE,property NUMBER,value VARCHAR2);

功能:设置树节点的属性

l PROCEDURE SET_TREE_PROPERTY (item_name VARCHAR2,property NUMBER, value VARCHAR2);

PROCEDURE SET_TREE_PROPERTY (item_name VARCHAR2,property NUMBER, value RECORDGROUP);

功能:设置树的属性

l PROCEDURE POPULATE_TREE (item_name VARCHAR2);

功能:清空树中已有数据,并根据记录组或数据查询重新生成树。

l PROCEDURE ADD_TREE_DATA (item_name VARCHAR2,node FTREE.NODE, offset_type NUMBER,offset NUMBER,data_source NUMBER,data VARCHAR2);

功能:在指定节点下添加树中数据

注:使用比较麻烦。

l FUNCTION FIND_TREE_NODE(item_name VARCHAR2,earch_string VARCHAR2, search_type NUMBER,search_by NUMBER,search_root NODE,start_point NODE);

功能:找到显示文本或值符合 search_string 的节点。

参数:

search_type : FIND_NEXT

FIND_NEXT_CHILD

Search_by : NODE_LABEL

NODE_VALUE

Search_root :查询的根节点,一般是 Ftree.ROOT_NODE

Start_point :查找的开始节点,一般是 Ftree.ROOT_NODE

l FUNCTION ADD_TREE_NODE(item_name VARCHAR2,node FTREE.NODE, offset_type NUMBER,offset NUMBER,state NUMBER,label VARCHAR2, icon VARCHAR2,value VARCHAR2);

功能:添加树节点。

Offset_type :指定节点的分支类型, PARENT_OFFSET 和 SIBLING_OFFSET

Offset :指定新节点的位置,

PARENT_OFFSET : 1..N

LAST_CHILD

SIBLING_OFFSET : NEXT_NODE

PREVIOUS_NODE

State : EXPANDED_NODE (扩展节点)

COLLAPSED_NODE (收缩节点)

LEAF_NODE (叶节点)

l PROCEDURE DELETE_TREE_NODE(item_name VARCHAR2,node NODE);

功能:删除树节点

l FUNCTION GET_TREE_NODE_PARENT(item_name VARCHAR2,node NODE);

功能:得到指定节点的父节点。

l FUNCTION GET_TREE_SELECTION(item_name VARCHAR2,selection NUMBER);

功能:得到处于选中状态的节点。

l PROCEDURE SET_TREE_SELECTION(item_name VARCHAR2,node NODE, selection_type NUMBER);

功能:指定单个节点的选中状态

参数:

selection_type : SELECT_ON

SELECT_OFF

SELECT_TOGGLE

FORM 运行态时有关的触发器:

l When-Tree-Node-Activated :用户双击节点或在节点选中时按 [ENTER] 键时触发。

l When-Tree-Node-Expanded :节点展开或收缩时触发

l When-Tree-Node-Selected :当节点选中或取消选择时触发

二、生成树的方式

树控件一般单独放在一个控制块中(注:不能放在数据块中),在画布( CANVAS )上放置树很容易,并且,如无必要,树的属性也不需要设置。

生成树的方式有几种:

l 运行前通过设置记录组或数据查询属性来生成

l 通过 ADD_TREE_DATA 触发子来实现

l 运行态,通过 ADD_TREE_NODE 等触发子来实现

l 运行态,通过添加或删除记录组的数据元素来实现

分析:

一、 对树直接操作

描述: Find_Tree_Node 找到指定节点, Add_Tree_Node 来添加其下级节点。

缺点:编程较为复杂,操作不灵活,而且易出错。

优点:可以对添加节点等过程进行控制,实现一些特殊要求。

例子:

--dept_cur 为取单位的 CURSOR , emp_cur 为取雇员的 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.NODE_LABEL, Ftree.ROOT_NODE, Ftree.ROOT_NODE);

-- 删除单位节点及其子节点

IF NOT Ftree.ID_NULL(del_node) then

Ftree.Delete_Tree_Node(htree, del_node);

END IF;

end loop;

close dept_cur;

-- 根据用 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;

-- 根据雇员 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;

-- 得到树的根节点

ss := Ftree.get_tree_property(htree,FTREE.NODE_COUNT);

-- 循环,直到树的所有节点都展开

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 THEN

Ftree.Set_Tree_Node_Property(htree, j, Ftree.NODE_STATE, Ftree.EXPANDED_NODE);

END IF;

END LOOP ;

二、 动态记录组

层次树所使用记录组的数据格式:

+ — Car

|

- — Airplane

| — Boeing

| — Boeing

初始状态

|

层数

|

显示文本

|

图标

|

---|---|---|---|---

-1 (收缩节点)

|

1

|

‘Car’

|

''

|

‘car’

0 (叶节点)

|

2

|

'Honda'

|

''

|

'civic'

1 (展开节点)

|

1

|

'Airplane'

|

''

|

'plane'

0

|

2

|

'Boeing'

|

''

|

'747'

0

|

2

|

'Boeing'

|

''

|

'757'

生成记录组的方式又分为两种。

1、 从查询生成记录组

描述:利用树的查询语句( connect by…prior…start with… )生成记录组,设置树的属性来生成。

优点:编程简单,方便。

缺点:只适用于可以构造出树状查询语句的情况下。

例子:

v_ignore number;

rg_emps recordgroup;

begin

rg_emps := find_group('EMPS');

-- 如果非空,则清空数据

if not id_null(rg_emps) then

delete_group(rg_emps);

end if;

-- 构造记录组

rg_emps := create_group_from_query('EMPS',

'select 1, level, ename, NULL, to_char(empno) ' ||

'from emp ' ||

'connect by prior empno = mgr '<SPAN style="mso-spacerun:

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus