CORRESPONDING
结构赋值语句,CORRESPONDING语句允许控制组件映射关系
*---------------------------------------------------------------------*
* 在ABAP 7.40之前,主要通过 MOVE-CORRESPONDING 来传递结构化数据,
* 但需要保持结构内部组件名称一致,否则数据将不会被传递,
* 而使用 CORRESPONDING 后,该语句在保持同名组件自动进行数据传递的基础上,
* MAPPING 可以允许我们将不同名称的组件映射到一起,
* EXCEPT 可以规避掉我们不需要传值的一些字段
*---------------------------------------------------------------------*
TYPES: BEGIN OF TY_DATA,
MATNR TYPE MARA-MATNR,
MTART TYPE MARA-MTART,
MATKL TYPE MARA-MATKL,
TEXT1 TYPE CHAR50,
END OF TY_DATA.
TYPES: BEGIN OF LTY_TABLE,
MATNR_C TYPE MARA-MATNR,
MTART TYPE MARA-MTART,
MATKL TYPE MARA-MATKL,
TEXT1 TYPE CHAR50,
END OF LTY_TABLE.
DATA LT_DATA TYPE TABLE OF TY_DATA.
DATA LT_TABLE TYPE TABLE OF LTY_TABLE.
LT_DATA = VALUE #( ( MATNR = 'Material-001'
MTART = 'WATR'
MATKL = '1020'
TEXT1 = 'First Material' )
( MATNR = 'Material-002'
MTART = 'WATR'
MATKL = '1030'
TEXT1 = 'Second Material' ) ).
LT_TABLE = CORRESPONDING #( LT_DATA
MAPPING MATNR_C = MATNR
EXCEPT MATKL ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_DATA ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_TABLE ).
*---------------------------------------------------------------------*
* 在 MAPPING 语句中,需要注意两边的字段类型,以免类型不兼容而导致程序 dump
* 使用DEEP处理深层结构数据,相当于MOVE CORRESPONDING [ EXPANDING NESTED TABLES ]
*---------------------------------------------------------------------*
TYPES: BEGIN OF LTY_PROD_MAT,
MATNR TYPE MATNR,
MTART TYPE MTART,
MATKL TYPE MATKL,
BISMT TYPE BISMT,
END OF LTY_PROD_MAT.
DATA: BEGIN OF LS_PROD_MATS,
SECTION TYPE CHAR10,
T_MATERIALS TYPE TABLE OF LTY_PROD_MAT,
END OF LS_PROD_MATS.
TYPES: BEGIN OF LTY_SALES_MAT,
MATNR TYPE MATNR,
BISMT TYPE BISMT,
MTART TYPE MTART,
MATKL TYPE MATKL,
END OF LTY_SALES_MAT.
DATA: BEGIN OF LS_SALES_MATS,
SECTION TYPE CHAR10,
T_MATERIALS TYPE TABLE OF LTY_SALES_MAT,
END OF LS_SALES_MATS.
SELECT MATNR MTART MATKL BISMT FROM MARA
INTO CORRESPONDING FIELDS OF TABLE LS_SALES_MATS-T_MATERIALS
UP TO 3 ROWS.
LS_PROD_MATS = CORRESPONDING #( DEEP LS_SALES_MATS ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LS_SALES_MATS-T_MATERIALS ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LS_PROD_MATS-T_MATERIALS ).
*---------------------------------------------------------------------*
* 使用BASE保留初始数据,为内表赋值时相当于
* MOVE CORRESPONDING [ KEEPING TARGET LINES ],
* 为结构赋值时类似于VALUE [ BASE ]
*---------------------------------------------------------------------*
TYPES: BEGIN OF TY_DATA,
MATNR TYPE MARA-MATNR,
MTART TYPE MARA-MTART,
MATKL TYPE MARA-MATKL,
TEXT1 TYPE CHAR50,
END OF TY_DATA.
DATA LT_DATA TYPE TABLE OF TY_DATA.
DATA LT_TABLE TYPE TABLE OF TY_DATA.
LT_DATA = VALUE #( ( MATNR = 'Material-001'
MTART = 'WATR'
MATKL = '1020'
TEXT1 = 'First Material' )
( MATNR = 'Material-002'
MTART = 'WATR'
MATKL = '1030'
TEXT1 = 'Second Material' ) ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_DATA ).
LT_TABLE = VALUE #( ( MATNR = 'Material-001'
MTART = 'FOOD' )
( MATNR = 'Material-002'
MTART = 'WATR') ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_TABLE ).
LT_TABLE = CORRESPONDING #( BASE ( LT_TABLE ) LT_DATA EXCEPT MATKL ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_TABLE ).
*---------------------------------------------------------------------*
* CORRESPONDING中可以从两个内表中引入数据,FORM子句后的内表结构需要定义为排序表或哈希表
* 该语法不能与DEEP/BASE关键字同时使用,但是可以使用MAPPING/EXCEPT
* 如下例所示,以表1为基表,根据USING定义的关联条件去表2查找数据,如果查找到,
* 则将表2的该条数据复写到表1对应的记录上并返回,否则直接返回表1的数据
* MAPPING/EXCEPT作用于表2数据复写到表1对应记录的过程中,特定条件下可以用来实现读取数据
* 并更新内表的操作,但是需要定义非标准表,有一定的局限性
*---------------------------------------------------------------------*
TYPES:BEGIN OF LTY_DATA,
INDEX TYPE CHAR4,
TEXT1 TYPE CHAR10,
TEXT2 TYPE CHAR10,
END OF LTY_DATA.
DATA: LT_TMP1 TYPE SORTED TABLE OF LTY_DATA WITH UNIQUE KEY INDEX,
LT_TMP2 TYPE SORTED TABLE OF LTY_DATA WITH UNIQUE KEY INDEX,
LT_DATA TYPE TABLE OF LTY_DATA.
LT_TMP1 = VALUE #( ( INDEX = '0001' TEXT1 = 'X' )
( INDEX = '0004' TEXT1 = 'X' )
( INDEX = '0009' TEXT1 = 'X' )
( INDEX = '0021' TEXT1 = 'X' ) ).
LT_TMP2 = VALUE #( ( INDEX = '0001' TEXT2 = 'Y' )
( INDEX = '0002' TEXT2 = 'Y' )
( INDEX = '0003' TEXT2 = 'Y' )
( INDEX = '0004' TEXT2 = 'Y' ) ).
LT_DATA = CORRESPONDING #( LT_TMP1 FROM LT_TMP2 USING INDEX = INDEX )."from后表的数据传递给前表,按照using后条件操作”
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_DATA ).
LT_DATA = CORRESPONDING #( LT_TMP1 FROM LT_TMP2 USING INDEX = INDEX EXCEPT TEXT1 )."可以使用mapping和except”
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_DATA ).
MOVE-CORRESPONDING(DEEP)
在 ABAP 7.40 后,MOVE-CORRESPONDING语句针对深层结构赋值进行了扩展,并且允许保留结构在被赋值前的数据
*---------------------------------------------------------------------*
* 在深层结构中使用 MOVE-CORRESPONDING传递数据时,需要保持嵌套的深层次结构一致,
* 包括字段名以及顺序等,否则数据会错位
*---------------------------------------------------------------------*
TYPES: BEGIN OF LTY_PROD_MAT,
MATNR TYPE MATNR,
MTART TYPE MTART,
MATKL TYPE MATKL,
BISMT TYPE BISMT,
END OF LTY_PROD_MAT.
DATA: BEGIN OF LS_PROD_MATS,
SECTION TYPE CHAR10,
T_MATERIALS TYPE TABLE OF LTY_PROD_MAT,
END OF LS_PROD_MATS.
DATA: BEGIN OF LS_SALES_MATS,
SECTION TYPE CHAR10,
T_MATERIALS TYPE TABLE OF LTY_PROD_MAT,
END OF LS_SALES_MATS.
SELECT MATNR MTART MATKL BISMT FROM MARA
INTO CORRESPONDING FIELDS OF TABLE LS_SALES_MATS-T_MATERIALS
UP TO 3 ROWS.
MOVE-CORRESPONDING LS_SALES_MATS TO LS_PROD_MATS.
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LS_SALES_MATS-T_MATERIALS ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LS_PROD_MATS-T_MATERIALS ).
*---------------------------------------------------------------------*
* 使用 EXPANDING NESTED TABLES 避免因结构不一致而导致的数据异常,
* 对于深层结构,只有相同名称的字段被复制,且不需要它们顺序相同,
* 但是该语句只考虑第一级的深层次结构,不适用于更深层次的数据
*---------------------------------------------------------------------*
TYPES: BEGIN OF LTY_PROD_MAT,
MATNR TYPE MATNR,
MTART TYPE MTART,
MATKL TYPE MATKL,
BISMT TYPE BISMT,
END OF LTY_PROD_MAT.
DATA: BEGIN OF LS_PROD_MATS,
SECTION TYPE CHAR10,
T_MATERIALS TYPE TABLE OF LTY_PROD_MAT,
END OF LS_PROD_MATS.
DATA: BEGIN OF LS_SALES_MATS,
T_MATERIALS TYPE TABLE OF LTY_PROD_MAT,
SECTION TYPE CHAR10,
END OF LS_SALES_MATS.
SELECT MATNR MTART MATKL BISMT FROM MARA
INTO CORRESPONDING FIELDS OF TABLE LS_SALES_MATS-T_MATERIALS
UP TO 3 ROWS.
MOVE-CORRESPONDING LS_SALES_MATS TO LS_PROD_MATS.
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LS_PROD_MATS-T_MATERIALS ).
MOVE-CORRESPONDING LS_SALES_MATS TO LS_PROD_MATS EXPANDING NESTED TABLES.
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LS_PROD_MATS-T_MATERIALS ).
*---------------------------------------------------------------------*
* 在使用 MOVE-CORRESPONDING 时,默认都会先清空目标结构的数据,
* 再将数据填充到结构里面,当我们需要保留目标结构原有的数据时,
* 可以使用 KEEPING TARGET LINES 语句,该语句适用于表结构赋值,
* 且不会修改原有的记录,仅添加需要填充的数据
*---------------------------------------------------------------------*
TYPES: BEGIN OF LTY_PROD_MAT,
MATNR TYPE MATNR,
MTART TYPE MTART,
MATKL TYPE MATKL,
BISMT TYPE BISMT,
END OF LTY_PROD_MAT.
DATA: BEGIN OF LS_PROD_MATS,
SECTION TYPE CHAR10,
T_MATERIALS TYPE TABLE OF LTY_PROD_MAT,
END OF LS_PROD_MATS.
DATA: BEGIN OF LS_SALES_MATS,
SECTION TYPE CHAR10,
T_MATERIALS TYPE TABLE OF LTY_PROD_MAT,
END OF LS_SALES_MATS.
SELECT MATNR MTART MATKL BISMT
FROM MARA
INTO CORRESPONDING FIELDS OF TABLE LS_SALES_MATS-T_MATERIALS
UP TO 4 ROWS.
SELECT MATNR MTART MATKL BISMT
FROM MARA
INTO CORRESPONDING FIELDS OF TABLE LS_PROD_MATS-T_MATERIALS
UP TO 1 ROWS.
MOVE-CORRESPONDING LS_SALES_MATS-T_MATERIALS TO LS_PROD_MATS-T_MATERIALS KEEPING TARGET LINES.
REDUCE
REDUCE赋值语句一般用于需要循环处理的数据。
注意:和value赋值语句中的for类似,但是更加复杂,使用前注意理清楚逻辑,不建议使用。
*---------------------------------------------------------------------*
* 一般情况下,我们可以使用 REDUCE 来统计内表中特定条件的记录条数,
* 或是汇总/拼接内表的部分字段
*---------------------------------------------------------------------*
TYPES: BEGIN OF TY_DATA,
MATNR TYPE MARA-MATNR,
MTART TYPE MARA-MTART,
MATKL TYPE MARA-MATKL,
INT TYPE INT8,
END OF TY_DATA.
DATA LT_DATA TYPE TABLE OF TY_DATA.
LT_DATA = VALUE #( ( MATNR = 'Material-001'
MTART = 'WATR'
MATKL = '1020'
INT = 10086 )
( MATNR = 'Material-002'
MTART = 'WATR'
MATKL = '1030'
INT = 666 ) ).
DATA(LV_LINES) = REDUCE #( INIT LV_RESULT = 0
FOR LS_DATA IN LT_DATA WHERE ( MATKL = '1020' )
NEXT LV_RESULT = LV_RESULT + 1 ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LV_LINES ).
*---------------------------------------------------------------------*
* REDUCE语句中可以使用UNTIL关键字,在使用时需要注意 NEXT 语句至少会被执行一次,
* 作用类似于DO循环,限制条件可以自行定义
*---------------------------------------------------------------------*
TYPES: BEGIN OF TY_DATA,
MATNR TYPE MARA-MATNR,
MTART TYPE MARA-MTART,
MATKL TYPE MARA-MATKL,
INT TYPE INT8,
END OF TY_DATA.
DATA LT_DATA TYPE TABLE OF TY_DATA.
LT_DATA = VALUE #( ( MATNR = 'Material-001'
MTART = 'WATR'
MATKL = '1020'
INT = 10086 )
( MATNR = 'Material-002'
MTART = 'WATR'
MATKL = '1030'
INT = 666 ) ).
DATA(LV_COUNT) = REDUCE #( INIT LV_COMPT = 0
FOR I = 1 UNTIL I > LINES( LT_DATA )
NEXT LV_COMPT = LV_COMPT + VALUE #( LT_DATA[ I ]-INT OPTIONAL ) ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LV_COUNT ).
*---------------------------------------------------------------------*
* REDUCE语句返回值为结构时,常用来汇总字段或作其他处理(例如取最大值/最小值/平均值等)
*---------------------------------------------------------------------*
TYPES:BEGIN OF LTY_RESULT,
SUM TYPE S_DISTANCE,
COUNT TYPE I,
MAX TYPE S_DISTANCE,
MIN TYPE S_DISTANCE,
END OF LTY_RESULT.
TYPES: LTY_TABLE TYPE TABLE OF LTY_RESULT WITH DEFAULT KEY.
SELECT DISTANCE FROM SPFLI INTO TABLE @DATA(LT_TABLE) UP TO 5 ROWS WHERE DISTANCE > 0.
DATA(LWA_RESULT) = REDUCE #( INIT LWA_TMP = VALUE LTY_RESULT( )
FOR LWA_TABLE IN LT_TABLE
INDEX INTO LV_INDEX
NEXT LWA_TMP = VALUE #( BASE LWA_TMP
SUM = LWA_TMP-SUM + LWA_TABLE-DISTANCE
COUNT = LWA_TMP-COUNT + 1
MAX = NMAX( VAL1 = LWA_TMP-MAX VAL2 = LWA_TABLE-DISTANCE )
MIN = COND #( WHEN LV_INDEX = 1 THEN LWA_TABLE-DISTANCE
ELSE NMIN( VAL1 = LWA_TMP-MIN VAL2 = LWA_TABLE-DISTANCE ) ) ) ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LWA_RESULT ).
*---------------------------------------------------------------------*
* REDUCE语句返回值为内表时,常用来汇总内表记录,可适用于深层嵌套的内表
*---------------------------------------------------------------------*
TYPES:BEGIN OF LTY_FIELD,
ROW TYPE I,
COL TYPE I,
END OF LTY_FIELD.
TYPES:LTY_FIELD_TAB TYPE TABLE OF LTY_FIELD WITH DEFAULT KEY.
TYPES:BEGIN OF LTY_DATA,
CHECK TYPE CHAR1,
FIELD TYPE LTY_FIELD_TAB,
END OF LTY_DATA.
DATA: LT_DATA TYPE TABLE OF LTY_DATA.
LT_DATA[] = VALUE #( ( CHECK = ABAP_TRUE
FIELD = VALUE #( ( ROW = 1 COL = 1 )
( ROW = 1 COL = 3 )
( ROW = 1 COL = 5 ) ) )
( CHECK = ABAP_FALSE
FIELD = VALUE #( ( ROW = 2 COL = 1 )
( ROW = 2 COL = 2 )
( ROW = 2 COL = 3 ) ) )
( CHECK = ABAP_TRUE
FIELD = VALUE #( ( ROW = 3 COL = 2 )
( ROW = 3 COL = 4 )
( ROW = 3 COL = 6 ) ) ) ).
DATA(LT_FIELDS) = REDUCE #( INIT LT_TEMP = VALUE LTY_FIELD_TAB( )
FOR LS_DATA IN LT_DATA
WHERE ( CHECK = ABAP_TRUE )
NEXT LT_TEMP = VALUE #( BASE LT_TEMP
FOR LS_FIELD IN LS_DATA-FIELD
( LS_FIELD ) ) ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_FIELDS ).