ABAP: Красивый

от автора

Эта публикация предназначена для 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *