We all know that ABAP Object is very powerful over the classical ABAP. Here I want to share one of my best experiments with the ABAP objects to overcome the restrictions of SALV mdoel.
Original
Initially I posted this article on SCN – Power of ABAP Objects: Overcome the Restrictions of SALV Model, which got lot of criticism and praise as well. When SCN was migrated to new system, the code snippet formatting got lost. So, I decided to move it here with the formatting.
Background
I was reading the help on the CL_SALV_TABLE to get more insight of how to use this new SALV model effectively. When I came across the section Recommendation and Restriction, I was amazed by reading “Tables displayed with ALV are not ready for input”.
It was very hard for me to understand this restriction because: The new SALV model is unified object oriented model which has kind of wrapper classes which are ultimately calling the FM REUSE_ALV_GRID_DISPLAY or REUSE_ALV_LIST_DISPLAY; class GL_GUI_ALV_GRID and so on. So, if the ALV created with the CL_GUI_ALV_GRID can be ready for input, why can’t the ALV created with the SALV model be the “Ready for input”? This propelled me to analyze how we can make the ALV Full-screen as “Set ready for Input”.
Journey to find the solution
By putting breakpoints and debugging, I came to know that when I tried to generate the fullscreen ALV, it calls the FM REUSE_ALV_GRID_DISPLAY and this FM in turn uses the class CL_GUI_ALV_GRID to generate the ALV.
Before couple of months, I came across a very powerful function module GET_GLOBALS_FROM_SLVC_FULLSCR which gives us the object of type GL_GUI_ALV_GRID which was created to generate the fullscreen ALV. I have used this FM in couple of programs to achieve some functionality which is not possible using the FM REUSE_ALV_GRID_DISPLAY. Some of them:
- Move Cursor to next row by pressing enter in Full-screen ALV
- Full-screen ALV: Disable DELTE key of Keyboard
- Full-screen ALV: Change Subtotal
- Re: Can we scroll to the last page of an alv grid?
Basically, to achieve this type of not achievable functionality of the Fullscreen ALV, I get the object using the FM GET_GLOBALS_FROM_SLVC_FULLSCR and use the methods available in the CL_GUI_GRID_DISPLAY followed by the refresh method to refresh the ALV.
Based on the assumption – if I get the ALV object from the SALV model than I can make the SALV model ALV to “Set Ready for input” – I have started searching the ALV object in the SALV model. At the very top node of the SALV model CL_SALV_MODEL, I got the methods (GET_GRID) which can provide me the ALV grid object.
UML diagram contains the SALV hierarchy and visibility of the R_CONTROLLER:
Class CL_SALV_MODEL has a protected attribute R_CONTROLLER which has everything I need to get to GRID object. So, I tried to access that attribute directly, but obviously I didn’t work as I didn’t have the object reference for the CL_SALV_MODEL. By this point of time, I have tried all the normal ways to get the access the R_CONTROLLER – like Feild-symbol to access the object from memory but that didn’t work either.
Solution
I knew that I have to think in a different way, and I tried to inherite the class from the class CL_SALV_MODEL_LIST, passed the ALV model to the class and tried to access the R_CONTROLLER and BINGO – I am able to access the R_CONTROLLER in my inherited class.
UML Diagram shows the iherited class along with the existing SALV model:
Steps to follow:
1. Inherited a local class LCL_SALV_MODEL from the CL_SALV_MODEL_LIST
2. Generate SALV model to generate the ALV object
3. Used narrow casting to get the CL_SALV_MODEL object from the ALV object
4. Passed this CL_SALV_MODEL object to the inherited class LCL_SALV_MODEL. Since LCL_SALV_MODEL is inherited from the CL_SALV_MODEL_LIST, it allows me to access the R_CONTROLLER of the CL_SALV_MODEL.
5. Get the GRID object from the object MODEL -> Controller -> Adapter -> Grid.
6. Set the Layout for EDIT and Refresh the ALV.
When we run the report, ALV will not come directly in the input mode:
As soon as we press the “My Function” button, ALV will change into editable ALV. This ALV will have its separate GUI Status which contains all the required buttons for the Editable ALV.
UML Diagram
UML diagram for code snippet:
Here is the code, which I used to get the access of the GRID object from the SALV model and to make ALV editable. Here I have used the PF-STATUS avaliable in the report program SALV_DEMO_TABLE_EVENTS for easy installation of this demo report.
*&---------------------------------------------------------------------* *& Report ZTEST_NP_EDIT_SALV *& Overcome the restriction of the SALV model using the power of the *& Object Oriented ABAP *&---------------------------------------------------------------------* REPORT ztest_np_edit_salv. *----------------------------------------------------------------------* * Define the Local class inheriting from the CL_SALV_MODEL_LIST * to get an access of the model, controller and adapter which inturn * provides the Grid Object *----------------------------------------------------------------------* CLASS lcl_salv_model DEFINITION INHERITING FROM cl_salv_model_list. PUBLIC SECTION. DATA: o_control TYPE REF TO cl_salv_controller_model, o_adapter TYPE REF TO cl_salv_adapter. METHODS: grabe_model IMPORTING io_model TYPE REF TO cl_salv_model, grabe_controller, grabe_adapter. PRIVATE SECTION. DATA: lo_model TYPE REF TO cl_salv_model. ENDCLASS. "LCL_SALV_MODEL DEFINITION *----------------------------------------------------------------------* * Event handler for the added buttons *----------------------------------------------------------------------* CLASS lcl_event_handler DEFINITION. PUBLIC SECTION. METHODS: on_user_command FOR EVENT added_function OF cl_salv_events IMPORTING e_salv_function. ENDCLASS. "lcl_event_handler DEFINITION *----------------------------------------------------------------------* * Local Report class - Definition *----------------------------------------------------------------------* CLASS lcl_report DEFINITION. PUBLIC SECTION. TYPES: ty_t_sflights TYPE STANDARD TABLE OF sflights. DATA: t_data TYPE ty_t_sflights. DATA: o_salv TYPE REF TO cl_salv_table. DATA: o_salv_model TYPE REF TO lcl_salv_model. METHODS: get_data, generate_output. ENDCLASS. "lcl_report DEFINITION *----------------------------------------------------------------------* * Global data *----------------------------------------------------------------------* DATA: lo_report TYPE REF TO lcl_report. *----------------------------------------------------------------------* * Start of selection *----------------------------------------------------------------------* START-OF-SELECTION. CREATE OBJECT lo_report. lo_report->get_data( ). lo_report->generate_output( ). *----------------------------------------------------------------------* * Local Report class - Implementation *----------------------------------------------------------------------* CLASS lcl_report IMPLEMENTATION. METHOD get_data. * test data SELECT * FROM sflights INTO TABLE me->t_data UP TO 30 ROWS. ENDMETHOD. "get_data METHOD generate_output. *...New ALV Instance ............................................... TRY. cl_salv_table=>factory( EXPORTING * r_container = w_alv1 list_display = abap_false IMPORTING r_salv_table = o_salv CHANGING t_table = t_data ). CATCH cx_salv_msg. "#EC NO_HANDLER ENDTRY. *...PF Status....................................................... * Add MYFUNCTION from the report SALV_DEMO_TABLE_EVENTS o_salv->set_screen_status( pfstatus = 'SALV_STANDARD' report = 'SALV_DEMO_TABLE_EVENTS' set_functions = o_salv->c_functions_all ). *...Event handler for the button..................................... DATA: lo_events TYPE REF TO cl_salv_events_table, lo_event_h TYPE REF TO lcl_event_handler. * event object lo_events = o_salv->get_event( ). * event handler CREATE OBJECT lo_event_h. * setting up the event handler SET HANDLER lo_event_h->on_user_command FOR lo_events. *...Get Model Object ............................................... DATA: lo_alv_mod TYPE REF TO cl_salv_model. * Narrow casting lo_alv_mod ?= o_salv. * object for the local inherited class from the CL_SALV_MODEL_LIST CREATE OBJECT o_salv_model. * grabe model to use it later CALL METHOD o_salv_model->grabe_model EXPORTING io_model = lo_alv_mod. *...Generate ALV output ............................................... o_salv->display( ). ENDMETHOD. "generate_output ENDCLASS. "lcl_report IMPLEMENTATION *----------------------------------------------------------------------* * LCL_SALV_MODEL implementation *----------------------------------------------------------------------* CLASS lcl_salv_model IMPLEMENTATION. METHOD grabe_model. * save the model lo_model = io_model. ENDMETHOD. "grabe_model METHOD grabe_controller. * save the controller o_control = lo_model->r_controller. ENDMETHOD. "grabe_controller METHOD grabe_adapter. * save the adapter from controller o_adapter ?= lo_model->r_controller->r_adapter. ENDMETHOD. "grabe_adapter ENDCLASS. "LCL_SALV_MODEL IMPLEMENTATION *----------------------------------------------------------------------* * Event Handler for the SALV *----------------------------------------------------------------------* CLASS lcl_event_handler IMPLEMENTATION. METHOD on_user_command. DATA: lo_grid TYPE REF TO cl_gui_alv_grid, lo_full_adap TYPE REF TO cl_salv_fullscreen_adapter. DATA: ls_layout TYPE lvc_s_layo. CASE e_salv_function. * Make ALV as Editable ALV WHEN 'MYFUNCTION'. * Contorller CALL METHOD lo_report->o_salv_model->grabe_controller. * Adapter CALL METHOD lo_report->o_salv_model->grabe_adapter. * Fullscreen Adapter (Down Casting) lo_full_adap ?= lo_report->o_salv_model->o_adapter. * Get the Grid lo_grid = lo_full_adap->get_grid( ). * Got the Grid .. ? IF lo_grid IS BOUND. * Editable ALV ls_layout-edit = 'X'. * Set the front layout of ALV CALL METHOD lo_grid->set_frontend_layout EXPORTING is_layout = ls_layout. * refresh the table CALL METHOD lo_grid->refresh_table_display. ENDIF. ENDCASE. ENDMETHOD. "on_user_command ENDCLASS. "lcl_event_handler IMPLEMENTATION
Example 2: Background Wallpaper in ALV created using SALV model
When we pass the parameter I_BACKGROUND_ID in the function module REUSE_ALV_GRID_DISPLAY, we will get the background wallpaper in the top of page section of the ALV.
SALV model uses the class CL_SALV_FORM_DYDOS to generate the TOP-OF-PAGE header from the SALV Form object (CL_SALV_FORM). CL_SALV_FORM is used to generate the Header in the SALV model.
When SALV model creates an object for the CL_SALV_FORM_DYDOS, it doesn’t pass the Wallpaper picture. Thus, we are not able to get the header background wallpaper in the SALV model.
To get the wallpaper in the header, we can use the same solution which we have used to make Editable ALV.
ALV header without wallpaper using the SALV model:
ALV header with the wallpaper using the SALV model:
Code snippet to get the header with the wallpaper:
Get the Header in the SALV:
* Code comes before the calling the Display method of SALV * O_SALV->DISPLAY( ) *...Header.......... ............................................... DATA: lo_header TYPE REF TO cl_salv_form_layout_grid, lo_h_label TYPE REF TO cl_salv_form_label, lo_h_flow TYPE REF TO cl_salv_form_layout_flow. * header object CREATE OBJECT lo_header. * information in Bold lo_h_label = lo_header->create_label( row = 1 column = 1 ). lo_h_label->set_text( 'Header in Bold' ). * information in tabular format lo_h_flow = lo_header->create_flow( row = 2 column = 1 ). lo_h_flow->create_text( text = 'This is text of flow' ). * set the top of list using the header for Online. o_salv->set_top_of_list( lo_header ).
Set the background wallpaper by accessing the GRID and TOP-of-LIST object
* Code comes in the event handler of the added button. * Get the Grid lo_grid = lo_full_adap->get_grid( ). * Got the Grid.. ? IF lo_grid IS BOUND. DATA: lo_form_tol TYPE REF TO cl_salv_form, lo_dydos TYPE REF TO cl_salv_form_dydos. * Get the Top of list object using the adapter CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR' EXPORTING ir_salv_fullscreen_adapter = lo_full_adap IMPORTING er_form_tol = lo_form_tol. * Got the Top Of List object.. ? IF lo_form_tol IS BOUND. * get the object using the Wide Casting lo_dydos ?= lo_form_tol. * set the wallpaper lo_dydos->set_wallpaper( 'ALV_BACKGROUND' ). * refresh the table CALL METHOD lo_grid->refresh_table_display. ENDIF. ENDIF.
Trackback
Power of ABAP Objects: Overcome the Restrictions of SALV Model
Hi naimesh, your blog contain very helpful.
By the way I want to know about call windows sound or whatever sound with abap.
Because I am still develop interface, I want appear sound via internal speaker if any error.
hopefully you can help me.
thx a lot before and after.
Your blog is very helpful. Thank you.
Where is the editable ALV useful. Is it just to edit the data and then the printout or we can use it to post data or maintain the table too.
Thanks
In 10 years, I have coded only 5 editable ALVs (using the old cl_gui_alv_grid), so this is not an important tool in my toolbox. What I found very funny was SAP’s responses. They could have had a disclaimer such as “SALV is not editable and we will NOT provide support!’.
Heep up the great work!
Hello Steve,
Yes, you are correct. SAP has documented that “SALV is not editable” but they never mentioned that they wont support if someone tries to do this type of tricks.
Regards,
Naimesh Patel