One ALV with headers and a second with details of selected row – quite a common use-case. And won’t it be practical to have all this in one screen, so users can check details quickly without constant back and forth between screens? This was indeed what users wanted and what I implemented for them.
In this post, I will describe how to make such a screen with two ALVs, utilizing CL_SALV_TABLE, displaying dependent information.
How to achieve split screen? Splitters and containers!
This screen distribution can be achieved by creating a splitter and two containers. Then place each ALV in its own container. I show it for two, but will work for whatever number you choose.
I do have my own class handling all the ALV-related things, therefore I have these set as instance attributes.
Then, compose everything together in the build_alv method. Notice how I specify the number of requested rows and columns when creating the splitter. When creating each ALV, I specify in which container they should go.
METHOD build_alv. *<------------------------------------------- DATA: lr_column_1 TYPE REF TO cl_salv_column_list, lr_column_2 TYPE REF TO cl_salv_column_list. DATA: lo_events TYPE REF TO cl_salv_events_table. * ------------------ * Create ALV screens TRY. * Splitter - it is neccessary to specify the default_screen as parent gr_splitter = NEW #( parent = cl_gui_container=>default_screen no_autodef_progid_dynnr = abap_true rows = 2 columns = 1 ). * Container 1 for header gr_container_1 = gr_splitter->get_container( row = 1 column = 1 ). * Container 2 for detail gr_container_2 = gr_splitter->get_container( row = 2 column = 1 ). *<< ALV1 - gt_alv_1 is the table with the data cl_salv_table=>factory( EXPORTING r_container = gr_container_1 IMPORTING r_salv_table = gr_salv_1 CHANGING t_table = gt_alv_1 ). * Set ALV functions - should you wish to include any gr_salv_func_1 = gr_salv_1->get_functions( ). gr_salv_func_1->set_all( abap_true ). * Set display settings as usual DATA(lr_display_1) = gr_salv_1->get_display_settings( ). * Selection - set as usual gr_salv_1->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>multiple ). * Layout - set as usual DATA(ls_key_1) = VALUE salv_s_layout_key( report = sy-cprog handle = '0001' ). DATA(lr_layout_1) = gr_salv_1->get_layout( ). lr_layout_1->set_key( ls_key_1 ).
Now we may proceed to create the second ALV in its own container. The data table may, for example, display the details of the very first row as default option.
*<< ALV_2 - details - gt_alv_2 is the table with data for the second ALV cl_salv_table=>factory( EXPORTING r_container = gr_container_2 IMPORTING r_salv_table = gr_salv_2 CHANGING t_table = gt_alv_2 ). * ALV functions gr_salv_2->get_functions( )->set_all( abap_true ). * Display settings - set as usual DATA(lr_display_2) = gr_salv_2->get_display_settings( ). * Layout - set as usual DATA(ls_key_2) = VALUE salv_s_layout_key( report = sy-cprog handle = '0002' ).
How to set column cells clickable? Hotspot and link click event!
Now our screen has correctly set container and we have created the first ALV. We want the column ‘TANUM’ to be clickable and display detail in the second ALV based on these clicks.
To achieve this, we can set this column as having cell type of if_salv_c_cell_type=>hotspot.
* Set columns * Set hotspot on particular column DATA(lr_columns_1) = gr_salv_1->get_columns( ). lr_columns_1->set_optimize( abap_true ). lr_column_1 ?= lr_columns_1->get_column( 'TANUM' ). lr_column_1->set_cell_type( if_salv_c_cell_type=>hotspot ).
To detect the event of user clicking on the hotspots, we will register an event handler for the ALV.
* ALV events - the implementation of the on link click event follows further in the post lo_events = gr_salv_1->get_event( ). SET HANDLER alv_1_on_link_click FOR lo_events.
And now we just display everything – do mind the write: space part. It will not display correctly if you omit it!
*<< Display ALV_1 gr_salv_1->display( ). *<< Display ALV_2, gr_salv_2->display( ). *<< Have to be to display ALV in full screen mode WRITE: space. CATCH cx_salv_msg cx_salv_not_found cx_salv_data_error cx_salv_access_error INTO DATA(lx_alv). DATA(lv_message) = lx_alv->get_text( ). raise_sy( ). ENDTRY. ENDMETHOD.
And with this the build_alv method is done!
On link click handler method
I have implemented the handler as another method of the class responsible for this whole screen. It has the following signature.
This event handler on its own provides us with the number of the row the user selected. This makes it very easy to work with. We will select the data we wish to have in the second ALV, put them in its data table and refresh everything.
METHOD alv_1_on_link_click. *<------------------------------------------- DATA: ls_alv_1 LIKE LINE OF gt_alv_1, ls_alv_2 LIKE LINE OF gt_alv_2, ls_data LIKE LINE OF go-data_t, ls_tai LIKE LINE OF ls_data-tai_t. * ------------------- *<< Get the data of the selected row and select data for second ALV accordingly to your needs READ TABLE gt_alv_1 INTO ls_alv_1 INDEX row. CHECK sy-subrc = 0. READ TABLE go-data_t INTO ls_data WITH KEY key_s-tanum = ls_alv_1-tanum. CHECK sy-subrc = 0. REFRESH gt_alv_2. LOOP AT ls_data-tai_t INTO ls_tai. MOVE-CORRESPONDING ls_tai TO ls_alv_2. APPEND ls_alv_2 TO gt_alv_2. ENDLOOP. gr_salv_1->refresh( ). * Second ALV will refresh its data based on the changed data table gr_salv_2->refresh( ). ENDMETHOD.
And this is it! A simple way to display two ALVs with dependent information based on user selection in one screen.
What about that Edit button?
You may have noticed that my first screenshot also includes Edit and Save buttons. Yes, it is indeed an editable ALV based on CL_SALV_TABLE. And more than that, it works with the changes made by the release 756!
If that is something you want too, I have already written about it here: https://blogs.sap.com/2022/08/01/editable-cl_salv_table-after-release-756/