ABAP 7.4 及更高版本 [3]:分组循环

2021-11-07 15:28发布


          点击此处--->   EasySAP.com 群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)

在这篇文章中,您将了解 7.40 中引入的 LOOP AT... GROUP BY 语句。可以使用此语句代替 AT NEW... END AT 语句。

您可以参考 SCN wiki Control Level Statements in ABAP – ABAP Development – Community Wiki (sap.com)以了解 AT…END AT 控制级别语句。

简而言之,在 LOOP 中可以使用 4 条 AT 语句来生成汇总数据。

  1. AT FIRST

    • 在表的第一条记录上执行

    • 可用于为报告编写标题

  2. AT NEW <field>

    • 当字段组合到 AT NEW 后提到的字段发生变化时执行

    • 可用于初始化所选组合的汇总数据

  3. AT END OF <field>

    • 在字段组合的最后一个条目上执行,直到 AT END OF 之后提到的字段

    • 可用于将汇总数据写入内部表或屏幕/调用 BAPI

  4. AT LAST

    • 在表的最后一条记录上执行

    • Clear / Free data tables

控制进入 AT…ENDAT 块,如下表所示。

例如,要使用 AT 语句打印每个 CARRID、CONNID、FLDATE 组合的总行李重量总和,如下所示。

LOOP AT bookings INTO DATA(booking).
  AT FIRST.
    WRITE: 'Carrier', 9 'Connection', 21 'Flight Date'.
    ULINE.
  ENDAT.
  AT NEW fldate.
    CLEAR total_weight.
    WRITE: /  booking-carrid, 9 booking-connid,
           21 booking-fldate.
    WRITE: 35 'Customer Id', 50 'Luggage Weight'.
  ENDAT.

  WRITE: /35 booking-customid, 50 booking-luggweight.
  total_weight = total_weight + booking-luggweight.
 
  AT END OF fldate.
    WRITE: /35 'Total Weight : ', 50 total_weight.
    ULINE.
  ENDAT.
ENDLOOP.


输出如下。

在 ABAP 7.4 中使用 LOOP AT .. GROUP BY 可以实现相同的输出。

WRITE: 'Carrier', 9 'Connection', 21 'Flight Date'.
ULINE.LOOP AT bookings INTO DATA(booking_gr)
                 GROUP BY ( carrid = booking_gr-carrid
                            connid = booking_gr-connid
                            fldate = booking_gr-fldate ).
  WRITE: /  booking_gr-carrid, 9 booking_gr-connid, 
         21 booking_gr-fldate.
  WRITE: 35 'Customer Id', 50 'Luggage Weight'.

  CLEAR total_weight.
  LOOP AT GROUP booking_gr 
                ASSIGNING FIELD-SYMBOL(<booking>).
    WRITE: /35 <booking>-customid, 50 <booking>-luggweight.
    total_weight = total_weight + <booking>-luggweight.  ENDLOOP.

  WRITE: /35 'Total Weight : ', 50 total_weight.
  ULINE.ENDLOOP.


为简单起见——让我们看看没有 write 语句的代码。

LOOP AT bookings INTO DATA(booking_gr)
                 GROUP BY ( carrid = booking_gr-carrid
                            connid = booking_gr-connid
                            fldate = booking_gr-fldate ). CLEAR total_weight.
 LOOP AT GROUP booking_gr ASSIGNING FIELD-SYMBOL(<booking>).
   total_weight = total_weight + <booking>-luggweight. 
 ENDLOOP.
ENDLOOP.

这将创建一个深层结构booking_gr,其中包含来自group by 子句(carrid、connid、fldate)的字段以及与该组合匹配的表条目。要在此循环,您需要使用 LOOP AT GROUP。

变化 - 

1. WITHOUT MEMBERS – 无需循环组成员即可获得唯一值。

LOOP AT bookings INTO DATA(booking_gr)
                 GROUP BY ( carrid = booking_gr-carrid )                 
                 WITHOUT MEMBERS
                 REFERENCE INTO DATA(booking_gr_2).  
                 WRITE: / booking_gr_2->carrid.
ENDLOOP.


请注意,显式引用用于获取数据。输出如下。

2. MEMBERS, SIZE 和 INDEX 的使用

在这里,您可以获得组的索引和组的大小,即组中的成员数量。注意指定的排序顺序。默认为升序。

LOOP AT bookings INTO DATA(booking_gr)
                 GROUP BY ( carrid = booking_gr-carrid
                            size   = GROUP SIZE
                            index  = GROUP INDEX )                ASCENDING 
                REFERENCE INTO DATA(booking_gr_2).  WRITE: / booking_gr_2->index LEFT-JUSTIFIED, 
          booking_gr_2->carrid, 
          booking_gr_2->size. 
ENDLOOP.

输出

因此,通过使用 LOOP AT... GROUP BY,您可以摆脱 AT 语句,使代码更简洁。与 AT 不同的是,您不需要将组合使用的字段作为表结构中的第一个字段。


例如,下面也可以工作。

LOOP AT bookings INTO DATA(booking_gr)
                 GROUP BY ( customid = booking_gr-customid
                            size     = GROUP SIZE
                            index    = GROUP INDEX )
                 REFERENCE INTO DATA(booking_gr_2).  WRITE: / booking_gr_2->customid, booking_gr_2->size.ENDLOOP.



赞赏支持