abapinternal-tables

ABAP 7.4 way of filling one itab from another?


Consider, I have GT_KUNNR internal table like below:

KUNNR TEXT
123 demo text
456 test inv

I have second GT_TEXT internal like below:

KUNNR TEXT EXPIRED
123 welcome X

I am writing the code till now in ABAP as:

LOOP AT GT_KUNNR ASSIGNING FIELD-SYMBOL(<lfs_kunnr>).
  READ TABLE GT_TEXT ASSIGNING FIELD-SYMBOL(lfs_text>) WITH KEY kunnr = <lfs_kunnr>-kunnr BINARY SEARCH.
  IF sy-subrc EQ 0.
    <lfs_kunnr>-text = <lfs_text>-text.
  ENDIF.
ENDLOOP.

My question is, how to achieve above using ABAP 7.4 and upwards? My understanding is, constructor expression (VALUE,FOR,REDUCE..) creates a new type, which I don't need (basically, GT_KUNNR is being updated and can have huge records. So, creating new structure/type and then passing that again to GT_KUNNR will be a performance bottleneck). So, how to achieve that? Any efficient way?


Solution

  • If you want to do this with a constructor operator, then you can use the CORRESPONDING-operator with a lookup table.

    But note that this requires that the linking condition between the two tables (kunnr = kunnr) uses a table key in the lookup table. That means that the lookup table (in this case gt_text) has to be a SORTED TABLE or a HASHED TABLE with kunnr as the keyfield, or that it at least has a SECONDARY KEY that matches the condition.

    " Declarations:
    TYPES:
      BEGIN OF kunnr_struct,
        kunnr TYPE kunnr,
        text TYPE string,
      END OF kunnr_struct,
      kunnr_tbl TYPE STANDARD TABLE OF kunnr_struct WITH DEFAULT KEY,
      BEGIN OF text_struct,
        kunnr TYPE kunnr,
        text TYPE string,
        expired TYPE abap_bool,
      END OF text_struct,
      text_tbl TYPE HASHED TABLE OF text_struct WITH UNIQUE KEY kunnr. " <- Important!
    
    " Test data:
    DATA(gt_kunnr) = VALUE kunnr_tbl(
       ( kunnr = '123' text = 'demo text'  )
       ( kunnr = '456' text = 'text inv')
    ).
    
    DATA(gt_text) = VALUE text_tbl(
       ( kunnr = '123' text = 'welcome' expired = abap_true )
    ).
    
    " The actual code you asked for:
    
    gt_kunnr = CORRESPONDING kunnr_tbl(
        gt_kunnr FROM gt_text USING kunnr = kunnr ).
    

    My understanding is, constructor expression (VALUE,FOR,REDUCE..) creates a new type, which I don't need (basically, GT_KUNNR is being updated and can have huge records.

    This does not create a new type, but according to the documentation I linked above, it does indeed create an interim table with the results in memory. This is unlikely to be a performance problem (the runtime increase would probably be linear at worst), but it could double the memory being used, so it could become a memory problem with very large datasets.

    If that is a concern for your use-case, then you can keep using your variant with a loop. If you don't want to use field-symbols, then you can do what many modern ABAP styleguides, like this one from SAP themselves, recommend to use references instead of field-symbols whenever possible. The code from the question using references would look like this:

    LOOP AT gt_kunnr REFERENCE INTO DATA(lrs_kunnr).
      READ TABLE gt_text REFERENCE INTO DATA(lrs_text) WITH KEY kunnr = lrs_kunnr->kunnr BINARY SEARCH.
      IF sy-subrc EQ 0.
        lrs_kunnr->text = lrs_text->text.
      ENDIF.
    ENDLOOP.