В этой статье посмотрим как можно задействовать Range Tables. Создадим Range Tables для четырех полей экрана выбора. Используем транзакцию SE11.
В ABAP/4 существует два типа полей ввода для стандартного экрана выбора:
Parameters - единичные поля.
Select-Options - Внутренние таблицы для задания составных критериев выборки.
Ranges Table как раз и является этой внутренней таблицей для Select-Options. Стандартная форма Select-Options на экране выбора имеет два поля ввода, позволяющих задать единственное значение или интервал. Более сложные критерии задаются на отдельном экране. Range Tables полезны например когда необходимо заполнить составной критерий выборки значениями по умолчанию до появления экрана выбора путем добавления одной или нескольких строк во внутреннюю таблицу, содержащую значения этого критерия.
Внутренняя таблица, соответствующая составному критерию Select-Option, всегда состоит из четырех столбцов: sign(признак), option(операция), low(нижнее значение), high(верхнее значение). Пример таблицы будет виден ниже. Итак идем дальше, создадим Ranges Table для ID.
В качестве элемента данных указываем ранее созданный ZKRE_ID. А вот структуру нужно создать нажимаем на кнопку Create. Выскочило окошко.
Сохраняем и активируем. После этого нажав Back (F3). Попадаем в экран редактирования нашей Range Table, где уже в качестве структуры выбираем только что созданную структуру.
Сохраняем, активируем, и таблица создана. Таким же образом создадим еще три таблицы для оставшихся полей.
Зайдя в навигатор объектов будем имеет примерно следующее.
Изменим текст главной программы.
*&---------------------------------------------------------------------*
*& Report ZKRE_HW4
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zkre_hw4.
TABLES: sscrfields.
DATA: gt_products TYPE zkre_t_hw3,
gs_products LIKE LINE OF gt_products,
it_ran_quant TYPE zkre_r_quant,
wa_ran_quant LIKE LINE OF it_ran_quant.
SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE text-001.
PARAMETERS: p_id TYPE zkre_products-id.
PARAMETERS: p_name TYPE zkre_products-name MODIF ID m1.
SELECT-OPTIONS: p_quant FOR gs_products-quantity.
SELECT-OPTIONS: p_desc FOR gs_products-description NO INTERVALS.
PARAMETERS: p_s1 RADIOBUTTON GROUP uc1,
p_s2 RADIOBUTTON GROUP uc1.
SELECTION-SCREEN END OF BLOCK bl1.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN PUSHBUTTON 1(10) bt1 USER-COMMAND uc2.
INITIALIZATION.
bt1 = text-bt1.
" Делаем поле Name обязательным для заполнения.
AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN.
CASE screen-group1.
WHEN 'M1'.
screen-required = 1.
MODIFY SCREEN.
ENDCASE.
ENDLOOP.
AT SELECTION-SCREEN.
CASE sscrfields-ucomm.
WHEN 'UC2'.
CLEAR: p_id, p_name, p_quant[], p_desc[].
ENDCASE.
START-OF-SELECTION.
REFRESH it_ran_quant.
wa_ran_quant-sign = 'I'.
wa_ran_quant-option = 'EQ'.
wa_ran_quant-low = '3'.
wa_ran_quant-high = ''.
APPEND wa_ran_quant TO it_ran_quant.
IF p_s2 EQ 'X'.
CALL FUNCTION 'ZKRE_FM4'
EXPORTING
ir_quant = it_ran_quant
IMPORTING
er_products = gt_products.
ELSEIF p_s1 EQ 'X'.
ENDIF.
Необходимо создать функциональный модуль ZKRE_FM4. Делаем это через транзакцию SE37 либо двойным кликом по названию модуля прямо в тексте программы. Зайдя в режим редактрования модуля, зададим импортируемые параметры.
Т.е модуль будет импортировать значения Range Table. Перейдем на вкладку экспорт чтобы задать экспортируемые параметры.
Сохраняем и переходим на вкладку исходный код.
Код функционального модуля следующий.
FUNCTION zkre_fm4.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(IR_QUANT) TYPE ZKRE_R_QUANT
*" EXPORTING
*" REFERENCE(ER_PRODUCTS) TYPE ZKRE_T_HW3
*"----------------------------------------------------------------------
SELECT zkre_products~id supply_id name purchase_cost sale_cost quantity description supply_date
INTO CORRESPONDING FIELDS OF TABLE er_products
FROM ( ( zkre_products INNER JOIN zkre_productst ON zkre_productst~prod_id = zkre_products~id )
INNER JOIN zkre_supply ON zkre_supply~id = zkre_products~supply_id )
WHERE quantity IN ir_quant.
ENDFUNCTION.
Запустим на выполнение наш модуль.
Нажимаем на нашу Range Table. И зададим примерно такие значения.
Нажимаем клавишу Back (F3). И отмечаем что в таблице появилась только что нами созданная запись.
Нажимаем выполнить.
В итоге появилась наша таблица с двумя записями, что верно. Нажимаем на значек таблички и смотрим результат.
Продолжим редактирование главной программы. Исходный код будет таким:
*&---------------------------------------------------------------------*
*& Report ZKRE_HW4
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zkre_hw4.
TABLES: sscrfields.
DATA: gt_products TYPE zkre_t_hw3,
gs_products LIKE LINE OF gt_products,
it_ran_quant TYPE zkre_r_quant,
wa_ran_quant LIKE LINE OF it_ran_quant.
SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE text-001.
PARAMETERS: p_id TYPE zkre_products-id.
PARAMETERS: p_name TYPE zkre_products-name MODIF ID m1.
SELECT-OPTIONS: p_quant FOR gs_products-quantity.
SELECT-OPTIONS: p_desc FOR gs_products-description NO INTERVALS.
PARAMETERS: p_s1 RADIOBUTTON GROUP uc1,
p_s2 RADIOBUTTON GROUP uc1.
SELECTION-SCREEN END OF BLOCK bl1.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN PUSHBUTTON 1(10) bt1 USER-COMMAND uc2.
INITIALIZATION.
bt1 = text-bt1.
" Делаем поле Name обязательным для заполнения.
AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN.
CASE screen-group1.
WHEN 'M1'.
screen-required = 1.
MODIFY SCREEN.
ENDCASE.
ENDLOOP.
AT SELECTION-SCREEN.
CASE sscrfields-ucomm.
WHEN 'UC2'.
CLEAR: p_id, p_name, p_quant[], p_desc[].
ENDCASE.
START-OF-SELECTION.
REFRESH it_ran_quant.
wa_ran_quant-sign = 'I'.
wa_ran_quant-option = 'EQ'.
wa_ran_quant-low = '555'.
wa_ran_quant-high = ''.
APPEND wa_ran_quant TO it_ran_quant.
IF p_s2 EQ 'X'.
CALL FUNCTION 'ZKRE_FM4'
EXPORTING
ir_quant = it_ran_quant
IMPORTING
er_products = gt_products.
ELSEIF p_s1 EQ 'X'.
SELECT zkre_products~id supply_id name purchase_cost sale_cost quantity description supply_date
INTO CORRESPONDING FIELDS OF TABLE gt_products
FROM ( ( zkre_products INNER JOIN zkre_productst ON zkre_productst~prod_id = zkre_products~id )
INNER JOIN zkre_supply ON zkre_supply~id = zkre_products~supply_id )
WHERE zkre_products~name EQ p_name.
ENDIF.
LOOP AT gt_products INTO gs_products.
WRITE: / gs_products-id COLOR COL_KEY,
gs_products-supply_id COLOR COL_KEY,
gs_products-name COLOR COL_NORMAL,
gs_products-purchase_cost COLOR COL_NORMAL,
gs_products-sale_cost COLOR COL_NORMAL,
gs_products-quantity COLOR COL_NORMAL,
gs_products-description COLOR COL_NORMAL,
gs_products-supply_date COLOR COL_NORMAL.
ENDLOOP.
Отредактируем наши текстовые переменные.
Селекционный экран нашей программы получается таким.
Сохраняем, активируем программу и нажимаем выполнить. В зависимости от того какую кнопку переключатель выбираем получаем разный результат.
Вот таким образом можно использовать Range Tables. В следующей статье - http://fibed.net/N/ познакомимся с GUI Status.
Михаил
Большое спасибо за проделанную работу.
Получается range работает не как диапазон, а как набор совпадающих элементов в таблице. Хотя значения low и high вводят в заблуждение.
Часть кода, находящегося в selection-screen не явно отрабатывает при открытии и останавливает работу программы.
Вопросы, возникшие при изучении: 1.Какие значения option возможны кроме 'EQ'? 2.Как ещё кроме нажатия на text-001 или text-b01 можно попасть в описания полей? 3. Когда набираю код программы программа предлагает вариант как его принять?
Михаил
На первый вопрос нашел ответ. Option может быть bt,eq, cp если указать bt то будет range.
Михаил
На второй тоже нашел. На главном экране se80, щелкнуть правой клавишей на программу в меню - просмотреть - текстовые элементы.
gos-tlt
Кнопкой TAB либо Enter.
Leo
Вообще RT - это и есть диапазон. Используются в селектах, к примеру есть у тебя SO (С и ПО), вот это и есть диапазон который ты можешь проверить в селекте с помощью IN RT.