Application Development and Automation 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: 
Read only

Tricky packaging statement

0 Likes
1,869

Hello,

I have to implement some parallel processing logic and therefore I have to create data packages of a defined package size.

Example from standard documentation ( Horst Keller ) makes first step easy.

With this coding packaging is quite easy


DATA(n) = 10.
cl_demo_input=>request( EXPORTING text = `Package size`
CHANGING field = n ).
IF n <= 0.
RETURN.
ENDIF.

cl_demo_output=>begin_section( |Packages of { n }| ).
DATA group LIKE itab.
LOOP AT itab INTO DATA(wa)
GROUP BY ( sy-tabix - 1 ) DIV n + 1.
CLEAR group.
LOOP AT GROUP wa ASSIGNING FIELD-SYMBOL(<wa>).
group = VALUE #( BASE group ( <wa> ) ).
ENDLOOP.
cl_demo_output=>write( group ).
ENDLOOP.

But I have an additional condition for this package building. I'm processing pricing conditions and when processing a package all parts of a pricing scale have to be in the same package.
Can I add an additional expression after statement.

GROUP BY ( sy-tabix - 1 ) DIV n + 1.

What statement can I use too keep pricing scales together in one package and at the same time skip correctly to next package ? ( It may so be possible that the package is smaller than package size n )

6 REPLIES 6
Read only

Sandra_Rossi
Active Contributor
0 Likes
1,690

Please use the CODE button to format your code so that it's shown in a more user-friendly format (colorized).

Read only

Sandra_Rossi
Active Contributor
0 Likes
1,690

Can you provide an example with input data and expected result?

Read only

Sandra_Rossi
Active Contributor
0 Likes
1,690

For those persons interested, your example is taken from ABAP documentation - Internal Tables, Grouping with LOOP in Packages.

Read only

michael_piesche
Active Contributor
0 Likes
1,690

I think you answer belongs to a different question, no?

Read only

michael_piesche
Active Contributor
0 Likes
1,690

The taken example in your question to create packages does not depend on the row content. However, your requirement does also depend on the row content as well. And also your package size requirement makes it a little bit more complicated since a package is only allowed to be smaller but definitly not bigger.

  • which in the worst case does lead to an 'error', if the package size is smaller than the number of scales for a condition -> therefore I would go for being able to allow for bigger packages than the package size, only in the event of having to 'squeeze' in those extra scales

I am assuming, you are wanting to use the GROUP BY function, because it looks more organized and is less coding, than programming the functions behind that logic yourself. Just be aware, that less coding does not necessarily also mean more performance.

And with your requirements, there are several things to be calculated and looked ahead in the group by condition. So you will end up with more coding again, one way or the other.

Before going into all possibilities with the GROUP BY parameter of the LOOP AT statement, you definitely could achieve the following with using a method (see Internal Tables, Grouping with LOOP Using a Method):

  1. sort itab by the key of your pricing conditions, so that pricing conditions with several scales are 'grouped' together
  2. calculate the number of corresponding scales per key
  3. create a 'hashing' function that groups max n records together and throws records with 'overlapping' pricing conditions into the next group

For point 2) I used a separate LOOP...GROUP BY... using column values and stored the calculated value in an appended field to the table (you could also have a reference table by key-id and store the calculated value there).

For point 3) I used the LOOP...GROUP BY... using a method to create the required packages. Note, that in case of keys with many duplicate key entries larger than the package size, those packages will end up being larger than package size, to avoid having to leave out those records. And there will be also packages with smaller package size, in case the next key with duplicate key entries does not fit into the current package.

CLASS demo DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      main,
      class_constructor.
    CLASS-DATA:
     max_package_size TYPE int4 VALUE 4.
  PRIVATE SECTION.
    CLASS-DATA:
      current_carrid       TYPE spfli-carrid,
      current_package      TYPE int4 VALUE 1,
      current_package_size TYPE int4,
      BEGIN OF flight.
        INCLUDE TYPE spfli.
        CLASS-DATA: key_cnt TYPE int4,
      END OF flight,
      flights LIKE TABLE OF flight.
    CLASS-METHODS
      get_package IMPORTING flight         LIKE flight
                  RETURNING VALUE(package) TYPE int4.
ENDCLASS.

CLASS demo IMPLEMENTATION.
  METHOD main.
    DATA(out) = cl_demo_output=>new( ).

    DATA members LIKE flights.
    LOOP AT flights INTO DATA(wa)
         GROUP BY ( package = get_package( wa )
                    size = GROUP SIZE index = GROUP INDEX )
         ASSIGNING FIELD-SYMBOL(<group>).
      out->write( name = `Group key` data = <group> ).
      CLEAR members.
      LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<member>).
        members = VALUE #( BASE members ( <member> ) ).
      ENDLOOP.
      out->write( members )->line( ).
    ENDLOOP.

    out->display( ).
  ENDMETHOD.

  METHOD class_constructor.
    SELECT * FROM spfli    INTO TABLE flights ORDER BY carrid.
    LOOP AT flights INTO DATA(wa)
             GROUP BY ( carrid = wa-carrid
                        size = GROUP SIZE index = GROUP INDEX )
             ASSIGNING FIELD-SYMBOL(<group>).
      LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<member>).
        <member>-key_cnt = <group>-size.
      ENDLOOP.
    ENDLOOP.
  ENDMETHOD.

  METHOD get_package.
    package = current_package.
    IF current_carrid = flight-carrid.
      ADD 1 TO current_package_size.
    ELSE.
      current_carrid = flight-carrid.
      IF current_package_size >= max_package_size
      OR current_package_size + flight-key_cnt > max_package_size.
        ADD 1 TO: current_package, package.
        current_package_size = 1.
      ELSE.
        ADD 1 TO current_package_size.
      ENDIF.
    ENDIF.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.
  demo=>main( ).
Read only

michael_piesche
Active Contributor
0 Likes
1,690

thomas.therre, please follow up on your open question.

  • comment answers or your question if there are still open issues.
  • otherwise mark an answer as accepted if it helped you solve your problem
  • or post an answer of yourself and accept it if you found another useful solution yourself
  • or redirect your question to another question that is related and was useful to solve your problem
  • in the end, close your question