简体   繁体   English

使用RTTS从内部表为字段创建范围

[英]Creating a range for a field from internal table using RTTS

I want to create a function/custom class method that takes in 2 parameters: 我想创建一个接受2个参数的函数/自定义类方法:

1) IM_ITAB type ANY TABLE 1)IM_ITAB类型ANY TABLE

2) IM_COMPONENT type STRING 2)IM_COMPONENT类型STRING

and returns 1 parameter: 并返回1个参数:

1) EX_RANGE type PIQ_SELOPT_T 1)EX_RANGE类型PIQ_SELOPT_T

So, algorithm is like this: 所以,算法是这样的:

  • First of all, we check if the column with a component name at all exists 首先,我们检查一下组件名称是否全部存在的列
  • Then, we check that internal table is not empty. 然后,我们检查内部表是否为空。
  • Then, we loop through internal table assigning component and filling range table. 然后,我们遍历内部表分配组件和填充范围表。 Code is below. 代码如下。
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.

But I want to improve the method further. 但我想进一步改进该方法。 If the imported internal table has, let's say, 255 columns, then it will take longer to loop through such table. 如果导入的内部表有255列,则遍历该表将花费更长的时间。 But I need only one column to compose the range. 但是我只需要一列即可组成范围。

So I want to get components of internal table, then choose only one component, create a new line type containing only that component, then create internal table with that line type and copy. 因此,我想获取内部表的组件,然后仅选择一个组件,创建仅包含该组件的新线型,然后使用该线型创建内部表并进行复制。

Here is the pseudo code corresponding to what I want to achieve: 这是与我想要实现的相对应的伪代码:

append corresponding fields of im_itab into new_line_type_internal_table.

How can I "cut out" one component and create a new line type using RTTS? 如何使用RTTS“裁剪”一个组件并创建新的线型?

You are overcomplicating everything, you don't need RTTS for that. 您使所有事情变得过于复杂,不需要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.

And yes, as Sandra said, you won't gain any performance with RTTS, just the opposite. 是的,正如Sandra所说,使用RTTS不会获得任何性能,相反。

Surprisingly, this variant turned out to be faster: 令人惊讶的是,这种变体更快:

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 delegates to a kernel function for the structure-to-structure move, which apparently is faster than the ABAP-native ASSIGN COMPONENT [...] OF STRUCTURE [...] TO FIELD-SYMBOL [...] . CL_ABAP_CORRESPONDING委托一个内核函数来进行结构到结构的移动,这显然快于ABAP原生的将结构ASSIGN COMPONENT [...] OF STRUCTURE [...] TO FIELD-SYMBOL [...] CL_ABAP_CORRESPONDING ASSIGN COMPONENT [...] OF STRUCTURE [...] TO FIELD-SYMBOL [...] The actual loop then seems to be faster because it uses fixed-name assignments. 这样,实际循环似乎会更快,因为它使用了固定名称分配。

Maybe somebody could verify. 也许有人可以验证。

I would not go for a Macro . 我不会去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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM