20240106

LOOP GROUP BY

  METHOD loop_group_by_1.

**     leva para as tabelas internas o mesmo tipo de
**     funcionalidade que já tinhamos no SELECT


*     LOOP AT itab INTO wa1 GROUP BY wa1-element.
*        ...
*        LOOP AT GROUP wa1 INTO wa2.
*           ..
*        ENDLOOP.
*
*     ENDLOOP.




  ENDMETHOD.



  METHOD loop_group_by_2.

     typesbegin of y_order,
                vbeln        type vbak-vbeln,
                kunnr        type vbak-kunnr,
                netwr        type vbak-netwr,
            end of y_order,

*            begin of y_kna1,
*              kunnr    type kna1-kunnr,
*              name1    type kna1-name1,
              t_order type STANDARD TABLE OF y_order
                 WITH DEFAULT KEY,
*            end of y_kna1,

            y_t_order    type STANDARD TABLE OF y_order
              WITH KEY PRIMARY_KEY COMPONENTS vbeln kunnr .



    data(t_orderVALUE y_t_order(
       vbeln '1001'  kunnr '10'  netwr '500' )
       vbeln '1002'  kunnr '10'  netwr '400' )
       vbeln '1003'  kunnr '20'  netwr '300' )
       vbeln '1004'  kunnr '20'  netwr '200' )
       vbeln '1005'  kunnr '10'  netwr '100' )
    ).

    LOOP AT t_order into DATA(s_customer)
      GROUP BY s_customer-kunnr.

      write:/
        |Cliene{ s_customer-kunnr }|.

*       Apenas no mesmo cliente
        LOOP AT GROUP s_customer into data(s_order).
           write:/
             |Ordem{ s_order-vbeln }Valor{ s_order-netwr } |.

        ENDLOOP.
    ENDLOOP.

    write:/
      |Total deciente{
         REDUCE vbak-netwr(
           INIT tot 0
           FOR  is_order in t_order
           WHERE kunnr s_customer-kunnr )
           NEXT tot += is_order-netwr
           )
         }|,/.


  ENDMETHOD.



**
** Modelo que apresenta os dados corretamente, mas
** que utiiza a estruura durante o proessamento.
  METHOD loop_group_by_3.

     typesbegin of y_order,
                vbeln        type vbak-vbeln,
                kunnr        type vbak-kunnr,
                netwr        type vbak-netwr,
            end of y_order,

     t_order type STANDARD TABLE OF y_order
       WITH DEFAULT KEY,

     y_t_order    type STANDARD TABLE OF y_order
       WITH KEY PRIMARY_KEY COMPONENTS vbeln kunnr .



    data(t_orderVALUE y_t_order(
       vbeln '1001'  kunnr '10'  netwr '500' )
       vbeln '1002'  kunnr '10'  netwr '400' )
       vbeln '1003'  kunnr '20'  netwr '300' )
       vbeln '1004'  kunnr '20'  netwr '600' )
       vbeln '1005'  kunnr '10'  netwr '100' )
    ).

    LOOP AT t_order into DATA(s_customer)
      GROUP BY s_customer-kunnr.

      write:/
        |Cliene{ s_customer-kunnr   }|.

*       Apenas no mesmo cliente
        LOOP AT GROUP s_customer into data(s_order).
           write:/
             |Ordem{ s_order-vbeln }Valor{ s_order-netwr } |.

        ENDLOOP.
    ENDLOOP.

    write:/
      |Total do clente{
         REDUCE vbak-netwr(
           INIT tot 0
           FOR  is_order in t_order
           WHERE kunnr s_customer-kunnr )
           NEXT tot += is_order-netwr
           )
         }|,/.

  ENDMETHOD.






