GROUP BY(FOR LOOP)
在 LOOP 语句中使用 GROUP BY 实现分组处理数据
*---------------------------------------------------------------------*
* 在 LOOP 中使用 GROUP BY 后,LWA_DATA 中不会存储相应的数据,同样,如果使用 FIELD-SYMBOL,
* 也不会被分配,如果需要修改内表数据,只能通过每个组进行修改,对内表数据进行分组时,
* 可通过 ASCENDING / DESCENDING 按组排序,否则按前后的顺序依次输出;
* GROUP BY 在需要使用多个字段进行分组时:GROUP BY ( KEY1 = field1 KEY2 = field2 … )
*---------------------------------------------------------------------*
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 = 'FOOD'
MATKL = '1020'
TEXT1 = 'FIRST' )
( MATNR = 'Material-002'
MTART = 'WATR'
MATKL = '1030'
TEXT1 = 'SECOND' )
( MATNR = 'Material-003'
MTART = 'WATR'
MATKL = '1020'
TEXT1 = 'THIRD' ) ).
LOOP AT LT_DATA INTO DATA(LWA_DATA) GROUP BY LWA_DATA-MATKL INTO DATA(G1).
LT_TABLE = VALUE #( FOR LWA_TABLE IN GROUP G1 ( LWA_TABLE ) ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_TABLE ).
ENDLOOP.
*---------------------------------------------------------------------*
* 如果需要根据自定义条件进行分组,可以使用 COND 语句将特定条件转换成字符或数字再进行分组
*---------------------------------------------------------------------*
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 = 'FOOD'
MATKL = '1020'
TEXT1 = 'FIRST' )
( MATNR = 'Material-002'
MTART = 'WATR'
MATKL = '1030'
TEXT1 = 'SECOND' )
( MATNR = 'Material-003'
MTART = 'WATR'
MATKL = '1010'
TEXT1 = 'THIRD' ) ).
LOOP AT LT_DATA INTO DATA(LWA_DATA)
GROUP BY COND STRING( WHEN LWA_DATA-MATKL = '1020' THEN 'A'
ELSE 'B' ) DESCENDING INTO DATA(G1).
LT_TABLE = VALUE #( FOR LWA_TABLE IN GROUP G1 ( LWA_TABLE ) ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_TABLE ).
ENDLOOP.
*---------------------------------------------------------------------*
* 修改内表数据示例如下,第一层 LOOP 遍历的是每个组,
* 第二层遍历的是对应组里的数据,我们需要在第二层做变更
*---------------------------------------------------------------------*
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.
LT_DATA = VALUE #( ( MATNR = 'Material-001'
MATKL = '1020'
TEXT1 = 100 )
( MATNR = 'Material-002'
MATKL = '1030'
TEXT1 = 200 )
( MATNR = 'Material-003'
MATKL = '1020'
TEXT1 = 300 ) ).
LOOP AT LT_DATA INTO DATA(LWA_DATA) GROUP BY LWA_DATA-MATKL ASCENDING INTO DATA(G1).
DATA(LV_COUNT) = REDUCE #( INIT LV_INDEX = 0
FOR LWA_GROUP IN GROUP G1
NEXT LV_INDEX = LV_INDEX + LWA_GROUP-TEXT1 ).
LOOP AT GROUP G1 ASSIGNING FIELD-SYMBOL(<FS_LINE>).
<FS_LINE>-TEXT1 = LV_COUNT.
ENDLOOP.
ENDLOOP.
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_DATA ).
FILTER
使用 FILTER 根据条件来过滤内表数据
*---------------------------------------------------------------------*
* 使用 FILTER 时,待过滤的内表结构至少需要有一个用于访问的 SORTED KEY 或 HASHED KEY,
* 否则不能通过语法检查,另外,在 WHERE 条件中运算符两边的字段类型需要完全兼容,否则也不能通过语法检查;
* 根据条件进行过滤的功能可以使用 VALUE 嵌套 FOR 语句实现,而且不用考虑内表的键值问题
*---------------------------------------------------------------------*
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 WITH KEY MATNR WITH NON-UNIQUE SORTED KEY MATKL COMPONENTS MATKL.
LT_DATA = VALUE #( ( MATNR = 'Material-001'
MATKL = '1020'
TEXT1 = 100 )
( MATNR = 'Material-002'
MATKL = '1030'
TEXT1 = 200 )
( MATNR = 'Material-003'
MATKL = '1020'
TEXT1 = 300 ) ).
DATA(LT_FILTER) = FILTER #( LT_DATA USING KEY MATKL WHERE MATKL = CONV MATKL( '1020' ) )."CONV对值进行类型转换
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_FILTER ).
DATA(LT_FILTER2) = FILTER #( LT_DATA USING KEY MATKL WHERE MATKL > CONV MATKL( '1020' ) )."可以填入比较运算符
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_FILTER2 ).
*---------------------------------------------------------------------*
* 参照内表来过滤数据时,被参照的内表仍然需要有 SORTED KEY 或 HASHED KEY,对于过滤数据的内表没有键值要求;
* 在 FILTER 语句中可以通过 EXCEPT 关键字来指定是需要过滤数据还是保留数据;
* 该语法可以实现 FOR ALL ENTRIES IN,但是需要将数据全部取出,影响性能,
* 不建议使用,且在 ABAP 7.52 后,允许将内表作为数据源,可以用来代替 FOR ALL ENTRIES IN 使用
*---------------------------------------------------------------------*
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 SORTED TABLE OF TY_DATA WITH UNIQUE KEY MATNR,
LT_TEMP TYPE TABLE OF TY_DATA.
LT_DATA = VALUE #( ( MATNR = 'MATERIAL-001' MATKL = '1020' )
( MATNR = 'MATERIAL-002' MATKL = '1030' )
( MATNR = 'MATERIAL-003' MATKL = '1020' ) ).
LT_TEMP = VALUE #( ( MATNR = 'MATERIAL-002' MATKL = '1000' )
( MATNR = 'MATERIAL-002' MATKL = '1040' )
( MATNR = 'MATERIAL-004' MATKL = '1020' ) ).
DATA(LT_FILTER) = FILTER #( LT_TEMP IN LT_DATA WHERE MATNR = MATNR ).
DATA(LT_EXCEPT) = FILTER #( LT_TEMP EXCEPT IN LT_DATA WHERE MATNR = MATNR ).
EXACT
关键字 EXACT 可以用来检查操作语句返回值是否存在丢失,如果存在丢失则会抛出异常
*---------------------------------------------------------------------*
* 抛出异常的范围比CONV更广,例如将CHAR10的数据赋值到CHAR1时,
* 因此在使用时需要注意异常的捕获,如果没有特殊的处理或属性需求,
* 可以直接使用父类异常 CX_SY_CONVERSION_ERROR 进行捕获.
* 判断数值语句是否被精确计算,如下实际抛出的异常是CX_SY_CONVERSION_ROUNDING,
* 获取到该异常类中的属性字段VALUE的数据
*---------------------------------------------------------------------*
TRY .
DATA(LV_DATA) = EXACT #( 3 * ( 1 / 3 ) ).
CATCH CX_SY_CONVERSION_ROUNDING INTO DATA(LO_EXCEPT).
DATA(LV_RESULT) = LO_EXCEPT->VALUE.
ENDTRY.
*---------------------------------------------------------------------*
* 字段类型不兼容时,如下实际抛出的异常是 CX_SY_CONVERSION_NO_NUMBER,
* 这里获取的是父类CX_SY_CONVERSION_ERROR中的返回信息
*---------------------------------------------------------------------*
TYPES LTY_NUM TYPE N LENGTH 10.
TRY .
DATA(LV_NUM) = EXACT LTY_NUM( '4 Apples' ).
CATCH CX_SY_CONVERSION_ERROR INTO DATA(LO_CONVERT).
DATA(LV_ERROR) = LO_CONVERT->GET_TEXT( ).
ENDTRY.
ENUM枚举
ENUM 定义一个结构样式的集合,包含枚举类型的枚举值。如果某个字段参考枚举类型,则字段定义必须为枚举集里面的枚举类型,否则报错。
TYPES:
BEGIN OF ENUM COLORS1,
BLACK,
RED,
GOLD,
END OF ENUM COLORS1.
DATA MYCOLOR1 TYPE COLORS1.
MYCOLOR1 = BLACK. "如果此处修改为mycolor1 = orange.则无法激活,报错。
TYPES:
BEGIN OF ENUM COLORS2 STRUCTURE COLORS2_VALUES,
RED1,
WHITE1,
BLUE1,
END OF ENUM COLORS2 STRUCTURE COLORS2_VALUES.
DATA MYCOLOR2 TYPE COLORS2.
MYCOLOR2 = COLORS2_VALUES-RED1.
TYPES:
BEGIN OF ENUM COLORS3 STRUCTURE COLORS3_VALUES BASE TYPE INT1,
RED2 VALUE IS INITIAL,
GREEN2 VALUE 42,
BLUE2 VALUE 255,
END OF ENUM COLORS3 STRUCTURE COLORS3_VALUES.
DATA MYCOLOR3 TYPE COLORS3.
MYCOLOR3 = COLORS3_VALUES-GREEN2.