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.

     types: begin 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_order) = VALUE 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.

     types: begin 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_order) = VALUE 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.

     types: begin 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_order) = VALUE 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.

     types: begin 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_order) = VALUE 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.

     types: begin 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_order) = VALUE 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.

     types: begin 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_order) = VALUE 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 string( WHEN 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.

     types: begin 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_order) = VALUE 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.