Mastering Dynamic Internal Table Sorting in SAP ABAP
Emre Göçmen
Author

Mastering Dynamic Internal Table Sorting in SAP ABAP
Dynamic internal table sorting is a powerful feature in SAP ABAP that allows developers to sort tables based on runtime conditions. This is particularly useful when sort criteria are not known at compile time and need to be determined during program execution. In this blog post, we will explore the intricacies of dynamic internal table sorting, accompanied by examples and best practices.
Introduction to Dynamic Sorting
In many scenarios, you may need to sort an internal table based on user inputs or other runtime conditions. Dynamic sorting in ABAP provides the flexibility to achieve this by allowing the sort fields and order to be specified by the program.
Basic Concepts
Before diving into dynamic sorting, let's briefly review the SORT statement in ABAP. The SORT statement is used to sort an internal table by one or more fields. Here's a simple example:
DATA: lt_table TYPE TABLE OF spfli,
ls_table TYPE spfli.
* Fill the table with sample data
SELECT * FROM spfli INTO TABLE lt_table.
* Sort the table by cityfrom in ascending order
SORT lt_table BY cityfrom.
In the above example, the sort field cityfrom is specified at compile time. However, in dynamic sorting, we determine the sort fields at runtime.
Dynamic Sorting Using Field Symbols
To sort an internal table dynamically, we use field symbols and dynamic expressions. Here's a step-by-step guide:
Step 1: Define and Populate the Internal Table
First, define and populate the internal table that you want to sort dynamically.
DATA: lt_table TYPE TABLE OF spfli,
ls_table TYPE spfli.
* Fill the table with sample data
SELECT * FROM spfli INTO TABLE lt_table.
Step 2: Determine Sort Criteria
Determine the sort criteria based on runtime conditions. This could be user inputs or any logic in your program.
DATA: lv_sort_field TYPE string.
* Set sort field based on a condition
lv_sort_field = 'CITYTO'. "" This could be dynamic based on user input
Step 3: Sort the Table Dynamically
Use the SORT statement with dynamic sorting. Here the VALUE operator and dynamic expressions are used.
TRY.
SORT lt_table BY VALUE #( ( name = lv_sort_field ) ).
CATCH cx_sy_dyn_table_ill_comp_val.
MESSAGE 'Error in sort criteria' TYPE 'E'.
ENDTRY.
In this example, lv_sort_field determines which field the table will be sorted by.
Advanced Dynamic Sorting
You can extend the dynamic sorting logic for more complex sorting scenarios like sorting by multiple fields or in different orders.
DATA: lt_sort_order TYPE abap_sortorder_tab,
lv_sort_field2 TYPE string.
lv_sort_field = 'CITYFROM'.
lv_sort_field2 = 'CITYTO'.
APPEND VALUE #( name = lv_sort_field ) TO lt_sort_order.
APPEND VALUE #( name = lv_sort_field2 descending = 'X' ) TO lt_sort_order.
TRY.
SORT lt_table BY lt_sort_order.
CATCH cx_sy_dyn_table_ill_comp_val.
MESSAGE 'Error in sort criteria' TYPE 'E'.
ENDTRY.
In this example, the internal table lt_table is sorted first by CITYFROM in ascending order and then by CITYTO in descending order.
Handling Errors
When performing dynamic sorting, it's important to handle potential errors. The CX_SY_DYN_TABLE_ILL_COMP_VAL exception can be used to catch issues with invalid sort criteria.
TRY.
SORT lt_table BY VALUE #( ( name = lv_sort_field ) ).
CATCH cx_sy_dyn_table_ill_comp_val.
MESSAGE 'Error in sort criteria' TYPE 'E'.
ENDTRY.
Dynamic Sorting with Field Symbols and Dynamic Tables
For sorting dynamic internal tables, we reference and process tables dynamically using field symbols. Here's how you can do this:
FIELD-SYMBOLS: <gfs_dyn_table> TYPE STANDARD TABLE,
<gfs_dyn_planned> TYPE STANDARD TABLE,
<gfs_dyn_unplanned> TYPE STANDARD TABLE,
<gfs_dyn_withdate_planned> TYPE STANDARD TABLE,
<gfs_dyn_withoutdate_planned> TYPE STANDARD TABLE,
<gfs_dyn_sorted> TYPE STANDARD TABLE,
<ls_table> TYPE any.
DATA : gt_planned TYPE REF TO data,
gt_unplanned TYPE REF TO data,
gt_withdate_planned TYPE REF TO data,
gt_withoutdate_planned TYPE REF TO data,
gt_sorted TYPE REF TO data.
* Create dynamic internal tables
CREATE DATA gt_planned LIKE <gfs_dyn_table>.
CREATE DATA gt_unplanned LIKE <gfs_dyn_table>.
CREATE DATA gt_withdate_planned LIKE <gfs_dyn_table>.
CREATE DATA gt_withoutdate_planned LIKE <gfs_dyn_table>.
CREATE DATA gt_sorted LIKE <gfs_dyn_table>.
* Assign dynamic tables to field symbols
ASSIGN gt_planned->* TO <gfs_dyn_planned>.
ASSIGN gt_unplanned->* TO <gfs_dyn_unplanned>.
ASSIGN gt_withdate_planned->* TO <gfs_dyn_withdate_planned>.
ASSIGN gt_withoutdate_planned->* TO <gfs_dyn_withoutdate_planned>.
ASSIGN gt_sorted->* TO <gfs_dyn_sorted>.
* Read data and separate by planning status
LOOP AT <gfs_dyn_table> ASSIGNING <ls_table>.
ASSIGN COMPONENT 'PLANLANDI' OF STRUCTURE <ls_table> TO FIELD-SYMBOL(<lv_plan>).
IF <lv_plan> IS NOT INITIAL.
APPEND <ls_table> TO <gfs_dyn_planned>.
ELSE.
APPEND <ls_table> TO <gfs_dyn_unplanned>.
ENDIF.
ENDLOOP.
* Separate planned data by material ready date
LOOP AT <gfs_dyn_planned> ASSIGNING <ls_table>.
ASSIGN COMPONENT 'DELIVERY_DATE' OF STRUCTURE <ls_table> TO FIELD-SYMBOL(<lv_date>).
IF <lv_date> IS NOT INITIAL AND <lv_date> NE '00000000'.
APPEND <ls_table> TO <gfs_dyn_withdate_planned>.
ELSE.
APPEND <ls_table> TO <gfs_dyn_withoutdate_planned>.
ENDIF.
ENDLOOP.
* Sort material ready dated records from oldest to newest within same production
*start date
SORT <gfs_dyn_withdate_planned> BY VALUE #( ( name = 'URETIM_BASLAMA_TARIH' )
( name = 'DELIVERY_DATE' ) ).
* Sort material ready undated records by priority descending within same production
*start date
SORT <gfs_dyn_withoutdate_planned> BY VALUE #( ( name = 'URETIM_BASLAMA_TARIH' )
( name = 'ONCELIK' descending = 'X' ) ).
* Combine sorted tables
APPEND LINES OF <gfs_dyn_withdate_planned> TO <gfs_dyn_sorted>.
APPEND LINES OF <gfs_dyn_withoutdate_planned> TO <gfs_dyn_sorted>.
APPEND LINES OF <gfs_dyn_unplanned> TO <gfs_dyn_sorted>.
* Write back results to original table
REFRESH <gfs_dyn_table>.
APPEND LINES OF <gfs_dyn_sorted> TO <gfs_dyn_table>.
This code demonstrates how to sort dynamic internal tables according to different conditions and combine them while preserving the primary sort order.
Practical Example
Let's put it all together in a practical example where sort criteria are determined by user input:
DATA: lt_table TYPE TABLE OF spfli,
ls_table TYPE spfli,
lv_sort_field TYPE string,
lt_sort_order TYPE abap_sortorder_tab.
* Fill the table with sample data
SELECT * FROM spfli INTO TABLE lt_table.
* User input to determine sort field
PARAMETERS: p_sort TYPE string.
lv_sort_field = p_sort.
APPEND VALUE #( name = lv_sort_field ) TO lt_sort_order.
TRY.
SORT lt_table BY lt_sort_order.
CATCH cx_sy_dyn_table_ill_comp_val.
MESSAGE 'Invalid sort field' TYPE 'E'.
ENDTRY.
* Display the sorted table
LOOP AT lt_table INTO ls_table.
WRITE: / ls_table-carrid, ls_table-connid, ls_table-cityfrom, ls_table-cityto.
ENDLOOP.
In this example, the user specifies the sort field via the p_sort parameter, and the internal table is sorted accordingly.
Conclusion
Dynamic internal table sorting in ABAP provides a robust way for handling sort requirements determined at runtime. By leveraging field symbols, dynamic expressions, and handling potential errors, you can build flexible and efficient sorting logic in your ABAP programs. This guide should equip you with the knowledge needed to implement dynamic sorting in various scenarios, enhancing the functionality and user experience of your applications.
Comments
No comments yet.
Be the first to comment.



