Получить компоненты структуры DDIC с включенными - PullRequest
1 голос
/ 16 октября 2019

Я использую cl_abap_structdescr->get_components, чтобы получить список полей в структуре. Он отлично работает, когда я использую его на локально объявленных типах структур, но когда я использую его на структурах DDIC, он не дает ожидаемых результатов.

Воспроизводимый пример:

TYPES: BEGIN OF gty_outtab,
  infty TYPE infty,
  uname TYPE uname,
  bdate TYPE datum,
  btime TYPE uzeit,
  pernr TYPE pernr_d,
  opera TYPE hr_opera,
  begda TYPE begda,
  endda TYPE endda,
END OF gty_outtab.

DATA: lr_infty_structdescr  TYPE REF TO cl_abap_structdescr,
      lr_outtab_structdescr TYPE REF TO cl_abap_structdescr,
      lt_outtab_components  TYPE STANDARD TABLE OF abap_componentdescr,
      lt_infty_components   TYPE STANDARD TABLE OF abap_componentdescr.

" works as expected
lr_outtab_structdescr ?= cl_abap_structdescr=>describe_by_name( 'GTY_OUTTAB' ).
lt_outtab_components = lr_outtab_structdescr->get_components( ).

" doesn't work as expected
lr_infty_structdescr ?= cl_abap_structdescr=>describe_by_name( 'P0008' ).
lt_infty_components = lr_infty_structdescr->get_components( ).

BREAK-POINT.

Результаты:

Это нормально для GTY_OUTTAB:

enter image description here

Есть толькодва поля для P0008, хотя оно содержит гораздо больше полей (см. ниже):

enter image description here

Я уже пытался использовать cl_abap_typedescr вместо этого и гуглил, нокаждый код, который я нахожу в Интернете, выглядит так же, как мой?

Вот определение P0008, которое содержит много полей, которые вы можете видеть:

DDIC structure P0008 in SE11 Hierarchy display

Ответы [ 4 ]

3 голосов
/ 16 октября 2019

Конечно после публикации я нашел причину, по которой (немецкая нить) . Очевидно, что если данная структура содержит включенные структуры, то get_components не будет разбивать их. В этой ветке было предложено три решения, и все они отлично работают для меня. Поскольку мне нужны только имена полей структур, я буду использовать вариант 1.

DATA: lt_infty_complist1 TYPE abap_compdescr_tab,
      lt_infty_complist2 TYPE STANDARD TABLE OF fieldname,
      lt_infty_complist3 TYPE abap_component_tab.

" 1 - get full fieldname list, but with barely any typedescription
lt_infty_complist1 = lr_infty_structdescr->components.

" 2 - get full fieldname list of DDIC structures, but without typedescription
SELECT fieldname
  FROM dd03l
  INTO TABLE lt_infty_complist2
 WHERE tabname = 'P0008'.

DELETE lt_infty_complist2 WHERE table_line = '.INCLU--AP'
                             OR table_line = '.INCLUDE'.

" 3 - get full component list 
" function code from: https://www.abapforum.com/forum/viewtopic.php?f=18&p=59840)
PERFORM return_components USING lr_infty_structdescr CHANGING lt_infty_complist3.
1 голос
/ 20 октября 2019

В cl_abap_structdescr есть метод get_included_view (), который расширяет включенные структуры

1 голос
/ 18 октября 2019

В том же классе есть метод get list list, которого может быть достаточно.

data: lo_incl_stru TYPE REF TO cl_abap_structdescr,
       lt_field_list TYPE ddfields.

    lt_field_list =  lo_incl_stru->get_ddic_field_list( p_including_substructres = abap_true ).

Если этого недостаточно ... try

 METHODS recursive_get_components
      IMPORTING
        io_structdescr       TYPE REF TO cl_abap_structdescr
      RETURNING
        VALUE(rt_components) TYPE abap_component_tab.


METHOD recursive_get_components.
    DATA:
      lo_incl_stru TYPE REF TO cl_abap_structdescr,
      lt_incl_comp TYPE abap_component_tab,
      l_curr_index TYPE i.

    FIELD-SYMBOLS: <comp>      LIKE LINE OF rt_components,
                   <incl_comp> LIKE LINE OF lt_incl_comp.


    rt_components = io_structdescr->get_components( ).

    LOOP AT rt_components ASSIGNING <comp>.
      IF <comp>-as_include = 'X'.
        lo_incl_stru ?= <comp>-type.  " not the include struc type
        l_curr_index = sy-tabix.      " and the index it is to be included
        DELETE rt_components INDEX l_curr_index.

        lt_incl_comp = recursive_get_components( io_structdescr =  lo_incl_stru  ).
        LOOP AT lt_incl_comp ASSIGNING <incl_comp>.
          INSERT <incl_comp> INTO rt_components INDEX l_curr_index.
          l_curr_index = l_curr_index + 1.
        ENDLOOP.
      ENDIF.

    ENDLOOP.


  ENDMETHOD.
1 голос
/ 18 октября 2019

Метод GET_RTTS_FOR_LOCAL_TABLE класса-помощника CL_CACS_RTTS_HELPER, кажется, делает именно то, что вы хотите, и чего не хватает вашему варианту 1

CALL METHOD cl_cacs_rtts_helper=>get_rtts_for_local_structure
  EXPORTING
    id_tabname = 'P0008'
  receiving
    ro_data    = DATA(ro_struct)
.

Он выбирает все компоненты структуры в объект справочных данных, а также включает в себяабсолютные типы:

enter image description here

...