Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

"LOOP AT ... GROUP BY" vs "FOR GROUPS ... OF"

0 Kudos

Hello,

Can someone explain why:

This compiles and works without errors:

data:
      begin of ls_hotel_item_group,
        posnr       type accit-posnr,
        group_index type i,
        item_type   type cte_s_fin_post_entry_item_rel-item_type,
      end of ls_hotel_item_group,
      lt_hotel_item_group like sorted table of ls_hotel_item_group
        with unique key primary_key components posnr group_index.

    data(ls_document_data) = zcl_im_concur_fin_exp_add_data=>ms_document_data.

    data(lt_hotel_lodging_entry) =
      value cte_t_fin_post_entry( for ls_entry in ls_document_data-entry
                                    where ( expense_type_name = 'Hotel'
                                        and expense_type_code = 'LODNG' )
                                    ( ls_entry ) ).
    
    " Group by vendor code and bill number
    loop at lt_hotel_lodging_entry into data(ls_hotel_lodging_entry)
      group by ( vendor = conv cte_api_string( ls_hotel_lodging_entry-entry_custom6_code )
                 bill_number = conv cte_api_string( ls_hotel_lodging_entry-entry_custom36_code )
                 size = group size
                 index = group index ) ascending into data(ls_hotel_group_key).

      " Group expense entries...except EVD = empl vendor
      loop at group ls_hotel_group_key into ls_hotel_lodging_entry.
        loop at ct_accrel into data(ls_accrel) where entry_id = ls_hotel_lodging_entry-entry_id
                                                 and item_type <> 'EVD'.
          insert value #( posnr = ls_accrel-posnr
                          group_index = ls_hotel_group_key-index
                          item_type = ls_accrel-item_type ) into table lt_hotel_item_group.
          clear ls_accrel.
        endloop.
        clear ls_hotel_lodging_entry.
      endloop.
      clear ls_hotel_lodging_entry.
    endloop.

But this does not? - syntax errors: structures in an OO context must be compatible.

    lt_hotel_item_group =
      value #( for groups ls_hotel_group_key of ls_hotel_lodging_entry in lt_hotel_lodging_entry
                 group by ( vendor      = conv cte_api_string( ls_hotel_lodging_entry-entry_custom6_code )
                            bill_number = conv cte_api_string( ls_hotel_lodging_entry-entry_custom36_code )
                            size        = group size
                            index       = group index ) ascending
                 for <ls_hotel_lodging_entry> in group ls_hotel_group_key
                   for ls_accrel in ct_accrel
                     where ( entry_id  =  <ls_hotel_lodging_entry>-entry_id
                         and item_type <> 'EVD' )
                   ( posnr       = ls_accrel-posnr
                     group_index = ls_hotel_group_key-index
                     item_type   = ls_accrel-item_type ) ).
1 REPLY 1

Sandra_Rossi
Active Contributor

I reproduce in 7.52 SP 0. Weird. Minimal reproducible (dumb) example:

  SELECT * FROM t005s INTO TABLE @DATA(lt_t005s).
  SELECT * FROM t005u INTO TABLE @DATA(lt_t005u).
  DATA(lt) = VALUE bapirettab(
             FOR GROUPS <ls_t005s_by_land1> OF <ls_t005s> IN lt_t005s
               GROUP BY <ls_t005s>-land1
             FOR <ls_t005u> IN lt_t005u
             ( ) ).

It seems that after FOR GROUPS, only its FOR IN GROUP is permitted, nothing else.

I'd say that there is a bug somewhere. I couldn't find a SAP note. The bug was already noticed here. But you can easily find a workaround. For instance (of course the example is still dumb - the syntax error is gone):

  SELECT * FROM t005s INTO TABLE @DATA(lt_t005s).
  SELECT * FROM t005u INTO TABLE @DATA(lt_t005u).
  TYPES ty TYPE STANDARD TABLE OF t005s-land1 WITH EMPTY KEY.
  DATA(lt) = VALUE bapirettab(
             LET table = VALUE ty( FOR GROUPS <ls_t005s_by_land1> OF <ls_t005s> IN lt_t005s
                                 GROUP BY <ls_t005s>-land1 ( ) ) IN
             FOR <line> IN table
             FOR <ls_t005u> IN lt_t005u
             ( ) ).