ошибка: FRM47337 Tree node label can not be null при выполнении скрипта DECLARE |
Сообщения, предупреждения и таймеры
Предупреждение (Alert) - это модальное окно, которое отображает сообщение, предупреждающее оператора о каком-либо событии в приложении.
Используйте предупреждения для вывода дополнительной информации, различных информативных и функциональных сообщений, требующих от пользователя подтвержения или выполнения какого-либо другого действия.
В Oracle Forms вы можете работать с тремя типами предупреждений: "Стоп", "Предупреждение" и "Замечание" – все эти типы можно установить в таблице свойств этого объекта. У каждого типа предупреждения свой уровень строгости. Для каждого типа в таблице свойств вы можете определить три кнопки с нужными вами метками, по умолчанию это "Да" (Кнопка1), "Стоп" (Кнопка2), "Отмена" (Кнопка3). Сообщение, отображаемое предупреждением, задается в свойстве "Сообщение".
При создании Alert вам также необходимо написать триггер для вывода этого предупреждения, а также указать основную информацию, такую как сообщение, которое вы бы хотели в нем выводить.
Далее мы подробнее рассмотрим создание и отображение Предупреждений.
Создание предупреждения
В этом разделе мы пошагово рассмотрим создание сообщения на этапе проектирования.
- В объектном навигаторе выберите узел предупреждения (Alerts).
- Создайте кнопку на форме и назовите ее "Расчет".
- Вызовите таблицу свойств Alert двойным щелчком по иконке.
- Установите стиль Alert, отвечающий вашим требованием, выберите "Стоп", "Предупреждение" или "Замечание".
- Во время выполнения формы рядом с сообщением в окне сигнала будет выводиться иконка, представляющая выбранный вами стиль.
- В окне свойства "Сообщение" наберите следующий текст: "Вывести ли дополнительно информацию по накладной за каждый месяц?" – именно это сообщение отобразится при выводе предупреждения. В редакторе "Сообщение" этого свойства можно ввести не более 200 символов (этот показатель зависит от используемой платформы).Примечание: старайтесь писать сообщения как можно более сжато и осмысленно, так как большие сообщения будут занимать много места на экране и к тому же время вывода такого окна увеличится.
- Определите одну или более кнопок для вашего предупреждения путем ввода текста в значения свойств "Метка Кнопки1", "Метка Кнопки2", "Метка Кнопки3" либо оставьте значения по умолчанию: "Да", "Стоп", "Отмена".Примечание: хотя бы одна кнопка в предупреждении должна иметь именованную метку. Кнопки, не имеющие своих меток, отображаться не будут. При выводе "Предупреждения" кнопки будут располагаться в таком же направлении, как и в таблице свойств.
- Далее выберите кнопку, которая будет активной по умолчанию при каждом запуске вашего предупреждения.
В этом разделе мы с вами детально рассмотрели все шаги создания "предупреждения". В следующем разделе рассмотрим один из способов программного отображения сообщения на экран.
Отображение Предупреждения
Для отображения предупреждения ваша PL/SQL-программа должна содержать встроенную функцию Forms – SHOW_ALERT, которая возвращает цифровую константу, указывающую, на какую из трех кнопок вы нажали. В программе эти кнопки представлены в виде констант численного типа: ALERT_BUTTON1, ALERT_BUTTON2, ALERT_BUTTON3. Порядковый номер констант соответствует номеру метки кнопки. В вашем PL/SQL-коде вызов предупреждения должен выглядеть следующим образом.
Синтаксис функции отображения сообщения:
Show_Alert (alert_name in varchar2) Return NUMBER;
Теперь перейдем к выводу предупреждения.
- Перейдите в Навигатор, затем выделите созданную вами ранее кнопку "Расчет" и вызовите триггер WHEN_BUTTON_PRESSED.
- В теле триггера напишите следующий пример:
When-Button-Pressed Trigger: declare a_lert number; begin a_lert:=Show_alert('Change'); end;
Обратите внимание на то, что функция не вызывается таким образом:
begin Show_alert('Change'); end;
Редактор PL/SQL, естественно, сразу выдаст вам ошибку – error 221: "Show_Alert не является процедурой или не определено", поэтому вызывать предупреждение нужно так, как это было показано в предыдущем примере, то есть через присваивание, т. к. это функция.
- Теперь запустите форму и вызовите предупреждение с помощью созданной кнопки. Поскольку мы не инициировали какие-либо действия при нажатии той или иной кнопки в окне предупреждения, нажатие любой из двух кнопок приведет к закрытию предупреждения.
- Расширим код нашего триггера, добавим к нему обработку кнопок:
When-Button-Pressed Trigger: declare a_lert number; begin a_lert:=Show_alert('Change'); IF alert_button = ALERT_BUTTON1 THEN Go_Block('Расчет'); END IF; end;
Запустите форму и вызовите предупреждение. Теперь при нажатии на кнопку "Да" вы перейдете в блок "Расчеты". Поскольку мы написали в триггере, что выбранная кнопка – ALERT_BUTTON1, необходимо выполнить навигацию к указанному блоку. Если же вы выбрали второй вариант, то есть "Нет", то предупреждение просто закроется, причем это действие мы не инициировали, т. к. вы уже знаете, что оно выполняется по умолчанию.
Мы рассмотрели наиболее актуальные примеры с использованием вызова предупреждений, которые научили вас не только выводить дополнительную информацию, но и инициировать различные события при выборе одного из предложенных вариантов. Теперь давайте рассмотрим пример, в котором некоторые свойства предупреждения будут меняться в ходе выполнения программы.
Set_Alert_Property – устанавливает значение свойства предупреждения.
Set_Alert_Property (alert_name, alert_property, property_value);
Пример:
DECLARE a_lert NUMBER; BEGIN Set_Alert_Property ('Change', ALERT_MESSAGE_TEXT, 'Сегодня '||TO_CHAR (SYSDATE)); a_lert:= Show_Alert ('Change'); END;
При срабатывании этого триггера выводится предупреждение, отображающее текущую дату.
Свойство Set_Alert_Property очень полезно, т. к. программно, изменяя сообщение сигнала, вы можете неплохо сэкономить, повторно используя один и тот же объект предупреждения вместо создания нескольких. Также это дает вам возможность создавать динамические сообщения, которые вы можете менять в зависимости от ситуации, текущего объекта, выбранного элемента или его значения.
Таймер
Таймер ( Timer ) – это средство измерения времени в Oracle Forms. Таймер начинает работать с момента своего создания и работает до тех пор, пока не закроется приложение или таймер не будет удален. Если задать временной интервал, то по истечении заданного времени таймер
вызовет событие WHEN-TIMER- EXPIRED и начнет отсчет времени заново. Таймером очень хорошо пользоваться для непрерывного отслеживания каких-либо действий. Вы также можете использовать таймер как планировщик, закрывая формы по истечении указанного времени, или, например, для выполнения автосохранения в форме.
Программное управление таймером
Oracle Forms позволяет создавать таймер только программным путем, то есть вы не можете создать таймер в навигаторе объектов. Вы можете удалять таймер и устанавливать его характеристики программно, используя встроенные подпрограммы. Ниже перечислены процедуры и функции для работы с таймером:
- CREATE_TIMER ;
- DELETE_TIMER ;
- SET_TIMER ;
- FIND_TIMER.
Создание таймера
CREATE_TIMER – создает таймер с заданным числом миллисекунд и возможностью повторного срабатывания. Возвращает числовой идентификатор таймера.
Синтаксис:
CREATE_TIMER(TIMER_NAME IN varchar2, MILLISECONDS IN number, ITERATE IN number) RETURN FORMS4C.TIMER;
- TIMER_NAME – определяет имя таймера;
- MILLISECONDS – определяет количество миллисекунд, по истечении которых таймер срабатывает, вызывая триггер WHEN-TIMER- EXPIRED ;
-
ITERATE – определяет количество срабатываний таймера. Это свойство принимает два параметра. Если в ITERATE задано 1000, значит, триггер сработает через секунду.
- REPEAT – при указании этой константы триггер WHEN-TIMER- EXPIRED будет срабатывать каждый раз по истечении времени, указанного в ITERATE , до тех пор, пока таймер не будет удален или форма не будет закрыта.
- NO_REPEAT – при указании этой константы триггер WHEN-TIMER- EXPIRED сработает всего один раз по истечении времени, указанного в ITERATE .
Пример:
DECLARE TimerId Timer; BEGIN TimerId:= Find_Timer ('T_Timer'); IF NOT Id_Null (TimerId) THEN Delete_Timer (TimerId); END IF; TimerId:= Create_Timer ('T_TIMER', 1000, NO_REPEAT); END;
Удаление таймера
DELETE_TIMER – удаляет таймер, принимая в качестве параметра его идентификатор, полученный при создании командой CREATE_ TIMER, или его имя.
Синтаксис возможный процедур DELETE_TIMER:
-
DELETE_TIMER(TIMER_NAME IN varchar2) ;
- TIMER_NAME – определяет имя таймера;
-
DELETE_TIMER(TIMER_ID IN FORMS4C.TIMER) ;
- TIMER_ID – идентификатор, полученный при создании командой CREATE_TIMER.
Пример:
- DELETE_TIMER('T_Timer') ;
-
DECLARE TimerId Timer; BEGIN TimerId:= Find_Timer ('T_Timer'); IF NOT Id_Null (TimerId) THEN Delete_Timer (TimerId); END IF;
Установка характеристик таймера
SET_TIMER – устанавливает значения свойств таймера, таких как временной интервал и количество итераций. Синтаксис:
SET_TIMER (TIMER_NAME IN varchar2 [TIMER_ID IN FORMS4C. TIMER], MILLISECONDS IN number, ITERATE IN number) RETURN FORMS4C.TIMER;
- TIMER_NAME – определяет имя таймера;
- TIMER_ID – идентификатор, полученный при создании командой CREATE_TIMER ;
- MILLISECONDS – определяет количество миллисекунд, по истечении которых таймер срабатывает, вызывая триггер WHEN-TIMER- EXPIRED ;
-
ITERATE – определяет количество срабатываний таймера. Это свойство принимает два параметра:
- REPEAT – при указании этой константы триггер WHEN-TIMER- EXPIRED будет срабатывать каждый раз по истечении времени, указанного в ITERATE , до тех пор, пока таймер не будет удален или форма не будет закрыта;
- NO_REPEAT – при указании этой константы триггер WHEN-TIMER- EXPIRED сработает всего один раз по истечении времени, указанного в ITERATE .
Создание системы оповещения
В этом примере будет показано, как можно с помощью таймера быстро создать несложную систему оповещения. Для наглядности примера мы создадим две формы – форму-оповещение ( Client_1 ) и форму-приемщик ( Client_2 ).
Предварительная подготовка
Создайте тестовую таблицу T_taime для демонстрации примера:
CREATE TABLE t_taime ( Mes_str varchar2(100), Prz number);
- Создайте новую форму и сохраните ее как Client_1.fmb.
- Создайте Блок Данных на основе таблицы T_taime.
- Для элемента Mes_str установите свойство Prompt – "Сообщение клиента 1", а для PRZ – "Отправить сообщение". Для элемента PRZ установите следующие свойства:
- Создайте триггер WHEN-CHECK-BOX-CHANGED для элемента PRZ. В теле триггера напишите следующий код:
WHEN-CHECK-BOX-CHANGED commit_form;
Форма оповещения готова, теперь перейдем к созданию второй формы, которая будет принимать сигнал оповещения и выполнять какое-либо действие.
- Создайте новую форму и сохраните ее как Client_2.fmb.
- Создайте блок данных на основе таблицы T_taime. В свойстве WHERE CLAUSE укажите условие PRZ=1.
- Для элемента Mes_str установите свойство Prompt – "Сообщение клиента 1". Элемент PRZ разместите на NULL -канве, то есть оставьте на канве только один элемент.
- Создайте триггер WHEN-NEW-FORM-INSTANCE на уроне формы и напишите в нем следующий код:
WHEN-NEW-FORM-INSTANCE DECLARE timer_id Timer; one_second NUMBER:= 1000; BEGIN timer_Id:= Find_Timer ('mes_timer'); IF NOT Id_Null (Timer_Id) THEN Delete_Timer (Timer_Id); END IF; timer_id:= CREATE_TIMER('mes_timer', one_second, REPEAT); END;
- Создайте параметр OLD_REC_CNT и установите нулевое начальное значение.
- Создайте триггер WHEN-TIMER- EXPIRED на уровне формы. В теле триггера напишите следующий код:
WHEN-TIMER-EXPIRED DECLARE rec_cnt number; BEGIN SELECT count(*) INTO rec_cnt FROM t_ime; IF :parameter.old_rec_cnt<>rec_cnt THEN execute_query; END IF; :parameter.old_rec_cnt:=rec_cnt; END;
Для того чтобы проверить выполненный нами пример, запустите две формы одновременно и расположите их на экране так, чтобы было видно два окна. Перейдите в форму Client_1, введите новую запись и включите переключатель, после чего в форме Client_2 через секунду появится новая запись. В триггере WHEN-TIMER- EXPIRED мы отслеживаем изменение количества записей в таблице, поэтому если запись была выключена из списка передаваемых значений, то она также будет выключена из списка полученных сообщений. Запись исключается из общего списка передаваемых сообщений отменой выбора значения переключателя.