‎2020 Mar 04 10:37 PM
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' ) ....
‎2020 Mar 05 1:35 AM
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( ).
‎2020 Mar 05 1:35 AM
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( ).
‎2020 Mar 05 2:55 PM
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
)
)
)
).
‎2020 Mar 05 3:09 PM
Very nice code, next step, you could transform it quickly in Abap Unit
‎2020 Mar 05 4:48 PM
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