ABAP--新语法--New Keyword in ABAP--第五天--GROUP BY(FOR LOOP)分组 FILTER过滤 EXACT ENUM枚举

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.
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值