Март 2005


Профессионалу разработчику


Полтавский П. В.
разработчик ПО
Компания : www.cgprojects.ru
www.ppol.newmail.ru

Cортировка данных в Oracle Forms 6i.

  1. Постановка задачи.

    При разработке клиентских приложений на Oracle Forms 6i довольно часто возникает необходимость выполнения сортировки по тем или иным базовым полям (например, в случае многозаписных форм табличного вида). Очевидно, что было бы удобно иметь достаточно универсальный механизм, позволяющий выполнять все виды сортировки (по возрастанию и убыванию) для любого поля формы по выбору пользователю. О реализации подобного механизма и пойдёт речь в данной статье.

  2. Описание реализации.

    Рассмотрим набор элементов, поддерживающих работу механизма сортировки:

    • всплывающее меню (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

    1. Исходный текст.

      Ниже приводится исходный текст процедуры сортировки:

      --
      --   Выполняет/отменяет сортировку на базовом блоке формы
      --
      --      Параметры:
      --
      --          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;
      
    2. Заключение.

    Предлагаемый механизм сортировки данных представляется достаточно удобным и простым в реализации и может быть рекомендован для использования при разработке клиентской части приложений на Oracle Forms 6i.

E-mail this page