Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
naimesh_patel
Active Contributor

Don’t get too excited about the editable SALV solution out of the box, but I think we have a solution.

Recently paul.hardy2 published a blog International Editable SALV day as the 8th anniversary of the first SALV Editable question and so far no out of the box solution. To those who hasn’t read the previous so many discussion, out of box solution means a single method to make it editable. As of ABAP 740 SP05, there isn’t any new method in SALV OM which does the same thing or at least sounds like SET_EDITABLE.

I developed an work around in November 2008 and got lot of criticism for that. You can see the solution and read the comments - Power of ABAP Objects: Overcome the Restrictions of SALV Model

Based on the comments, customers should never use these type of workarounds. Obviously,  SAP must not use the work around as they say Editable is not intended purpose of SALV OM. But, look what I found >> Standard SAP (yes, standard SAP) has used the almost similar approach to make SALV editable which I used in my solution.

Standard SAP Application

I was replying to some query on CL_SALV_TREE and I did a where used on the adapter object and stumbled upon this function group FOT_RFD_MONI. Usually the adapter is used by only CL_SALV* Classes and my test program. But, suddenly I see a new program popping up in the where used list and that kept me thinking what is this program doing here?

This standard SAP application is developed using this approach – almost same as the approach used in my solution. (Note, that I’m not calling it a workaround anymore :wink: 😞

  • Inherit the class from the Model class
  • Create a method in the inherited class to gain access to the Adapter object – E.g. Grid, Fullscreen, Tree
  • Gain access of the underlying object – Grid or Tree

Class definition

Class Implementation

Use of method to make Grid editable / non-editable

Redefined Solution

So, based on this design, I simplified my version of the approach. Created a custom class where I have couple of helper methods to gain access to the adapter and then the underlying object – either Grid or Tree.

  • GET_GRID would be used to get the CL_GUI_ALV_GRID object
  • GET_TREE would be used to get the CL_GUI_ALV_TREE object

Utility Class

*----------------------------------------------------------------------*
*       CLASS ZCL_TEST_NP_SALV_MODEL DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_test_np_salv_model DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    CLASS-METHODS get_grid
      IMPORTING
        !io_salv_model TYPE REF TO cl_salv_model
      RETURNING
        value(eo_grid) TYPE REF TO cl_gui_alv_grid
      RAISING
        cx_salv_error .
    CLASS-METHODS get_tree
      IMPORTING
        !io_salv_model TYPE REF TO cl_salv_model
      RETURNING
        value(ro_tree) TYPE REF TO cl_gui_alv_tree
      RAISING
        cx_salv_error .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS ZCL_TEST_NP_SALV_MODEL IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_TEST_NP_SALV_MODEL=>GET_GRID
* +-------------------------------------------------------------------------------------------------+
* | [--->] IO_SALV_MODEL                  TYPE REF TO CL_SALV_MODEL
* | [<-()] EO_GRID                        TYPE REF TO CL_GUI_ALV_GRID
* | [!CX!] CX_SALV_ERROR
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD get_grid.

    DATAlo_error      TYPE REF TO cx_salv_msg.

    IF io_salv_model->model NE if_salv_c_model=>table.
      RAISE EXCEPTION TYPE cx_salv_msg
        EXPORTING
          msgid = '00'
          msgno = '001'
          msgty = 'E'
          msgv1 = 'Incorrect SALV Type'.
    ENDIF.

    eo_grid = lcl_salv_model_list=>get_grid( io_salv_model ).

  ENDMETHOD.                    "get_grid


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_TEST_NP_SALV_MODEL=>GET_TREE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IO_SALV_MODEL                  TYPE REF TO CL_SALV_MODEL
* | [<-()] RO_TREE                        TYPE REF TO CL_GUI_ALV_TREE
* | [!CX!] CX_SALV_ERROR
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD get_tree.

    DATAlo_error      TYPE REF TO cx_salv_msg.

    IF io_salv_model->model NE if_salv_c_model=>tree.
      RAISE EXCEPTION TYPE cx_salv_msg
        EXPORTING
          msgid = '00'
          msgno = '001'
          msgty = 'E'
          msgv1 = 'Incorrect SALV Type'.
    ENDIF.

    ro_tree = lcl_salv_model_list=>get_tree( io_salv_model ).

  ENDMETHOD.                    "GET_TREE
ENDCLASS.

To get the CL_GUI_ALV_GRID:

    DATA: lo_grid   TYPE REF TO cl_gui_alv_grid.
    DATA: lo_msg    TYPE REF TO cx_salv_msg.
    TRY .
        lo_grid  = zcl_test_np_salv_model=>get_grid( o_salv ).
      CATCH cx_salv_msg INTO lo_msg.
        "appropriate handling
    ENDTRY.

Local class LCL_SALV_MODEL_LIST which is inherited from CL_SALV_MODEL_BASE. Previously, I used the CL_SALV_MODEL_LIST to inherit my helper class, which wouldn't provide me the instance for the TREE. Thus, moved higher in the class hierarchy.

*"* use this source file for the definition and implementation of
*"* local helper classes, interface definitions and type
*"* declarations

*
CLASS lcl_salv_model_list DEFINITION INHERITING FROM cl_salv_model_base.

  PUBLIC SECTION.

    CLASS-METHODS:
      get_grid
        IMPORTING
          io_salv_model TYPE REF TO cl_salv_model
        RETURNING
          value(ro_gui_alv_grid) TYPE REF TO cl_gui_alv_grid
        RAISING
          cx_salv_msg,

      get_tree
        IMPORTING
          io_salv_model TYPE REF TO cl_salv_model
        RETURNING
          value(ro_tree) TYPE REF TO cl_gui_alv_tree
        RAISING
          cx_salv_msg.


ENDCLASS.                    "lcl_salv_model_list DEFINITION
*
CLASS lcl_salv_model_list IMPLEMENTATION.
  METHOD get_grid.
    DATA:
     lo_grid_adap TYPE REF TO cl_salv_grid_adapter,
     lo_fs_adap   TYPE REF TO cl_salv_fullscreen_adapter,
     lo_root      TYPE REF TO cx_root.

    TRY .
        lo_grid_adap ?= io_salv_model->r_controller->r_adapter.
      CATCH cx_root INTO lo_root.
        "could be fullscreen adaptper
        TRY .
            lo_fs_adap ?= io_salv_model->r_controller->r_adapter.
          CATCH cx_root INTO lo_root.
            RAISE EXCEPTION TYPE cx_salv_msg
              EXPORTING
                previous = lo_root
                msgid    = '00'
                msgno    = '001'
                msgty    = 'E'
                msgv1    = 'Check PREVIOUS exception'.
        ENDTRY.
    ENDTRY.

    IF lo_grid_adap IS NOT INITIAL.
      ro_gui_alv_grid = lo_grid_adap->get_grid( ).
    ELSEIF lo_fs_adap IS NOT INITIAL.
      ro_gui_alv_grid = lo_fs_adap->get_grid( ).
    ELSE.
      RAISE EXCEPTION TYPE cx_salv_msg
        EXPORTING
          msgid = '00'
          msgno = '001'
          msgty = 'W'
          msgv1 = 'Adapter is not bound yet'.
    ENDIF.


  ENDMETHOD.                    "get_grid

  METHOD get_tree.

    DATA:
     lo_tree_adap TYPE REF TO cl_salv_tree_adapter,
     lo_root      TYPE REF TO cx_root.

    TRY .
        lo_tree_adap ?= io_salv_model->r_controller->r_adapter.
      CATCH cx_root INTO lo_root.
        RAISE EXCEPTION TYPE cx_salv_msg
          EXPORTING
            previous = lo_root
            msgid    = '00'
            msgno    = '001'
            msgty    = 'E'
            msgv1    = 'Check PREVIOUS exception'.
    ENDTRY.

    IF lo_tree_adap IS NOT BOUND.
      RAISE EXCEPTION TYPE cx_salv_msg
        EXPORTING
          msgid = '00'
          msgno = '001'
          msgty = 'W'
          msgv1 = 'Adapter is not bound yet'.
    ENDIF.
    ro_tree = lo_tree_adap->r_tree.

  ENDMETHOD.                    "get_tree
ENDCLASS.                    "lcl_salv_model_list IMPLEMENTATION

To get the CL_GUI_ALV_TREE:

  DATA: lo_tree TYPE REF TO cl_gui_alv_tree.
  TRY .
      lo_tree = zcl_test_np_salv_model=>get_tree( gr_tree ).
    CATCH cx_salv_msg.

  ENDTRY.

Updated version of the ON_USER_COMMAND method in the original solution Power of ABAP Objects: Overcome the Restrictions of SALV Model

  METHOD on_user_command.
    DATA: lo_grid TYPE REF TO cl_gui_alv_grid.
    DATA: ls_layout TYPE lvc_s_layo.
    CASE e_salv_function.
*     Make ALV as Editable ALV
      WHEN 'MYFUNCTION'.
*>>       
        TRY .
            lo_grid = zcl_test_np_salv_model=>get_grid( lo_report->o_salv ).
          CATCH cx_salv_msg.
        ENDTRY.
*<<       
        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

Questions are ...

These also raises to these questions:

  • Is SAP not planning to have SET_EDITABLE method in OM as they have started using this approach?
  • Would SAP now provide support if customer uses the same approach and run into issues?
  • If no, than how come SAP approved this design to exist it in customer’s system?
  • If yes, As you can see, the application was created in somewhere 2011 by SAP. So, the developer must be aware of the existence of my solution. Shouldn't I get at least a some credit? Not that I want, but would be good to have, :wink:

Please share your thoughts...

updated on 23-Jun-15 at 8:30 AM CST to add the missing local class

31 Comments