ошибка: 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;