Существует как минимум 3 способа создания динамических таблиц:
- Используется в старых системах, через генерацию программы (GENERATE SUBROUTINE POOL).
- Используя класс CL_ALV_TABLE_CREATE.
- Используя RTTS (Run Time Type Services).
В данной статье будут рассмотрены все три, примеры максимально упрощены для понимания.
GENERATE SUBROUTINE POOL
В старых системах (до версии ABAP 6.40) для генерации динамической таблицы (или структуры) использовался метод динамического создания подпрограммы с использованием оператора GENERATESUBROUTINEPOOL. Пример реализации:
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 56 57 58 59 60 61 62 63 64 65 |
REPORT zdyn_itab_old. * DATA: dy_table TYPE REF TO DATA, dy_line TYPE REF TO DATA. * FIELD-SYMBOLS: <dyn_table> TYPE STANDARD TABLE, <dyn_wa>. * FIELD-SYMBOLS: <fs> TYPE ANY. * DATA: ls_source TYPE STRING. DATA: lt_source LIKE STANDARD TABLE OF ls_source WITH HEADER LINE. * DATA: l_name LIKE sy-repid. DATA: l_message(240) TYPE C, l_line TYPE I, l_word(72) TYPE C. * DATA: l_form(30) TYPE C VALUE 'TABLE_CREATE'. * *..................................................................... START-OF-SELECTION. lt_source = 'REPORT ZTEST_SUBROUTINE_POOL.'. APPEND lt_source. lt_source = 'FORM TABLE_CREATE USING I_FS TYPE ANY.'. APPEND lt_source. * Определяем динамическую структуру таблицы lt_source = 'DATA: BEGIN OF LT_GENTAB OCCURS 0.'. APPEND lt_source. lt_source = 'DATA: BUKRS TYPE BUKRS. '. APPEND lt_source. lt_source = 'DATA: BKTXT TYPE BKTXT. '. APPEND lt_source. lt_source = 'DATA: END OF LT_GENTAB.'. APPEND lt_source. lt_source = 'DATA: POINTER TYPE REF TO DATA.'. APPEND lt_source. lt_source = 'CREATE DATA POINTER LIKE STANDARD TABLE OF LT_GENTAB.'. APPEND lt_source. lt_source = 'I_FS = POINTER.'. APPEND lt_source. lt_source = 'ENDFORM. '. APPEND lt_source. l_name = 'ZTEST_SUBROUTINE_POOL'. CATCH SYSTEM-EXCEPTIONS generate_subpool_dir_full = 9. GENERATE SUBROUTINE POOL lt_source NAME l_name MESSAGE l_message LINE l_line WORD l_word. "#EC CI_GENERATE ENDCATCH. * В случае ошибки выведем сообщение IF NOT l_message IS INITIAL. MESSAGE e000(0k) WITH l_message l_line l_word. ENDIF. ASSIGN dy_table TO <fs>. * Вызываем подпрограмму из сгенерированной программы PERFORM (l_form) IN PROGRAM (l_name) USING <fs>. * Получаем определение типа данных и присваиваем динамической переменной ASSIGN dy_table->* TO <dyn_table>. * * Создаем тип данных, как строку сформированной таблицы CREATE DATA dy_line LIKE LINE OF <dyn_table>. * Получем определение строки таблицы и присваеваем дин. переменной ASSIGN dy_line->* TO <dyn_wa>. |
CL_ALV_TABLE_CREATE
Второй способ подразумевает использование класса CL_ALV_TABLE_CREATE и его статического метода create_dynamic_table. На вход мы должны передать каталог полей (внутреняя таблица определенной структуры, описывающая из каких полей будет состоять таблица), на выходе получим ссылочную переменную на созданный тип данных. Данный способ является по сути ООП обёрткой над предыдущим. Пример реализации:
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 |
REPORT ztest_np_dyn. DATA: lv_table TYPE REF TO DATA, lv_line TYPE REF TO DATA, ls_lvc_cat TYPE lvc_s_fcat, lt_lvc_cat TYPE lvc_t_fcat. FIELD-SYMBOLS: <fs_table> TYPE TABLE, <fs_line> TYPE ANY. DEFINE append_catalog. ls_lvc_cat-fieldname = &1. " Имя поля ls_lvc_cat-ref_field = &2. " Ссылочное поле ls_lvc_cat-ref_table = &3. " Ссылочная таблица ls_lvc_cat-domname = &4. " Домен из ABAP словаря APPEND ls_lvc_cat TO lt_lvc_cat. END-OF-DEFINITION. append_catalog 'ABMNG' 'ABMNG' 'PLAF' ''. append_catalog 'ISHOD' 'ABMNG' 'PLAF' ''. append_catalog 'MEINS' 'MEINS' 'PLAF' ''. append_catalog 'PSTTR' 'PSTTR' 'PLAF' ''. append_catalog 'PEDTR' 'PEDTR' 'PLAF' ''. CALL METHOD cl_alv_table_create=>create_dynamic_table EXPORTING it_fieldcatalog = lt_lvc_cat IMPORTING ep_table = lv_table. ASSIGN lv_table->* TO <fs_table>. CREATE DATA lv_line LIKE LINE OF <fs_table>. ASSIGN lv_line->* TO <fs_line>. |
RTTS
RTTS появился начиная с версии ABAP 6.40. С помощью набора классов, который предоставляет RTTS, мы можем получать информацию о типах и создавать новые динамически во время выполнения. Пример реализации:
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 |
DATA: lo_struct TYPE REF TO cl_abap_structdescr, lo_element TYPE REF TO cl_abap_elemdescr, lo_new_type TYPE REF TO cl_abap_structdescr, lo_new_tab TYPE REF TO cl_abap_tabledescr, lo_data TYPE REF TO DATA, lt_comp TYPE cl_abap_structdescr=>component_table. FIELD-SYMBOLS: <fs_tab> TYPE ANY TABLE, <fs_line> TYPE ANY. * Получаем описание структуры из ABAP словаря lo_struct ?= cl_abap_typedescr=>describe_by_name( 'PLAF' ). lt_comp = lo_struct->get_components( ). * Создаем новый тип структуры по каталогу полей. lo_new_type = cl_abap_structdescr=>create( lt_comp ). * Создаем новую таблицу по структуре lo_new_tab = cl_abap_tabledescr=>create( p_line_type = lo_new_type p_table_kind = cl_abap_tabledescr=>tablekind_std p_unique = abap_false ). * Создаем ссылочные переменные присываеваем значения CREATE DATA lo_data TYPE HANDLE lo_new_type. ASSIGN lo_data->* TO <fs_line>. CREATE DATA lo_data TYPE HANDLE lo_new_tab. ASSIGN lo_data->* TO <fs_tab>. |
Спасибо!
Пожалуйста
простой способ, если структура известна и достаточна:
CREATE DATA lo_data TYPE TABLE OF (‘PLAF’)