ALV with OO — CL_SALV_TABLE
Build modern ALV reports using CL_SALV_TABLE: the object-oriented approach with columns, sorting, aggregation, and event handling.
ALV with OO — CL_SALV_TABLE
What You'll Learn
- Creating ALV with CL_SALV_TABLE — the modern approach
- Customizing columns, sorting, and aggregation via methods
- Adding colors and icons
- The advantages over REUSE_ALV_GRID_DISPLAY
CL_SALV_TABLE — The Modern Way
REPORT z_salv_demo.
TYPES: BEGIN OF ty_employee,
employee_id TYPE n LENGTH 10,
name TYPE string,
department TYPE string,
salary TYPE p DECIMALS 2,
hire_date TYPE d,
END OF ty_employee.
DATA: lt_employees TYPE TABLE OF ty_employee,
lo_alv TYPE REF TO cl_salv_table.
START-OF-SELECTION.
lt_employees = VALUE #(
( employee_id = '0000000001' name = 'Alice Johnson' department = 'Engineering' salary = '120000' hire_date = '20200115' )
( employee_id = '0000000002' name = 'Bob Smith' department = 'Marketing' salary = '95000' hire_date = '20190601' )
( employee_id = '0000000003' name = 'Charlie Brown' department = 'Engineering' salary = '130000' hire_date = '20210320' )
( employee_id = '0000000004' name = 'Diana Prince' department = 'Sales' salary = '88000' hire_date = '20221110' )
( employee_id = '0000000005' name = 'Eve Wilson' department = 'Marketing' salary = '92000' hire_date = '20200805' )
).
TRY.
* Create the ALV object
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_employees ).
* Customize and display
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lo_error).
MESSAGE lo_error->get_text( ) TYPE 'E'.
ENDTRY.
That's the minimum — 3 lines of real code. But unlike REUSE_ALV, everything is configured through methods on the ALV object.
Customizing Columns
* Get the columns object
DATA(lo_columns) = lo_alv->get_columns( ).
lo_columns->set_optimize( ). " Auto-size columns
* Customize individual columns
TRY.
DATA(lo_col_name) = lo_columns->get_column( 'NAME' ).
lo_col_name->set_short_text( 'Name' ).
lo_col_name->set_medium_text( 'Employee Name' ).
lo_col_name->set_long_text( 'Full Employee Name' ).
lo_col_name->set_output_length( 25 ).
DATA(lo_col_salary) = CAST cl_salv_column_table( lo_columns->get_column( 'SALARY' ) ).
lo_col_salary->set_short_text( 'Salary' ).
* Hide a column
DATA(lo_col_id) = lo_columns->get_column( 'EMPLOYEE_ID' ).
lo_col_id->set_visible( if_salv_c_bool_sap=>false ).
CATCH cx_salv_not_found.
" Column not found — handle gracefully
ENDTRY.
Adding Sorting and Totals
* Sort by department ascending
DATA(lo_sorts) = lo_alv->get_sorts( ).
TRY.
lo_sorts->add_sort( columnname = 'DEPARTMENT' position = 1 sequence = if_salv_c_sort=>sort_up subtotal = if_salv_c_bool_sap=>true ).
lo_sorts->add_sort( columnname = 'SALARY' position = 2 sequence = if_salv_c_sort=>sort_down ).
CATCH cx_salv_not_found cx_salv_existing cx_salv_data_error.
ENDTRY.
* Add totals for salary column
DATA(lo_aggregations) = lo_alv->get_aggregations( ).
TRY.
lo_aggregations->add_aggregation( columnname = 'SALARY' aggregation = if_salv_c_aggregation=>total ).
CATCH cx_salv_not_found cx_salv_existing cx_salv_data_error.
ENDTRY.
Layout and Display Settings
* Zebra stripes
DATA(lo_display) = lo_alv->get_display_settings( ).
lo_display->set_striped_pattern( if_salv_c_bool_sap=>true ).
lo_display->set_list_header( 'Employee Salary Report' ).
* Enable all standard ALV functions (sort, filter, export, etc.)
DATA(lo_functions) = lo_alv->get_functions( ).
lo_functions->set_all( ).
set_all( ) enables every built-in ALV function — sorting, filtering, subtotals, export to Excel, print, column configuration, and more. Without it, some toolbar buttons may be hidden.
Complete Example
REPORT z_salv_complete.
TYPES: BEGIN OF ty_employee,
employee_id TYPE n LENGTH 10,
name TYPE string,
department TYPE string,
salary TYPE p DECIMALS 2,
hire_date TYPE d,
END OF ty_employee.
DATA: lt_employees TYPE TABLE OF ty_employee,
lo_alv TYPE REF TO cl_salv_table.
PARAMETERS: p_dept TYPE c LENGTH 30.
START-OF-SELECTION.
lt_employees = VALUE #(
( employee_id = '0000000001' name = 'Alice' department = 'Engineering' salary = '120000' hire_date = '20200115' )
( employee_id = '0000000002' name = 'Bob' department = 'Marketing' salary = '95000' hire_date = '20190601' )
( employee_id = '0000000003' name = 'Charlie' department = 'Engineering' salary = '130000' hire_date = '20210320' )
( employee_id = '0000000004' name = 'Diana' department = 'Sales' salary = '88000' hire_date = '20221110' )
( employee_id = '0000000005' name = 'Eve' department = 'Marketing' salary = '92000' hire_date = '20200805' )
).
* Filter by department if specified
IF p_dept IS NOT INITIAL.
DELETE lt_employees WHERE department <> p_dept.
ENDIF.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = lo_alv CHANGING t_table = lt_employees ).
* Enable all toolbar functions
lo_alv->get_functions( )->set_all( ).
* Optimize column widths
lo_alv->get_columns( )->set_optimize( ).
* Zebra pattern
lo_alv->get_display_settings( )->set_striped_pattern( if_salv_c_bool_sap=>true ).
lo_alv->get_display_settings( )->set_list_header( |Employee Report — { COND string( WHEN p_dept IS INITIAL THEN 'All Departments' ELSE p_dept ) }| ).
* Sort and subtotal
lo_alv->get_sorts( )->add_sort( columnname = 'DEPARTMENT' subtotal = if_salv_c_bool_sap=>true ).
lo_alv->get_aggregations( )->add_aggregation( columnname = 'SALARY' aggregation = if_salv_c_aggregation=>total ).
* Display
lo_alv->display( ).
CATCH cx_salv_msg cx_salv_not_found cx_salv_existing cx_salv_data_error INTO DATA(lo_err).
MESSAGE lo_err->get_text( ) TYPE 'E'.
ENDTRY.
REUSE vs CL_SALV — When to Use Which
Feature REUSE_ALV CL_SALV_TABLE
───────────────────────── ────────── ─────────────
Approach Function OOP
Field catalog Manual Auto-generated
Column customization Via table Via methods
Event handling FORM/PERFORM Class events
Editable grid Yes Limited
Recommended for new code No Yes
Learning curve Lower Moderate
For new programs, use CL_SALV_TABLE. It's cleaner, more maintainable, and SAP's recommended approach. Use REUSE_ALV only when maintaining existing code that already uses it, or when you need editable grid functionality.
Common Mistakes
- Forgetting
get_functions( )->set_all( ). Without it, the ALV toolbar is minimal — users can't sort, filter, or export. Always callset_all()unless you have a specific reason to restrict functions. - Not handling exceptions. CL_SALV methods throw exceptions for invalid column names, duplicate sorts, etc. Always wrap in TRY/CATCH.
- Trying to make CL_SALV_TABLE editable. CL_SALV_TABLE is designed for display, not editing. For editable grids, you need CL_GUI_ALV_GRID (more complex) or the REUSE function module approach.
Key Takeaways
- CL_SALV_TABLE is the modern OOP approach to ALV — cleaner than REUSE_ALV_GRID_DISPLAY.
factory()creates the ALV, method calls customize it,display()shows it.- Call
get_functions()->set_all()to enable all toolbar features. - Use
get_columns()to customize individual columns. - Use
get_sorts()for sorting andget_aggregations()for totals. - Always wrap in TRY/CATCH — CL_SALV methods throw exceptions.
Next Lesson
Module 4 is complete! You can build selection screens, handle events, create classical reports, and display professional ALV grids. In Module 5: Integration & Communication, we start with Lesson 23: Function Modules and Function Groups — how to build reusable, callable components in SAP.