Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shortest notation to split ABAP internal table into smaller pieces

In ABAP, I have a pretty large internal table, say 31,000 rows. What's the shortest and most efficient way to split that into multiple smaller tables of fixed size, say 1,000 rows each?

Naive way would be:

DATA lt_next_package TYPE tt_table_type.
LOOP AT it_large_table INTO DATA(ls_row).
  INSERT ls_row INTO TABLE lt_next_package.
  IF lines( lt_next_package ) >= lc_package_size.
    INSERT lt_next_package INTO TABLE rt_result.
    CLEAR lt_next_package.
  ENDIF.
ENDLOOP.
IF lt_next_package IS NOT INITIAL.
  INSERT lt_next_packge INTO TABLE rt_result.
ENDIF.

That works and is rather efficient, but looks cumbersome, esp. the don't-forget-the-last-package section at the very end. I believe there must be a better way to do this with the newer ABAP mesh paths and table expressions, but so far couldn't come up with one.

like image 566
Florian Avatar asked Nov 01 '25 19:11

Florian


2 Answers

I am not sure if, there is a right way to do it (sure, there are several ways to do it), but you can try this to overcome the last package problem:

WHILE it_large_table IS NOT INITIAL.
  LOOP AT it_large_table ASSIGNING FIELD-SYMBOL(<ls_line>) FROM 1 TO 1000.
    INSERT <ls_line> INTO TABLE lt_next_package.
  ENDLOOP.
  DELETE it_large_table FROM 1 TO 1000.
  INSERT lt_next_package INTO TABLE rt_table.
  CLEAR: lt_next_package.
ENDWHILE.
like image 192
József Szikszai Avatar answered Nov 04 '25 10:11

József Szikszai


Based on JozsefSzikszai's answer, devised another option:

rt_result = VALUE #( FOR i = 1
                     UNTIL i > round( val = lines( it_large_table) / lc_package_size
                                      dec = 0
                                      mode = cl_abap_math=>round_up )
                     LET lv_end = i * lc_package_size
                         lv_start = lv_end - lc_package_size + 1 IN
                       ( VALUE <result-type>(
                          ( LINES OF it_large_table FROM lv_start TO lv_end ) ) ) ).
like image 39
Florian Avatar answered Nov 04 '25 10:11

Florian