ошибка: FRM47337 Tree node label can not be null при выполнении скрипта DECLARE |
PL/SQL в Oracle Forms. Управляющие структуры. Глобальные переменные и параметры
Системные переменные и константы
Системные переменные - это переменные сессии Oracle Forms. Как только вы запускаете приложение, вам становятся доступны все его переменные окружения, выполнения и внутреннего состояния. Системные переменные, их имена и типы не привязаны к какому-либо объекту конкретно, они лишь передают текущее состояние или значение объекта, поэтому системная переменная - это, скорее, ссылка на текущее состояние приложения, элемента или события. Практически все системные переменные имеют тип данных VARCHAR и поэтому могут возвращать различные типы данных, такие как число, дата, строка. Системные переменные - это не только путь к написанию правильного и "гибкого" кода, это еще и огромный шаг к написанию переносимых и независимых программных единиц. Для наглядного примера напишем триггер, в котором нам нужно будет определить статус блока и, если блок находится в режиме CHANGED, сохранить изменения.
- Пример с использованием системной переменной:
If :SYSTEM.BLOCK_STATUS = 'CHANGED' Then Commit_Form ; End if ;
- Пример без использования системной переменной:
if get_block_property('block_name', status)='CHANGED' then Commit_Form; end if;
Если сравнивать эти два примера, то основной и самой существенной разницей между ними будет отсутствие в первом имени блока, статус
которого мы проверяем. Первый пример вы можете перенести в любое другое приложение, и оно точно будет работать, а вот со вторым так не получится, так как в нем указано имя блока.
Все системные переменные, за исключением четырех, являются Read_Only, то есть "только для чтения". Ниже приведена табл. 16.2, в которой перечислены все основные системные переменные.
Полный перечень системных переменных вы можете получить, просмотрев одноименный узел в отладчике Forms. Далее приведено описание наиболее используемых функций.
SYSTEM.BLOCK_STATUS - показывает статус блока, точнее, в каком режиме он находится: Enter_Query (ввода запроса), Insert (вставки), New (новой записи).
SYSTEM.CURRENT_BLOCK - возвращает имя текущего блока.
SYSTEM.CURRENT_DATETIME - возвращает системную дату.
SYSTEM.CURRENT_ITEM - возвращает имя (если это кнопка, то также возвращает имя, а не метку ) текущего элемента блока.
SYSTEM.CURRENT_FORM - возвращает имя текущей формы.
SYSTEM.CURRENT_VALUE - возвращает текущее значение поля.
SYSTEM.CURSOR_BLOCK - возвращает имя курсора блока.
SYSTEM.CURSOR_ITEM - возвращает курсор на текущий элемент блока в формате block_name.item_name.
SYSTEM.CURSOR_RECORD - возвращает последовательный номер курсора записи.
SYSTEM.FORM_STATUS - ' CHANGED ', ' NEW ', ' QUERY '.
SYSTEM.LAST_QUERY - возвращает последний запрос.
SYSTEM.LAST_RECORD - возвращает TRUE, если достигнута последняя запись, и ' FALSE ', если наоборот.
SYSTEM.MESSAGE_LEVEL - эта одна из немногих системных переменных, которая не только возвращает значение, но и принимает его, позволяя разработчику контролировать уровень строгости сообщения. Чем больше уровень строгости, тем меньше системных сообщений
на экране. Если в процессе работы формы требуется вывести сообщение, то оно будет выведено только в том случае, когда уровень этого сообщения больше, чем значение SYSTEM.MESSAGE_LEVEL. В противном случае сообщение будет проигнорировано.
По умолчанию значение SYSTEM.MESSAGE_LEVEL равно 0, и это значит, что Oracle Forms будет выводить любые сообщения. Исходя из списка возможных уровней, мы знаем 6 значений, которые имеет смысл присваивать переменной SYSTEM.MESSAGE_LEVEL: 0, 5, 10, 15, 20, 25. Каждый вышестоящий уровень подавляет нижестоящий. Присвоение переменной SYSTEM.MESSAGE_LEVEL значения 10 будет означать, что все сообщения, имеющие уровень 5 или 10, больше выводиться не будут.
SYSTEM.MODE - возвращает текущий режим форма запроса.
SYSTEM.MOUSE_BUTTON_PRESSED - возвращает значение состояния кнопки. Состояние TRUE означает, что кнопка мыши нажата. SYSTEM.MOUSE_BUTTON_SHIFT_STATE - возвращает состояние курсора на кнопке.
SYSTEM.MOUSE_X_POS - возвращает значение позиции курсора мыши на экране по X.
SYSTEM.MOUSE_Y_POS - возвращает значение позиции курсора мыши на экране по Y.
SYSTEM.RECORD_STATUS - эта переменная показывает, в каком режиме находится запись: CHANGED, INSERT, NEW, QUERY.
SYSTEM.SUPPRESS_WORKING - подавляет стандартные рабочие сообщения, если SYSTEM.SUPPRESS_WORKING:= TRUE.
SYSTEM.TRIGGER_BLOCK - возвращает курсор блока, когда текущий триггер инициализирован.
SYSTEM.TRIGGER_ITEM - возвращает курсор элемента блока, когда текущий триггер инициализирован.
SYSTEM.TRIGGER_RECORD - возвращает последовательный номер записи.
После того как мы рассмотрели основные принципы теории использования системных переменных, перейдем непосредственно к выполнению примеров, которые более наглядно помогут вам разобраться в их нужности и важности.
-
:SYSTEM.CURSOR_BLOCK
Declare Curr_bl varchar2(90):= :system.current_block If :system.current_block='Zak' then Set_block_property(curr_bl, update_allowed, property_false); Set_block_property(curr_bl, delete_allowed, property_false); Set_block_property(curr_bl, insert_allowed, property_false); … End if; End;
В этом примере системная переменная используется для проверки имени блока, и в случае совпадения имени со значением условия выполняется некоторое действие, а именно запрет на операции DML в блоке.
-
:SYSTEM.CURSOR_RECORD
Вы можете использовать эту переменную для генерирования последовательности записей. Например, у вас в блоке одновременно отображается десять записей и вам нужно пронумеровать каждую новую запись. Для этого можно создать триггер WHEN-NEW-ITEM-INSTANCE на уровне блока и в теле триггера написать:
:zak.num:=:SYSTEM.CURSOR_RECORD
Если вы выполните этот пример, то увидите, как при переходе на следующую запись элемент :num принимает значение последовательного номера записи. Можно записать пример намного проще:
Message('Номер записи: ':SYSTEM.CURSOR_RECORD);
- :SYSTEM.DATE_THRESHOLD :System.Date_Threshold := '01:00' ;
- :SYSTEM.EFFECTIVE_DATE :System.Effective_Date := '01-Декабрь-2007 11:00:00' ;
-
:SYSTEM.MOUSE_BUTTON_PRESSED
Declare Btn_press Varchar2(21) := :System.Mouse_Button_Pressed ; Begin If Btn_press = '1' Then Message('Нажата левая кнопка' ); ElsIf Btn_press = '2' Then Message('Нажата правая кнопка' ); Else Message('Другая клавиша' ); End if ; End ;
В этом примере показано, как с помощью системной переменной проверяется нажатие клавиши.
-
:SYSTEM.LAST_RECORD
Begin First_Record ; Loop Exit When :System.last_Record = 'TRUE' ; :num:=: system.cursor_record; Message('Это была запись №_ '||:system.cursor_record) Next_Record ; End loop ; End ;
В этом примере системная переменная :system.last_record используется для проверки условия выхода из цикла, так как возвращает значение ' TRUE ', если текущая запись последняя.
-
:SYSTEM.MESSAGE_LEVEL
Уровни строгости сообщения:
- 0;
- 5;
- 10;
- 15;
- 20;
- 25.
Declare Mess_lev Pls_Integer := :System.Message_Level ; Begin Insert into Zak values(...) :System.Message_Level := 5 ; Commit_Form ; :System.Message_Level := Mess_lev; End ;
В этом примере показан стандартный прием для обхода сообщения "Нет изменений для сохранения". Для начала переменной Mess_ lev присваивается временное значение начального уровня строгости сообщения, а затем переопределяется значение самой системной переменной для фиксации изменений. После того как фиксация прошла, системной переменной присваивается первоначальное значение.
-
:SYSTEM.FORM_STATUS
- CHANGED ;
- NEW ;
- QUERY.
If :SYSTEM.FORM_STATUS = 'CHANGED' Then Message('Форма находится в режиме:'||:SYSTEM.FORM_STATUS); …; End if;
В этом примере проверяется статус формы и выводится на экран в виде сообщения.
-
:SYSTEM.BLOCK_STATUS
- CHANGED ;
- NEW ;
- QUERY.
If :SYSTEM.BLOCK_STATUS = 'Query' Then Go_item(:num); LIST_VALUES; End if ;
В этом примере проверяется статус блока, и если он находится в режиме запроса, то выполняется навигация к элементу и вызывается список значений.
-
:SYSTEM.RECORD_STATUS
- CHANGED ;
- INSERT ;
- NEW ;
- QUERY.
If :SYSTEM.RECORD_STATUS in ('CHANGED') then Commit_form; Go_block('pzak'); Execute_query; End if;
В этом примере проверяется статус блока, и если он находится в режиме изменения, то выполняется сохранение и запрос данных.
-
:SYSTEM.CURRENT_VALUE
If :system.current_value>100 then … End if;
В этом примере идет проверка значения элемента, и если оно больше заданного, то выполняется какое-либо действие.
-
:SYSTEM.MASTER_BLOCK
Copy(name_in(:System.Master_Block||'.primary_item'), 'detail_block.detail_item');
В этом примере системная переменная используется для определения имени Мастер блока. С помощью команды COPY значение первичного ключа Мастер блока ( primary_item ) копируется в элемент подчиненного блока ( detail_block.detail_item ).