Приходилось ли Вам сталкиваться с ситуацией, когда стандартные ALV отчёты удовлетворяют частично Вашим потребностям, но при этом код в этих отчётах устроен слишком сложно, чтобы сразу понять всю логику выбора данных? Переписывать всю логику при этом будет достаточно накладно, но многие так и делают 🙂
Некоторые отчёты позволяют сделать обёртку над ними, они предоставляют все выбранные через них данные, получить к ним доступ можно через EXPORT TO MEMORY/IMPORT FROM MEMORY. В качестве примера может служить транзакция IA09 (программа riplko10), получить доступ к выбранным в ней данным можно следующим образом:
1 2 3 4 5 6 7 |
SUBMIT riplko10 WITH SELECTION-TABLE lt_selscreen WITH pn_iflo = abap_true "Select Func Loc Tasklists WITH dy_tcode = 'IA09' WITH dy_selm = 'D' "Dark mode AND RETURN. IMPORT sel_tab FROM MEMORY ID 'RIPLKO10'. |
К сожалению не все программы позволяют получить данные из них таким образом. Но в SAP предусмотрена техника получения данных из любого SAP GUI ALV отчёта без использования модификаций/расширений.
Когда ALV отчёт запускается, вся информация об экземпляре ALV (формат, каталог полей, ключевые поля, фильтры, данные и т.д.) сохраняется и доступна через статические методы класса CL_SALV_BS_RUNTIME_INFO. Благодаря ему можно получить данные, из запускаемой через submit программы, без каких либо модификаций.
Данный класс насчитывает около 20 методов, но только некоторые из них будут интересными для нас:
Метод SET() – отчищает все данные в памяти этого класса, должен использоваться Вами перед непосредственным вызовом программы. Метод имеет следующие параметры:
- Display – необходимо установить в abap_false, параметр включает так называемый «темный режим» для всех ALV экземпляров, т.о. говорит о том что выводить их не нужно.
- Metadata – установив данный параметр в abap_false, вы тем самым отключите выгрузку в память всех метаданных ALV, таких как фильтры, каталог полей и т.д.
- Data – установив в abap_true вы тем самым включаете выгрузку в память самих данных используемых в ALV.
Метод GET_DATA_REF() – очень полезный метод, позволяет получить ссылку на внутреннюю таблицу с данными — используется, в случае если структура данных не известна. Параметры:
- R_DATA – выдаёт ссылку на таблицу (..REF TO DATA)
- R_DATA_LINE – если ALV отчёт запущен в иерархическом списке, в данном параметре будет ссылка на строку используемую в таблице.
Метод GET_DATA() – метод, используемый в том случае, когда вам точно известна структура внутренней таблицы с данными, используемая в ALV. Параметры:
- T_DATA – экспортный параметр, внутренняя таблица с данными
- T_DATA_LINE — если ALV отчёт запущен в иерархическом списке, в данном параметре будет строка используемую в таблице.
Метод CLEAR_ALL() – данный метод отчищает все данные из памяти, сбрасывает все флаги установленные методом SET(). Обязательно используйте в случае, если после получения данных из программы будете выводить свой ALV, т.к. параметры, установленные в методе SET() могут повлиять на его вывод.
Данная методика позволяет получить данные из отчетов, использующих любой вид ALV таблицы: ALV Grid, ALV List, Иерархический ALV список.
Ну и напоследок пример получения данных из транзакции MB51 (программа RM07DOCS):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
REPORT zalv_runtime_info. TABLES: mara. DATA: rspar TYPE TABLE OF rsparams, wa_rspar LIKE LINE OF rspar, lt_data_ref TYPE REF TO DATA, go_salv_table TYPE REF TO cl_salv_table. FIELD-SYMBOLS: <fs_table> TYPE STANDARD TABLE. SELECT-OPTIONS: so_matnr FOR mara-matnr. wa_rspar-selname = 'MATNR'. wa_rspar-KIND = 'S'. wa_rspar-SIGN = 'I'. wa_rspar-OPTION = 'EQ'. wa_rspar-LOW = so_matnr-LOW. APPEND wa_rspar TO rspar. cl_salv_bs_runtime_info=>set( display = abap_false metadata = abap_false DATA = abap_true ). SUBMIT RM07DOCS WITH SELECTION-TABLE rspar AND RETURN. TRY. cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = lt_data_ref ). CATCH cx_salv_bs_sc_runtime_info. MESSAGE 'Ошибка при получении данных' TYPE 'E'. ENDTRY. cl_salv_bs_runtime_info=>clear_all( ). ASSIGN lt_data_ref->* TO <fs_table>. TRY. cl_salv_table=>factory( EXPORTING list_display = IF_SALV_C_BOOL_SAP=>true IMPORTING r_salv_table = go_salv_table CHANGING t_table = <fs_table> ). CATCH cx_salv_msg . MESSAGE 'Ошибка при создании экземпляра ALV объекта' TYPE 'E'. ENDTRY. go_salv_table->display( ). |
Добрый день.
Спасибо за описание.
Несколько замечаний:
1) Пример с MB51 некорректный. Т.к. данные в MB51 выводятся в виде иерархического списка.
У вас в примере вы получили таблицу данных заголовка, а нужно еще получить таблицу данных позиций.
Сделал вот так:
zcl_salv_bs_runtime_info=>set(
display = abap_false
metadata = abap_true
data = abap_true ).
*Вызываем MB51
submit rm07docs with selection-table seltab and return.
*Данные отчета MB51
try.
zcl_salv_bs_runtime_info=>get_data_ref(
importing
r_data_line = lt_data_i ).
catch cx_salv_bs_sc_runtime_info.
message ‘Ошибка при получении данных’ type ‘E’.
endtry.
*Мета-данные отчета MB51
try.
ls_metadata = zcl_salv_bs_runtime_info=>get_metadata( ).
catch cx_salv_bs_sc_runtime_info.
message ‘Ошибка при получении данных’ type ‘E’.
endtry.
zcl_salv_bs_runtime_info=>clear_all( ).
assign lt_data_i->* to .
create data ref_ls_alv like line of .
assign ref_ls_alv->* to .
*Каталог полей из MB51
lt_fcat = ls_metadata-t_fcat.
*Создаем таблицу по каталогу полей
call method cl_alv_table_create=>create_dynamic_table
exporting
it_fieldcatalog = lt_fcat
importing
ep_table = tab1.
assign tab1->* to .
*Создаем тип (строка таблицы)
create data p_line like line of .
assign p_line->* to .
*Перекладываем данные из MB51 в созданную таблицу
loop at into .
l_tabix = sy-tabix.
move-corresponding to .
append to .
endloop.
В своем примере использовал интерфейс классов ZCL_SALV_BS_RUNTIME_INFO(копия CL_SALV_BS_RUNTIME_INFO). О причинах — ниже.
2) Есть вопросы к интерфейсу классов CL_SALV_BS_RUNTIME_INFO.
Метод method get_data.
Нужно добавить проверку:
if t_data is requested.
….
перед вызовом оператора:
import t_data to t_data from memory id zcl_salv_bs_runtime_info=>c_memid_data.
Иначе, если будете работать с отчетами, в которых данные выводятся в виде иерархических списков может быть дамп(как было у меня).
Добрый вечер, не совсем понятны ваши замечания, на моей системе пример абсолютно работоспособный 🙂
Доброе утро.
Пример рабочий, вопросов нет. 🙂
При запуске отчета zalv_runtime_info что у вас выводится в грид?
Я так понимаю всего 4 поля: материал, краткий текст материала, завод, имя 1.
Так?
Все понял, спасибо за замечания!
Тебе спасибо большое за пример!
И еще — вывод в Грид лучше делать формируя грид по каталогу полей стандартного отчета(в примере это MB51). Потому что во внутренней таблице данных много «левых» полей, которых нет в каталоге полей.