Эта публикация предназначена для ABAP-разработчиков в SAP ERP и всем им сочувствующим.
Немногие знают, что в ALV можно подключать HTML-заголовки. Еще больше не знают, что можно сделать красивый стандартный выпадающий список, он же select-box, только для такой по сути стандартной фичи, потребуется много вашего Z-кода.
Выглядит примерно так:
Добро пожаловать под кат.
Поехали! Определим глобальные переменные:
— Выходная таблица нашего отчета, пусть она будет на основе всем известной таблицы MARA;
— Переменная, в которой мы будем хранить текущее значение выбранной в селект-боксе;
— константу с подпрограммой для HTML-header;
— класс-handler, который будет срабатывать при выборе данных, и объект handler.
*----------------------------------------------------------------------* * Определение глобальных переменных *----------------------------------------------------------------------* TYPE-POOLS: slis. TABLES: mara. DATA: gt_data TYPE TABLE OF mara WITH HEADER LINE, gv_matnr TYPE mara-matnr. CONSTANTS: gc_form_top TYPE slis_formname VALUE 'DO_HTML_TOP_OF_PAGE'. *----------------------------------------------------------------------* * CLASS cl_my_event_handler DEFINITION *----------------------------------------------------------------------* CLASS cl_my_event_handler DEFINITION. PUBLIC SECTION. METHODS: handle_selections FOR EVENT selected OF cl_dd_select_element IMPORTING sender. ENDCLASS. DATA: go_hand1 TYPE REF TO cl_my_event_handler.
Напишем главную программу отчета и подпрограммы по инициализации, получении данных и выводе отчета. Здесь особо отмечу, что нужно создать объект handler и подключить HTML-заголовок: i_callback_html_top_of_page = gc_form_top.
*----------------------------------------------------------------------* * Отчет *----------------------------------------------------------------------* SELECT-OPTIONS: so_matnr FOR mara-matnr. INITIALIZATION. PERFORM init. START-OF-SELECTION. PERFORM get_data. END-OF-SELECTION. PERFORM reuse_alv. *&---------------------------------------------------------------------* *& Form init *&---------------------------------------------------------------------* FORM init. " -------------------------------------------------- " " Создадим объект хендлера " -------------------------------------------------- " CREATE OBJECT go_hand1. ENDFORM. *&---------------------------------------------------------------------* *& Form get_data *&---------------------------------------------------------------------* FORM get_data. " -------------------------------------------------- " " Получим данные " -------------------------------------------------- " SELECT * FROM mara INTO TABLE gt_data WHERE matnr IN so_matnr. CHECK: sy-subrc IS INITIAL. SORT: gt_data BY matnr. ENDFORM. "get_data *&---------------------------------------------------------------------* *& Form reuse_alv *&---------------------------------------------------------------------* FORM reuse_alv. DATA: lt_fieldcat TYPE TABLE OF lvc_s_fcat. CHECK gt_data[] IS NOT INITIAL. " -------------------------------------------------- " " Вывод ALV " -------------------------------------------------- " CALL FUNCTION 'LVC_FIELDCATALOG_MERGE' EXPORTING i_structure_name = 'MARA' CHANGING ct_fieldcat = lt_fieldcat[] EXCEPTIONS inconsistent_interface = 1 program_error = 2 OTHERS = 3. CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC' EXPORTING i_callback_program = sy-repid i_callback_html_top_of_page = gc_form_top it_fieldcat_lvc = lt_fieldcat[] i_save = 'A' TABLES t_outtab = gt_data[]. ENDFORM. "reuse_alv
Для HTML-хедера создаем подпрограмму с именем, указанным в глобальном константе. Вызовем из нее подпрограмму, которая создаст нашу красоту:
*&---------------------------------------------------------------------* *& Form do_html_top_of_page *&---------------------------------------------------------------------* FORM do_html_top_of_page USING p_doc TYPE REF TO cl_dd_document. DATA: lo_form TYPE REF TO cl_dd_form_area, lo_sele TYPE REF TO cl_dd_select_element. " -------------------------------------------------- " " Создадим область " -------------------------------------------------- " CALL METHOD p_doc->add_form IMPORTING formarea = lo_form. " -------------------------------------------------- " " Создадим селект-бокс " -------------------------------------------------- " PERFORM add_casebox TABLES gt_data CHANGING gv_matnr lo_form lo_sele. ENDFORM. "do_html_top_of_page
Посмотрим подпрограмму по созданию селект-бокса. Здесь отмечу, что если в отчете была команда, снять фильтры, зачищаем нашу глобальную переменную (gv_matnr) со значением. Потом создаем линию, в которую добавляем заголовок фильтра, вызываем подпрограмму, которая заполнит нам значения в нем, и сам фильтр на форму, закрываем линию:
*&---------------------------------------------------------------------* *& Form add_casebox *&---------------------------------------------------------------------* FORM add_casebox *&---------------------------------------------------------------------* TABLES it_data STRUCTURE mara CHANGING iv_matnr TYPE mara-matnr lo_form TYPE REF TO cl_dd_form_area lo_selec TYPE REF TO cl_dd_select_element. *&---------------------------------------------------------------------* DATA: lt_opt_tab TYPE sdydo_option_tab, lv_text TYPE sdydo_text_element. *----------------------------------------------------------------------* DO. CASE sy-index. WHEN 1. " -------------------------------------------------- " " Отмена фильтров " -------------------------------------------------- " CHECK sy-ucomm EQ '&ILD'. CLEAR: iv_matnr. WHEN 2. " -------------------------------------------------- " " Начало линии " -------------------------------------------------- " CALL METHOD lo_form->line_with_layout EXPORTING start = 'X'. WHEN 3. " -------------------------------------------------- " " Заголовок селект-бокса " -------------------------------------------------- " lv_text = 'Материал:'. CALL METHOD lo_form->add_text EXPORTING text = lv_text. WHEN 4. " -------------------------------------------------- " " Разделитель " -------------------------------------------------- " CALL METHOD lo_form->add_gap EXPORTING width = 2. WHEN 5. " -------------------------------------------------- " " Заполним таблицу значений " -------------------------------------------------- " PERFORM fill_mat_tab TABLES it_data CHANGING iv_matnr lt_opt_tab. WHEN 6. " -------------------------------------------------- " " Добавим сам селект-бокс " -------------------------------------------------- " CALL METHOD lo_form->add_select_element EXPORTING OPTIONS = lt_opt_tab value = 'P' IMPORTING select_element = lo_selec. WHEN 7. " -------------------------------------------------- " " Подключим хендлер " -------------------------------------------------- " SET HANDLER go_hand1->handle_selections FOR lo_selec. WHEN 8. " -------------------------------------------------- " " Окончание линии " -------------------------------------------------- " CALL METHOD lo_form->line_with_layout EXPORTING end = 'X'. WHEN OTHERS. EXIT. ENDCASE. ENDDO. ENDFORM.
В программе по заполнению фильтра добавим сначала то значение, которое сейчас выбрано, чтобы оно было первым в списке. Потом добавим значение Все, если у нас в таблице больше одного значения. И потом все записи из таблицы:
*&---------------------------------------------------------------------* *& Form fill_mat_tab *&---------------------------------------------------------------------* FORM fill_mat_tab *&---------------------------------------------------------------------* TABLES it_data STRUCTURE mara CHANGING iv_matnr TYPE matnr it_optab TYPE sdydo_option_tab. *&---------------------------------------------------------------------* DATA: ls_opt TYPE sdydo_option. REFRESH: it_optab. *----------------------------------------------------------------------* DO. CASE sy-index. WHEN 1. " -------------------------------------------------- " " Сохраним значение если оно выбрано " -------------------------------------------------- " CHECK iv_matnr IS NOT INITIAL. ls_opt-value = iv_matnr. ls_opt-text = iv_matnr. APPEND ls_opt TO it_optab. WHEN 2. " -------------------------------------------------- " " Если значение не одно, добавим строчку - Все " -------------------------------------------------- " READ TABLE it_data INDEX 1. LOOP AT it_data TRANSPORTING NO FIELDS WHERE matnr NE it_data-matnr. ls_opt-value = '*'. ls_opt-text = 'Все'. APPEND ls_opt TO it_optab. EXIT. ENDLOOP. WHEN 3. " -------------------------------------------------- " " Добавим все значения " -------------------------------------------------- " LOOP AT it_data WHERE matnr IS NOT INITIAL. ls_opt-value = it_data-matnr. ls_opt-text = it_data-matnr. COLLECT ls_opt INTO it_optab. ENDLOOP. WHEN OTHERS. EXIT. ENDCASE. ENDDO. ENDFORM.
Внедрим наш handler. Здесь в sender->value значение, выбранное пользователем. Запишем его сразу в нашу глобальную переменную gv_matnr. В подпрограмме set_filter по обработке стандартной фильтрации:
1) Получим глобальный grid в локальный объект;
2) Получим уже установленные параметры фильтрации, и снимем уже установленный ранее фильтр, по полю, которое мы фильтруем, через селект-бокс;
3) Добавим новые параметры фильтрации;
4) Сохраним фильтр;
5) Обновим отчет.
*----------------------------------------------------------------------* * CLASS cl_my_event_handler IMPLEMENTATION *----------------------------------------------------------------------* CLASS cl_my_event_handler IMPLEMENTATION. METHOD handle_selections. DATA text_buff TYPE sdydo_text_element. text_buff = sender->value. gv_matnr = text_buff. " -------------------------------------------------- " " Установим фильтр в отчете " -------------------------------------------------- " PERFORM set_filter TABLES gt_data USING gv_matnr . ENDMETHOD. "handle_selections ENDCLASS. "cl_my_event_handler IMPLEMENTATION *&---------------------------------------------------------------------* *& Form set_filter *&---------------------------------------------------------------------* FORM set_filter *&---------------------------------------------------------------------* TABLES it_data STRUCTURE mara USING iv_value TYPE mara-matnr. *&---------------------------------------------------------------------* DATA: lo_ref1 TYPE REF TO cl_gui_alv_grid, lt_filtered TYPE lvc_t_filt, lv_field TYPE char10 VALUE 'MATNR', ls_filter LIKE LINE OF lt_filtered. *----------------------------------------------------------------------* DO. CASE sy-index. WHEN 1. " -------------------------------------------------- " " Получим объект ALV " -------------------------------------------------- " CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR' IMPORTING e_grid = lo_ref1. WHEN 2. " -------------------------------------------------- " " Получим итоги и уберем фильтр уст. в прошлый раз " -------------------------------------------------- " CALL METHOD lo_ref1->get_filter_criteria IMPORTING et_filter = lt_filtered. DELETE lt_filtered WHERE fieldname = lv_field. WHEN 3. " -------------------------------------------------- " " Добавим новый фильтр " -------------------------------------------------- " CHECK iv_value NE '' AND iv_value NE '*'. ls_filter-fieldname = lv_field. ls_filter-sign = 'I'. ls_filter-option = 'EQ'. ls_filter-low = iv_value. APPEND ls_filter TO lt_filtered. WHEN 4. " -------------------------------------------------- " " Сохраним фильтр " -------------------------------------------------- " CALL METHOD lo_ref1->set_filter_criteria EXPORTING it_filter = lt_filtered EXCEPTIONS no_fieldcatalog_available = 1 OTHERS = 2. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. WHEN 5. " -------------------------------------------------- " " Обновим ALV " -------------------------------------------------- " lo_ref1->refresh_table_display( ). WHEN OTHERS. EXIT. ENDCASE. ENDDO. ENDFORM.
Запускаем! Любуемся на итог страданий:
Вроде простая штука, а в SAPе нужно постараться еще. Всем спасибо.
ссылка на оригинал статьи https://habrahabr.ru/post/275677/
Добавить комментарий