Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

FOR table iteration

Former Member
1,259

I'd like to use FOR Operand for a table iteration and have hit a road block. Here's my requirement:

Data Structures -

ITAB1 has two fields FIELD1 and FIELD2 with 10 records.

ITAB2 has two fields FIELD1 and FIELD 3 with 6 records.

ITAB3 has 4 fields FIELD1, 2 and 3.

Requirement:

LOOP AT itab1 into ls_itab1 WHERE field2 = 'X'.

READ TABLE itab2 INTO ls_itab2 WITH KEY field1 = ls_itab1-field1

IF sy-subrc = 0.

populate table ITAB3 mapping FIELD1, 2 and 3 from LS_ITAB1 and LS_ITAB2.

ELSE.

message i000 with LS_ITAB1-FIELD1.

ENDIF.

ENDLOOP.

Need help completing the following code:

DATA(ITAB3) = VALUE TY_TAB3( FOR ls_itab1 IN itab1 WHERE ( field2 = 'X' ) ....

1 ACCEPTED SOLUTION
Read only

michael_piesche
Active Contributor
1,044
  • Can you give examples with table values for ITAB1, 2 and 3? Is FIELD1 unique in ITAB1 and 2?
  • What do you mean by 'populate table ITAB3 mapping FIELD1, 2 and 3 from LS_ITAB1 and LS_ITAB2.'
  • Is it just a join for rows with the same FIELD1 value?
  • So instead of a LOOP AT with a nested READ TABLE, you want to create itab3 through a table comprehension with a table iteration?

I simply reused the Demo Report 'DEMO_TABLE_COMPRH_JOIN' and added your Where Condition FIELD2 = 'X'. That does the trick for you as well. The demo gives two alternatives of doing this, but be aware, that option 1 (resulting in ITAB3) leads to a dump in case of missing rows in ITAB2, whereas option 2 (resulting in ITAB4) does not have this issue, but it will not show those records from ITAB1 which are missing in ITAB2, and also, in case of non-unique keys, those will be multiplied. If you want to have a combination of those two, you will have to implement conditions in the FOR parameter.

CLASS demo DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS main.
ENDCLASS.

CLASS demo IMPLEMENTATION.
  METHOD main.
    TYPES:
      BEGIN OF line1,
        field1 TYPE i,
        field2 TYPE c LENGTH 1,
      END OF line1,
      itab1 TYPE STANDARD TABLE OF line1 WITH EMPTY KEY,
      BEGIN OF line2,
        field1 TYPE i,
        field3 TYPE i,
      END OF line2,
      itab2 TYPE STANDARD TABLE OF line2 WITH EMPTY KEY,
      BEGIN OF line3,
        field1 TYPE i,
        field2 TYPE c LENGTH 1,
        field3 TYPE i,
      END OF line3,
      itab3 TYPE STANDARD TABLE OF line3 WITH EMPTY KEY.

    DATA(out) = cl_demo_output=>new( ).

    DATA(itab1) = VALUE itab1(
      ( field1 = 1  field2 = ' ' )
      ( field1 = 3  field2 = 'X' )
      ( field1 = 5  field2 = ' ' )
      ( field1 = 11 field2 = ' ' )
      ( field1 = 12 field2 = 'X' )
      ( field1 = 16 field2 = 'X' )
      ( field1 = 17 field2 = ' ' )
      ( field1 = 18 field2 = 'X' )
      ( field1 = 21 field2 = ' ' )
      ( field1 = 31 field2 = 'X' ) ).
    out->write( itab1 ).

    DATA(itab2) = VALUE itab2(
      ( field1 = 1  field3 = 1  )
      ( field1 = 3  field3 = 4  )
      ( field1 = 12 field3 = 44 )
      ( field1 = 16 field3 = 14 )
      ( field1 = 18 field3 = 24 )
      ( field1 = 31 field3 = 34 ) ).
    out->write( itab2 ).

    DATA(itab3) = VALUE itab3(
      FOR wa IN itab1 where ( field2 = 'X' )
        ( field1  = wa-field1
          field2  = wa-field2
          field3  = itab2[ field1 = wa-field1 ]-field3 ) ).
    out->write( itab3 ).

    DATA(itab4) = VALUE itab3(
      FOR wa1 IN itab1 INDEX INTO idx where ( field2 = 'X' )
      FOR wa2 IN itab2 WHERE ( field1 = wa1-field1 )
        ( field1 = wa1-field1
          field2 = wa1-field2
          field3 = wa2-field3 ) ).
    out->write( itab4 ).

    out->display( ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  demo=>main( ).
4 REPLIES 4
Read only

michael_piesche
Active Contributor
1,045
  • Can you give examples with table values for ITAB1, 2 and 3? Is FIELD1 unique in ITAB1 and 2?
  • What do you mean by 'populate table ITAB3 mapping FIELD1, 2 and 3 from LS_ITAB1 and LS_ITAB2.'
  • Is it just a join for rows with the same FIELD1 value?
  • So instead of a LOOP AT with a nested READ TABLE, you want to create itab3 through a table comprehension with a table iteration?

I simply reused the Demo Report 'DEMO_TABLE_COMPRH_JOIN' and added your Where Condition FIELD2 = 'X'. That does the trick for you as well. The demo gives two alternatives of doing this, but be aware, that option 1 (resulting in ITAB3) leads to a dump in case of missing rows in ITAB2, whereas option 2 (resulting in ITAB4) does not have this issue, but it will not show those records from ITAB1 which are missing in ITAB2, and also, in case of non-unique keys, those will be multiplied. If you want to have a combination of those two, you will have to implement conditions in the FOR parameter.

CLASS demo DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS main.
ENDCLASS.

CLASS demo IMPLEMENTATION.
  METHOD main.
    TYPES:
      BEGIN OF line1,
        field1 TYPE i,
        field2 TYPE c LENGTH 1,
      END OF line1,
      itab1 TYPE STANDARD TABLE OF line1 WITH EMPTY KEY,
      BEGIN OF line2,
        field1 TYPE i,
        field3 TYPE i,
      END OF line2,
      itab2 TYPE STANDARD TABLE OF line2 WITH EMPTY KEY,
      BEGIN OF line3,
        field1 TYPE i,
        field2 TYPE c LENGTH 1,
        field3 TYPE i,
      END OF line3,
      itab3 TYPE STANDARD TABLE OF line3 WITH EMPTY KEY.

    DATA(out) = cl_demo_output=>new( ).

    DATA(itab1) = VALUE itab1(
      ( field1 = 1  field2 = ' ' )
      ( field1 = 3  field2 = 'X' )
      ( field1 = 5  field2 = ' ' )
      ( field1 = 11 field2 = ' ' )
      ( field1 = 12 field2 = 'X' )
      ( field1 = 16 field2 = 'X' )
      ( field1 = 17 field2 = ' ' )
      ( field1 = 18 field2 = 'X' )
      ( field1 = 21 field2 = ' ' )
      ( field1 = 31 field2 = 'X' ) ).
    out->write( itab1 ).

    DATA(itab2) = VALUE itab2(
      ( field1 = 1  field3 = 1  )
      ( field1 = 3  field3 = 4  )
      ( field1 = 12 field3 = 44 )
      ( field1 = 16 field3 = 14 )
      ( field1 = 18 field3 = 24 )
      ( field1 = 31 field3 = 34 ) ).
    out->write( itab2 ).

    DATA(itab3) = VALUE itab3(
      FOR wa IN itab1 where ( field2 = 'X' )
        ( field1  = wa-field1
          field2  = wa-field2
          field3  = itab2[ field1 = wa-field1 ]-field3 ) ).
    out->write( itab3 ).

    DATA(itab4) = VALUE itab3(
      FOR wa1 IN itab1 INDEX INTO idx where ( field2 = 'X' )
      FOR wa2 IN itab2 WHERE ( field1 = wa1-field1 )
        ( field1 = wa1-field1
          field2 = wa1-field2
          field3 = wa2-field3 ) ).
    out->write( itab4 ).

    out->display( ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  demo=>main( ).
Read only

0 Likes
1,044

Thanks for your help. The second option is what I'm looking for, the only caveat is that I need to raise an exception when a matching entry doesn't exist in itab2. Any ideas how? I have the following logic and it doesn't throw a message.

 DATA(itab3) = VALUE itab3( FOR wa1 IN itab1 WHERE ( field2 = 'X' )
 			      ( field1 = wa1-field1
 				field2 = wa1-field2
 				field3 = REDUCE #( INIT dref2 TYPE field3 " Field3 is Data Element
 						FOR WA2 IN itab2
 						WHERE ( field1 = wa1-field1 )
 						NEXT dref2 = COND #(
 								WHEN wa2 IS INITIAL
 								THEN THROW cx_demo_dyn_t100( MESSAGE i001(zzmsg_class) WITH wa1-field1 )
 								ELSE wa2-field3 
 								)
 						  )
 				)
 			   ).
Read only

0 Likes
1,044

Very nice code, next step, you could transform it quickly in Abap Unit

Read only

1,044
Raj Ananthakrishnan, you say you prefer second option (itab4), but you show coding for first option (itab3). That version actually already throws an error if the line does not exist when trying to access the field of the line.Throws error "ITAB_LINE_NOT_FOUND" "CX_SY_ITAB_LINE_NOT_FOUND":
DATA(itab3) = VALUE itab3(
              FOR wa IN itab1 where ( field2 = 'X' )
              ( field1  = wa-field1
                field2  = wa-field2
                field3  = itab2[ field1 = wa-field1 ]-field3 ) ). " throws error 
Doesnt throw error:
DATA(itab3) = VALUE itab3(
              FOR wa IN itab1 where ( field2 = 'X' )
              ( field1  = wa-field1
                field2  = wa-field2
                field3  = VALUE #( itab2[ field1 = wa-field1 ]-field3 OPTIONAL ) ) ). " doesnt throw error