|
ошибка: FRM47337 Tree node label can not be null при выполнении скрипта DECLARE |
Элемент дерево (Tree view)
Процедура SET_TREE_PROPERTY
SET_TREE_PROPERTY (item_name [item_id] VARCHAR2 [FORMS4C.ITEM], property NUMBER, value NUMBER [VARCHAR2, RECORDGROUP]) - устанавливает значение указанного свойства дерева.
| Метод | Параметр | Тип | Значение |
|---|---|---|---|
| PROCEDURE SET_TREE_PROPERTY (параметры) | itemname [idname] | VARCHAR2 [FORMS4C.ITEM] | Определяет имя элемента или его идентификатор |
| property | NUMBER | Устанавливает одно из перечисленных свойств равным value: RECORD_GROUP, QUERY_TEXT, ALLOW_EMPTY_BRANCHES | |
| value | NUMBER[VARCHAR2,RECORDGROUP] | Значение, устанавливаемое для заданного свойства. Для ALLOW_EMPTY_BRANCHES это всегда PROPERTY_TRUE или PROPERTY_FALSE |
В следующем примере разрешается наличие в дереве пустых узлов, то есть элементов, не содержащих детей.
DECLARE
Itree item := find_item('tree_block.tree_item ');
BEGIN
Ftree.Set_Tree_Property(Itree, Ftree.ALLOW_EMPTY_BRANCHES,
property_true);
END;
Листинг
3.10.
Получение выделенной вершины
Процедура SET_TREE_SELECTION
SET_TREE_SELECTION item_name [item_id] VARCHAR2 [FORMS4C. ITEM], node NODE, selection_type NUMBER) - устанавливает или сбрасывает выделение указанной вершины.
Следующий пример описывает процесс поиска корневого узла и его выделение.
DECLARE
Itree item := find_item('tree_block.tree_item ');
select_node Ftree.NODE;
i_value VARCHAR2(30);
BEGIN
select_node:= Ftree.Find_Tree_Node(Itree, i_value,
Ftree.FIND_NEXT, Ftree.NODE_VALUE,
Ftree.ROOT_NODE, Ftree.ROOT_NODE);
Ftree.Get_Tree_Property(Itree, select_node, ftree.select_on);
END;
Листинг
3.11.
Выделение заданной вершины
Теперь, когда мы рассмотрели все основные процедуры и функции для работы с деревом, можно приступить к его построению. Для начала выполним простой пример, который описывает создание корневого и дочернего узла, причем для построения дерева мы будем использовать шаблон, созданный в предыдущем примере.
- Установите для кнопки метку "Добавить родительский узел" и создайте для нее событие WHEN-BUTTON-PRESSED. В теле триггера напишите и скомпилируйте строки, которые приведены ниже.
WHEN-BUTTON-PRESSED DECLARE r_Node Ftree.Node; c_Node Ftree.Node; BEGIN r_Node:=Ftree.Add_Tree_Node('TREE.TREE', Ftree.ROOT_NODE, Ftree.PARENT_OFFSET, Ftree.LAST_CHILD, Ftree.EXPANDED_NODE, 'Главный' , NULL, '1'); END; - Установите для второй кнопки метку "Добавить дочернюю ветку " и создайте для нее событие WHEN-BUTTON-PRESSED. В теле триггера напишите и скомпилируйте строки, которые приведены ниже.
WHEN-BUTTON-PRESSED DECLARE h_Node Ftree.Node; l_Node Ftree.Node; begin h_Node:=Ftree.Add_Tree_Node(' TREE.TREE ', Ftree.ROOT_NODE, Ftree.PARENT_OFFSET, Ftree.LAST_CHILD, Ftree.EXPANDED_NODE, 'Дочерний' , NULL, '1'); l_node:=Ftree.Add_Tree_Node('TREE.TREE', h_node, Ftree.Parent_offset, ftree.NEXT_NODE, Ftree.LEAF_NODE, 'Дочерний', NULL, '2'); end;
Результат работы программы показан на рис. 1. Далее приведен пример с заполнением дерева моделью Мастер-Деталь.
- Для создания блоков COUNTRY и CITY выполните скрипт, приведенный в листинге 3.12.
SQL: CREATE TABLE COUNTRY (PRkey number PRIMARY KEY, cntr varchar2(100)) / SQL: CREATE TABLE CITY (FKkey number, town varchar2(100)) / -- вставка значений в таблицу COUNTRY SQL: INSERT INTO COUNTRY VALUES (1,'Украина'); SQL: INSERT INTO COUNTRY VALUES (2,'Россия'); SQL: INSERT INTO COUNTRY VALUES (3,'Германия'); -- вставка значений в таблицу CITY SQL: INSERT INTO CITY VALUES (1,'Киев'); SQL: INSERT INTO CITY VALUES (1,'Львов'); SQL: INSERT INTO CITY VALUES (1,'Мариуполь'); SQL: INSERT INTO CITY VALUES (2,'Москва'); SQL: INSERT INTO CITY VALUES (2,'Санкт-Петербург'); SQL: INSERT INTO CITY VALUES (2,'Калининград'); SQL: INSERT INTO CITY VALUES (3,'Берлин'); SQL: INSERT INTO CITY VALUES (3,'Франкфурт'); SQL: INSERT INTO CITY VALUES (3,'Магдебург');Листинг 3.12. Создание таблиц COUNTRY и CITY - Сохраните модуль как relation_tree.
- Создайте два блока COUNTRY и CITY и свяжите их между собой, установив JOIN CONDITION равным COUNTRY.PRKEY=CITY. FKKEY.
- Находясь в навигаторе объектов, создайте небазовый блок и назовите его " TREE ".
- Находясь в редакторе разметки, создайте одну канву. Разместите на канве элемент Tree View и назовите его TREE.
- Создайте триггер WHEN-NEW-FORM-INSTANCE и напишите в нем нижеприведенный код.
WHEN-NEW-FORM-INSTANCE
DECLARE
z varchar2(100);
x number;
h_Node Ftree.Node;
l_Node Ftree.Node;
cursor c1 is select * from country;
cursor a1 is select * from city;
c2 c1%rowtype;
a2 a1%rowtype;
begin
open c1;
for i in (select * from country) loop
begin
:parameter.param:=:parameter.param+1;
h_Node:=Ftree.Add_Tree_Node('TREE.TREE', ftree.ROOT_NODE,
Ftree.PARENT_OFFSET, Ftree.LAST_CHILD, Ftree.EXPANDED_NODE,
i.cntr , NULL, :parameter.param);
for j in (select * from city) loop
if j.fkkey=i.prkey then
z:=j.c;
l_node:=Ftree.Add_Tree_Node('TREE.TREE', h_node,
Ftree.Parent_offset, ftree.NEXT_NODE, Ftree.LEAF_NODE, j.c,
NULL, :parameter.param);
ELSE
null;
end if;
end loop;
end;
end loop;
end;При запуске формы дерево заполняется значениями из таблиц. Далее мы рассмотрим несколько примеров, которые не только продемонстрируют нам методы пакета FTREE, но и расширят функциональность формы.
Вы можете синхронизировать дерево с главным блоком, отражая перемещение на следующую запись в дереве, выделяя и развертывая соответствующий узел. Для того чтобы выполнить этот пример, создайте триггер WHEN-NEW-RECORD-INSTANCE для блока COUNTRY и напишите в нем нижеприведенный код.
WHEN-NEW-RECORD-INSTANCE
DECLARE
Itree item := find_item('tree.tree');
select_node ftree.node;
begin
select_node := ftree.find_tree_node(Itree, :prkey,
ftree.find_next, ftree.node_value,
ftree.root_node, ftree.root_node);
ftree.set_tree_selection(Itree, select_node, ftree.select_on);
ftree.set_tree_node_property(Itree, select_node, ftree.node_state,
ftree.expanded_node);
end;Запустите форму и выберите записи. Попробуйте перейти на следующую или предыдущую запись, и вы увидите, как синхронно разворачивается и выделяется узел в дереве при перемещении на новую запись. Теперь создадим кнопку, по нажатию которой будет удаляться выбранный элемент дерева. Для этого создайте кнопку и установите для нее метку "Удалить узел". Создайте триггер WHEN-BUTTON-PRESSED для кнопки и напишите в нем нижеприведенный код.
WHEN-BUTTON-PRESSED.
Удаление выделенного узла
DECLARE
Itree item := find_item('tree.tree');
select_node Ftree.NODE := Ftree.Get_Tree_Selection(Itree, :country.prkey);
begin
Ftree.Delete_Tree_Node(Itree, select_node);
end;