**
** Modelo acima melhorado de modo que a chave kunnr
** é armazenada numa variável e que liberada de
** neccessidade de uso a estrutura s_wa1
  METHOD loop_group_by_4.

     typesbegin of y_order,
                vbeln        type vbak-vbeln,
                kunnr        type vbak-kunnr,
                netwr        type vbak-netwr,
            end of y_order,

     t_order type STANDARD TABLE OF y_order
       WITH DEFAULT KEY,

     y_t_order    type STANDARD TABLE OF y_order
       WITH KEY PRIMARY_KEY COMPONENTS vbeln kunnr .



    data(t_orderVALUE y_t_order(
       vbeln '1001'  kunnr '10'  netwr '500' )
       vbeln '1002'  kunnr '10'  netwr '400' )
       vbeln '1003'  kunnr '20'  netwr '300' )
       vbeln '1004'  kunnr '20'  netwr '600' )
       vbeln '1005'  kunnr '10'  netwr '100' )
    ).

    LOOP AT t_order into DATA(s_wa1)
      GROUP BY s_wa1-kunnr
      INTO DATA(kunnr_key).

      write:/
        |Cliene{ kunnr_key }|.

*       Apenas no mesmo cliente
        LOOP AT GROUP kunnr_key into data(s_order).
           write:/
             |Ordem{ s_order-vbeln }Valor{ s_order-netwr } |.

        ENDLOOP.
    ENDLOOP.

** Erro de sintaxe...
**
*    write:/
*      |Total do clente: {
*         REDUCE vbak-netwr(
*           INIT tot = 0
*           FOR  is_order in GROUP kunnr_key
*           NEXT tot += is_order-netwr
*           )
*         }|,/.

  ENDMETHOD.




**
**
**  Quebra com 2 campos
**
  METHOD loop_group_by_5.

     typesbegin of y_order,
                vbeln        type vbak-vbeln,
                vkorg        type vbak-vkorg,
                kunnr        type vbak-kunnr,
                netwr        type vbak-netwr,
            end of y_order,

     y_t_order    type STANDARD TABLE OF y_order
       WITH KEY PRIMARY_KEY COMPONENTS vbeln .



    data(t_orderVALUE y_t_order(
       vbeln '1001'  vkorg 'A'  kunnr '10'  netwr '500' )
       vbeln '1002'  vkorg 'A'  kunnr '40'  netwr '400' )
       vbeln '1003'  vkorg 'B'  kunnr '20'  netwr '300' )
       vbeln '1004'  vkorg 'B'  kunnr '20'  netwr '600' )
       vbeln '1005'  vkorg 'A'  kunnr '30'  netwr '100' )
       vbeln '1006'  vkorg 'A'  kunnr '30'  netwr '110' )
    ).

    SORT t_order by vkorg kunnr vbeln.

    LOOP AT t_order into DATA(s_wa1)
      GROUP BY (
        vkorg s_wa1-vkorg
        kunnr s_wa1-kunnr
      )
      INTO DATA(s_key1).

      write:/
        |VKORG{ s_key1-vkorg },|
        && |KUNNR{ s_key1-kunnr }|.

    ENDLOOP.

  ENDMETHOD.




**
**
** Vários níveis
**
  METHOD loop_group_by_6.

     typesbegin of y_order,
                vbeln        type vbak-vbeln,
                posnr        type posnr,
                kunnr        type vbak-kunnr,
                netwr        type vbak-netwr,
            end of y_order,

     y_t_order    type STANDARD TABLE OF y_order
       WITH KEY PRIMARY_KEY COMPONENTS vbeln .



    data(t_orderVALUE y_t_order(
       vbeln '1001'  posnr '00001'  kunnr '10'  netwr '500' )
       vbeln '1001'  posnr '00002'  kunnr '10'  netwr '100' )
       vbeln '1001'  posnr '00003'  kunnr '10'  netwr '100' )
       vbeln '1002'  posnr '00001'  kunnr '10'  netwr '400' )
       vbeln '1003'  posnr '00001'  kunnr '20'  netwr '300' )
       vbeln '1004'  posnr '00001'  kunnr '20'  netwr '200' )
       vbeln '1005'  posnr '00002'  kunnr '20'  netwr '400' )
       vbeln '1006'  posnr '00001'  kunnr '10'  netwr '100' )
    ).

    SORT t_order by kunnr vbeln posnr.

    LOOP AT t_order into DATA(s_wa1)       "nivel 1: cliente
      GROUP BY (
        kunnr s_wa1-kunnr
      )
      INTO DATA(s_key1).

      write:/
        |Cliente{ s_key1-kunnr }|.


      LOOP AT GROUP s_key1 into DATA(s_wa2)  "nível 2: ordem.
         GROUP BY (
            vbeln s_wa2-vbeln
         )
        INTO DATA(s_key2).


        write:/
          |Ordem{ s_key2-vbeln }|.


        LOOP AT GROUP s_key2 into DATA(s_wa3)"nível 3: item

          write:/
            |     Item{ s_wa3-posnr },Valor{ s_wa3-netwr }|.

        ENDLOOP.


        WRITE:/
           |      Total da Ordem{
                    REDUCE vbak-netwr(
                      INIT tot 0
                      FOR is_order in GROUP s_key2
                      NEXT tot += is_order-netwr
                    )
                  }|/.

      ENDLOOP.

