Создание диапазона для поля из внутренней таблицы с использованием RTTS - PullRequest
1 голос
/ 24 мая 2019

Я хочу создать метод функции / пользовательского класса, который принимает 2 параметра:

1) IM_ITAB типа ЛЮБОЙ СТОЛ

2) IM_COMPONENT типа STRING

и возвращает1 параметр:

1) EX_RANGE тип PIQ_SELOPT_T

Итак, алгоритм выглядит так:

  • Прежде всего, мы проверяем, если столбец с именем компонента ввсе существует
  • Затем мы проверяем, что внутренняя таблица не пуста.
  • Затем мы перебираем внутреннюю таблицу, назначающую компонент и заполняем таблицу диапазонов.Код ниже.
METHODS compose_range_from_itab
    IMPORTING 
      IM_ITAB      type ANY TABLE
      IM_COMPONENT type STRING
    EXPORTING
      EX_RANGE     type PIQ_SELOPT_T.
...
METHOD compose_range_from_itab.

  DATA: lo_obj   TYPE REF TO cl_abap_tabledescr,
        wa_range TYPE selopt,
        lt_range TYPE piq_selopt_t.

  FIELD-SYMBOLS: <fs_line> TYPE ANY,
                 <fs_component> TYPE ANY.

  lo_obj ?= cl_abap_typedescr=>describe_by_data( p_data = im_itab ).

  READ TABLE lo_obj->key TRANSPORTING NO FIELDS WITH KEY name = im_component.

  IF sy-subrc IS INITIAL.

    IF LINES( im_itab ) GT 0.

      LOOP AT im_itab ASSIGNING <fs_line>.

        ASSIGN COMPONENT im_component OF STRUCTURE <fs_line> TO <fs_component>.

        wa_range-sign = 'I'.
        wa_range-option = 'EQ'.
        wa_range-low = <fs_component>.

        APPEND wa_range TO lt_range.

      ENDLOOP.

      SORT lt_range BY low.
      DELETE ADJACENT DUPLICATES FROM lt_range COMPARING low.

      ex_range[] = lt_range[].

    ENDIF.

  ENDIF.

ENDMETHOD.

Но я хочу улучшить метод дальше.Если импортированная внутренняя таблица имеет, скажем, 255 столбцов, то цикл обработки такой таблицы займет больше времени.Но мне нужен только один столбец для составления диапазона.

Поэтому я хочу получить компоненты внутренней таблицы, затем выбрать только один компонент, создать новый тип строки, содержащий только этот компонент, а затем создать внутреннюю таблицу с этой строкой.введите и скопируйте.

Вот псевдокод, соответствующий тому, чего я хочу достичь:

append corresponding fields of im_itab into new_line_type_internal_table.

Как я могу "вырезать" один компонент и создать новый тип линии, используя RTTS?

Ответы [ 3 ]

0 голосов
/ 27 мая 2019

Удивительно, но этот вариант оказался быстрее:

CLASS-METHODS make_range_variant_2
  IMPORTING
    sample        TYPE table_type
    column        TYPE string
  RETURNING
    VALUE(result) TYPE range_type.

METHOD make_range_variant_2.

  TYPES:
    BEGIN OF narrow_structure_type,
      content TYPE char32,
    END OF narrow_structure_type.

  TYPES narrow_table_type TYPE STANDARD TABLE OF narrow_structure_type WITH EMPTY KEY.

  DATA narrow_table TYPE narrow_table_type.

  DATA(mapping) =
    VALUE cl_abap_corresponding=>mapping_table_value(
      ( kind = cl_abap_corresponding=>mapping_component srcname = column dstname = 'CONTENT' ) ).

  DATA(mover) =
    cl_abap_corresponding=>create_with_value(
      source      = sample
      destination = narrow_table
      mapping     = mapping ).

  mover->execute(
    EXPORTING
      source      = sample
    CHANGING
      destination = narrow_table ).

  LOOP AT narrow_table ASSIGNING FIELD-SYMBOL(<row>).

    INSERT VALUE #(
        sign   = 'I'
        option = 'EQ'
        low    = <row>-content )
      INTO TABLE result.

  ENDLOOP.

ENDMETHOD.

CL_ABAP_CORRESPONDING делегирует функции ядра для перемещения между структурами, что, очевидно, быстрее, чем собственный ABAP ASSIGN COMPONENT [...] OF STRUCTURE [...] TO FIELD-SYMBOL [...]. Тогда реальный цикл кажется более быстрым, поскольку он использует назначения с фиксированными именами.

Может быть, кто-нибудь может проверить.

0 голосов
/ 27 мая 2019

Я бы не пошел за Macro.

Data:
      lr_data type ref to data.

FIELD-SYMBOLS:
      <lv_component> TYPE any,
      <ls_data> TYPE any.

CREATE DATA lr_data LIKE LINE OF im_itab.
ASSIGN lr_data->* TO <ls_data>.

"Check whether im_component exists
ASSIGN COMPONENT im_component OF STRUCTURE <ls_data> TO <lv_component>.

CHECK sy-subrc EQ 0.

LOOP AT im_itab INTO <ls_data>.
  APPEND VALUE #( sign = 'I' option = 'EQ' low = <lv_component> ) TO ex_range.
ENDLOOP.
0 голосов
/ 25 мая 2019

Вы все усложняете, для этого вам не нужен RTTS.

DEFINE make_range.
  ex_range = VALUE #( BASE ex_range ( sign = 'I' option = 'EQ' low = &1 ) ).
END-OF-DEFINITION.

LOOP AT im_itab ASSIGNING FIELD-SYMBOL(<fs_line>).
  ASSIGN COMPONENT im_component OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_field>).
  CHECK sy-subrc = 0 AND <fs_field> IS NOT INITIAL.
  make_range <fs_field>.
ENDLOOP.

И да, как сказала Сандра, вы не получите никакой производительности с RTTS, как раз наоборот.

...