Вы находитесь на странице: 1из 12

SALV Table 10 Editable SALV

Model (Overcome the


restriction of SALV Model)
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 cant 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 didnt work as I didnt 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 didnt 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-OFPAGE 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 doesnt
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.

Вам также может понравиться