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.
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.
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 ) ) ) ).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With