
Март 2005
Профессионалу разработчику
Полтавский П. В.
разработчик ПО
Компания : www.cgprojects.ru
www.ppol.newmail.ru
Cортировка данных в Oracle Forms 6i.
- Постановка задачи.
При разработке клиентских приложений на Oracle Forms 6i довольно часто возникает необходимость выполнения сортировки по тем или иным базовым полям (например, в случае многозаписных форм табличного вида). Очевидно, что было бы удобно иметь достаточно универсальный механизм, позволяющий выполнять все виды сортировки (по возрастанию и убыванию) для любого поля формы по выбору пользователю. О реализации подобного механизма и пойдёт речь в данной статье.
- Описание реализации.
Рассмотрим набор элементов, поддерживающих работу механизма сортировки:
- всплывающее меню (SET_ORDER_BY_MENU), создается в разделе Popup Menus объектного навигатора Oracle Forms Builder. Состоит из следующих пунктов: Сортировать по возрастанию, Сортировать по убыванию, Отменить сортировку (этот пункт упорядочивает записи в соответствии с порядком сортировки, заданным на базовом блоке по умолчанию). Каждый из этих пунктов реализует вызов процедуры сортировки с соответствующим параметром. Это меню определяется и хранится в библиотечной (ссылочной) форме, используемой для хранения стандартных элементов и классов свойств приложения
- процедура сортировки (STD_SYSTOR_Sorter), непосредственно реализующая выполнение сортировки на базовом блоке формы. Определяется в и хранится в PLL библиотеке приложения (см. п. 3 данной статьи).
Для того, чтобы подключить механизм сортировки для использования в какой-либо форме, в Oracle Forms Builder необходимо выполнить следующие действия:
- создать в форме ссылку на всплывающее меню SET_ORDER_BY_MENU, определённое в ссылочной (библиотечной) форме приложения (см. рис. 1)
- присоединить (если не присоединена) PLL библиотеку приложения к ссылочной форме
- для поля базового блока формы, по которому предполагается выполнять сортировку, в значение свойства Popup Menu (раздел Functional) выбрать SET_ORDER_BY_MENU. Это необходимо выполнить для всех сортируемых полей (все эти поля обязательно должны быть базовыми, т.е. связанными с соответствующими столбцами таблицы/представления базового блока)
Рис. 1
Для выполнения сортировки в открытой форме приложения пользователю достаточно установить курсор на сортируемое поле и нажать правую кнопку мыши, после чего появляется контекстное меню сортировки (см. рис. 2).
>
Рис. 2
- Исходный текст.
Ниже приводится исходный текст процедуры сортировки:
--
-- Выполняет/отменяет сортировку на базовом блоке формы
--
-- Параметры:
--
-- p_increase_flag (Вх) - определяет порядок сортировки и
-- может принимать значения 'ASC','DESC'
-- Если не задан, происходит возврат к
-- исходному (default) значению ORDER_BY блока
--
--
PROCEDURE STD_SYSTOR_Sorter (p_increase_flag in varchar2 default null) IS
v_str_dflt_ord_by VARCHAR2(200);
v_str_ord_by VARCHAR2(200);
v_repl_str_ord_by VARCHAR2(200);
--
v_global_nm_dflt_ord_by VARCHAR2(100);
v_global_nm_ord_by VARCHAR2(100);
--
v_cursor_item VARCHAR2(50);
v_delimiter VARCHAR2(1);
v_empty VARCHAR2(1):=' ';
v_curr_form VARCHAR2(100):=GET_APPLICATION_PROPERTY(CURRENT_FORM_NAME);
v_init_flag BOOLEAN :=FALSE;
--
-- Функция проверки существования поля блока в текущей строке сортировки.
--
FUNCTION Is_Item (p_order_by in varchar2,
p_item in varchar2,
p_order_by_type in varchar2) RETURN VARCHAR2 IS
v_ret VARCHAR2(200):='N';
v_order_by VARCHAR2(200);
v_str VARCHAR2(50);
BEGIN
v_order_by:=p_order_by;
v_str:=p_item||' ASC';
--
if INSTR(v_order_by,v_str) > 0 then
v_ret:=REPLACE(v_order_by,v_str,p_item||p_order_by_type);
end if;
--
v_str:=p_item||' DESC';
--
if INSTR(p_order_by,v_str) > 0 then
v_ret:=REPLACE(v_order_by,v_str,p_item||p_order_by_type);
end if;
--
return v_ret;
END Is_Item;
--
BEGIN
v_global_nm_dflt_ord_by:='GLOBAL.'||v_curr_form||'_'||NAME_IN('system.cursor_block')||'_ORDER_BY';
v_global_nm_ord_by:='GLOBAL.'||v_curr_form||'_'||NAME_IN('system.cursor_block')||'_CURR_ORDER_BY';
DEFAULT_VALUE('*',v_global_nm_dflt_ord_by);
DEFAULT_VALUE('*',v_global_nm_ord_by);
--
if NAME_IN(v_global_nm_dflt_ord_by) = '*' then
v_str_dflt_ord_by:=GET_BLOCK_PROPERTY(NAME_IN('system.cursor_block'), ORDER_BY);
COPY(v_str_dflt_ord_by, v_global_nm_dflt_ord_by);
end if;
--
if NAME_IN(v_global_nm_ord_by) = '*' then
COPY(v_empty, v_global_nm_ord_by);
v_init_flag:=TRUE;
end if;
--
v_delimiter:=',';
v_cursor_item:=SUBSTR(NAME_IN('system.cursor_item'),instr(NAME_IN('system.cursor_item'),'.')+1,
length(NAME_IN('system.cursor_item'))-instr(NAME_IN('system.cursor_item'),'.'));
v_str_ord_by:=NAME_IN(v_global_nm_ord_by);
--
if v_str_ord_by is null then
v_delimiter:=' ';
end if;
--
IF UPPER(p_increase_flag) = 'ASC' then
v_repl_str_ord_by:=Is_Item(v_str_ord_by,v_cursor_item,' ASC');
if v_init_flag then
v_str_ord_by:=v_cursor_item||' ASC';
else
v_str_ord_by:=v_str_ord_by||v_delimiter||v_cursor_item||' ASC';
end if;
else
v_str_ord_by:=v_repl_str_ord_by;
end if;
COPY(v_str_ord_by, v_global_nm_ord_by);
SET_BLOCK_PROPERTY(NAME_IN('system.cursor_block'),ORDER_BY,v_str_ord_by);
ELSIF UPPER(p_increase_flag) = 'DESC' then
v_repl_str_ord_by:=Is_Item(v_str_ord_by,v_cursor_item,' DESC');
if v_repl_str_ord_by = 'N' then
if v_init_flag then
v_str_ord_by:=v_cursor_item||' DESC';
else
v_str_ord_by:=v_str_ord_by||v_delimiter||v_cursor_item||' DESC';
end if;
else
v_str_ord_by:=v_repl_str_ord_by;
end if;
COPY(v_str_ord_by, v_global_nm_ord_by);
SET_BLOCK_PROPERTY(NAME_IN('system.cursor_block'),ORDER_BY,v_str_ord_by);
ELSIF p_increase_flag IS NULL then
SET_BLOCK_PROPERTY(NAME_IN('system.cursor_block'),ORDER_BY,v_str_dflt_ord_by);
COPY(v_str_dflt_ord_by, v_global_nm_ord_by);
END IF;
--
DO_KEY('EXECUTE_QUERY');
GO_ITEM(NAME_IN('system.cursor_block')||'.'||v_cursor_item);
END;
- Заключение.
Предлагаемый механизм сортировки данных представляется достаточно удобным и простым в реализации и может быть рекомендован для использования при разработке клиентской части приложений на Oracle Forms 6i.
|