*      WRITE:/
*         |      Total do Cliente: {
*                  REDUCE vbak-netwr(
*                    INIT tot = 0
*                    FOR ls_order IN s_key2
*                    NEXT tot += is_order-netwr
*                  )
*                }|, /.




    ENDLOOP.

  ENDMETHOD.





**
**
** Expressões NO GROUP BY
**
  METHOD loop_group_by_7.

     typesbegin of y_order,
                vbeln        type vbak-vbeln,
                posnr        type posnr,
                kunnr        type vbak-kunnr,
                netwr        type vbak-netwr,
            end of y_order,

     y_t_order    type STANDARD TABLE OF y_order
       WITH KEY PRIMARY_KEY COMPONENTS vbeln .



    data(t_orderVALUE y_t_order(
       vbeln '1001'  kunnr '10'  netwr '500' )
       vbeln '1002'  kunnr '10'  netwr '400' )
       vbeln '1003'  kunnr '20'  netwr '300' )
       vbeln '1004'  kunnr '20'  netwr '200' )
       vbeln '1005'  kunnr '20'  netwr '600' )
       vbeln '1006'  kunnr '10'  netwr '100' )
    ).

*    SORT t_order by kunnr vbeln posnr.

    LOOP AT t_order into DATA(s_wa1)
      GROUP BY (
        kunnr |Cliente{ s_wa1-kunnr } |
          && | { COND stringWHEN s_wa1-kunnr '10'
                              THEN 'este é o 10' )
               } |
      )
      INTO DATA(s_key1).

      write:/
        |Cliente{ s_key1-kunnr }|.

    ENDLOOP.

  ENDMETHOD.





**
**
** GROUP SIZEe GROUP iNDEX
**
  METHOD loop_group_by_8.

     typesbegin of y_order,
                vbeln        type vbak-vbeln,
                posnr        type posnr,
                kunnr        type vbak-kunnr,
                netwr        type vbak-netwr,
            end of y_order,

     y_t_order    type STANDARD TABLE OF y_order
       WITH KEY PRIMARY_KEY COMPONENTS vbeln .



    data(t_orderVALUE y_t_order(
       vbeln '1001'  kunnr '10'  netwr '500' )
       vbeln '1002'  kunnr '10'  netwr '400' )
       vbeln '1003'  kunnr '20'  netwr '300' )
       vbeln '1004'  kunnr '20'  netwr '200' )
       vbeln '1005'  kunnr '20'  netwr '600' )
       vbeln '1006'  kunnr '10'  netwr '100' )
    ).


    LOOP AT t_order into DATA(s_wa1)
      GROUP BY (
        kunnr s_wa1-kunnr
        index GROUP INDEX
        size  GROUP SIZE
      )
      INTO DATA(s_key1).

      write:/
           |Cliente{ s_key1-kunnr },|
        && |Index  { s_key1-index },|
        && |Size   { s_key1-size },|
        .

    ENDLOOP.

  ENDMETHOD.