Skip to Content
Technical Articles
Author's profile photo Victor Floret

Editable AVL grid with class CL_GUI_ALV_GRID

I have been looking in the forums for ways of making a CL_GUI_ALV_GRID grid editable for the user in a way that whatever value they put in the cells gets registered in the iternal table being displayed on that ALV, but most of the content I found were solutions using the FUNCTION ‘REUSE_ALV_GRID_DISPLAY_LVC’, but in my case I couldn’t use this function module because the program I was editing was already buit with CL_GUI_ALV_GRID, so I had to find out by myself (and with a little help from ChatGPT).

This%20is%20how%20it%20looks%20like

This is how it looks like

Here is the code I wrote. Don’t forget to add a button with code ‘SWITCH’ for calling the f_switch_edit_mode  subroutine.

*&---------------------------------------------------------------------*
*& Report  Z_EDITABLE_ALV_GRID -  Made with help of ChatGPT
*&---------------------------------------------------------------------*

REPORT z_editable_alv_grid.

* Types----------------------------------------------------------------*
TYPES BEGIN OF y_orders_c.
TYPES mu       TYPE mseg-erfme.
TYPES quant     TYPE mseg-lsmng.
TYPES quant2  TYPE mseg-lsmng. "make editable
TYPES mu2       TYPE mseg-lsmeh.
TYPES celltab   TYPE lvc_t_styl.
TYPES END OF y_orders_c.

* Declare local variables----------------------------------------------*
DATA: lo_grid     TYPE REF TO cl_gui_alv_grid,
      lt_fieldcat TYPE lvc_t_fcat,
      lt_data     TYPE TABLE OF y_orders_c.

DATA: gs_alv_layout TYPE lvc_s_layo .

DATA: e_cell_type TYPE lvc_s_styl.

DATA e_orders_c TYPE y_orders_c.

START-OF-SELECTION.

  CALL SCREEN 100.

MODULE show_orders OUTPUT.

  IF NOT lo_grid IS BOUND.

* Populate field catalog-----------------------------------------------*
    PERFORM f_fieldcat USING  lt_data[]
                      CHANGING  lt_fieldcat.
    LOOP AT lt_fieldcat ASSIGNING FIELD-SYMBOL(<fs_fieldcat>).

      CASE <fs_fieldcat>-fieldname.
        WHEN 'MU'.
          <fs_fieldcat>-coltext = 'MU'.
        WHEN 'QUANT'.
          <fs_fieldcat>-coltext = 'Original qtd.'.
        WHEN 'QUANT2'.
          <fs_fieldcat>-edit = 'X'. "Set field to editable
          <fs_fieldcat>-coltext = 'New qtd.'.
        WHEN 'MU2'.
          <fs_fieldcat>-coltext = 'New MU'.
      ENDCASE.
    ENDLOOP.

* Layout options-------------------------------------------------------*
    CLEAR gs_alv_layout.
    MOVE abap_true TO: gs_alv_layout-cwidth_opt,
                       gs_alv_layout-zebra,
                       gs_alv_layout-col_opt.
    gs_alv_layout-stylefname = 'CELLTAB'.


* Populate data--------------------------------------------------------*
    e_orders_c-mu = 'KG'.
    e_orders_c-quant = '2000'.
    e_orders_c-quant2 = '2'.
    e_orders_c-mu2 = 'TO'.
    APPEND e_orders_c TO lt_data.

    CLEAR e_orders_c-mu.
    e_orders_c-mu = 'KG'.
    e_orders_c-quant = '7000'.
    e_orders_c-quant2 = '7'.
    e_orders_c-mu2 = 'TO'.
    APPEND e_orders_c TO lt_data.

    CLEAR e_orders_c-mu.
    e_orders_c-mu = 'KG'.
    e_orders_c-quant = '15000'.
    e_orders_c-quant2 = '15'.
    e_orders_c-mu2 = 'TO'.
    APPEND e_orders_c TO lt_data.

    CLEAR e_orders_c-mu.
    e_orders_c-mu = 'KG'.
    e_orders_c-quant = '2500'.
    e_orders_c-quant2 = '2.5'.
    e_orders_c-mu2 = 'TO'.
    APPEND e_orders_c TO lt_data.

    CLEAR e_orders_c-mu.
    e_orders_c-mu = 'KG'.
    e_orders_c-quant = '1000'.
    e_orders_c-quant2 = '1'.
    e_orders_c-mu2 = 'TO'.
    APPEND e_orders_c TO lt_data.


* Create ALV grid and display------------------------------------------*
    CREATE OBJECT lo_grid
      EXPORTING
        i_parent = cl_gui_container=>screen0.

    CALL METHOD lo_grid->set_table_for_first_display
      EXPORTING
        i_structure_name = 'LT_DATA'
        is_layout        = gs_alv_layout
      CHANGING
        it_outtab        = lt_data
        it_fieldcatalog  = lt_fieldcat.

* Register event for cell editing--------------------------------------*
    CALL METHOD lo_grid->register_edit_event
      EXPORTING
        i_event_id = cl_gui_alv_grid=>mc_evt_enter
      EXCEPTIONS
        error      = 1
        OTHERS     = 2.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.

  ELSE.
    PERFORM f_update_grid USING lo_grid.
  ENDIF.

ENDMODULE.                 " SHOW_ORDERS  OUTPUT


*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  SET PF-STATUS 'STATS100'.
*  SET TITLEBAR 'your title here'.
ENDMODULE. "status_0100


*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
  CASE sy-ucomm.
    WHEN 'BACK' OR 'EXIT' OR 'CANCEL'.
      LEAVE TO SCREEN '0'.
    WHEN 'SWITCH'.
      PERFORM f_switch_edit_mode.
    WHEN OTHERS.
*     do nothing
  ENDCASE.
ENDMODULE. "user_command_0100


*&---------------------------------------------------------------------*
*&      Form  F_FIELDCAT
*&---------------------------------------------------------------------*
FORM f_fieldcat USING     pt_table     TYPE ANY TABLE
                  CHANGING  pt_fieldcat  TYPE lvc_t_fcat.

  DATA:
    lr_tabdescr TYPE REF TO cl_abap_structdescr,
    lr_data     TYPE REF TO data,
    lt_dfies    TYPE ddfields,
    ls_dfies    TYPE dfies,
    ls_fieldcat TYPE lvc_s_fcat.
  
  CLEAR pt_fieldcat.

  CREATE DATA lr_data LIKE LINE OF pt_table.
  lr_tabdescr ?= cl_abap_structdescr=>describe_by_data_ref( lr_data ).
  lt_dfies = cl_salv_data_descr=>read_structdescr( lr_tabdescr ).

  LOOP AT lt_dfies INTO ls_dfies.
    CLEAR ls_fieldcat.
    MOVE-CORRESPONDING ls_dfies TO ls_fieldcat.
    APPEND ls_fieldcat TO pt_fieldcat.
  ENDLOOP.
ENDFORM. "f_fieldcat


*&---------------------------------------------------------------------*
*&      Form  SWITCH_EDIT_MODE
*&---------------------------------------------------------------------*
FORM f_switch_edit_mode.

  IF lo_grid->is_ready_for_input( ) EQ 0.
* set edit enabled cells ready for input
    CALL METHOD lo_grid->set_ready_for_input
      EXPORTING
        i_ready_for_input = 1.

  ELSE.
* lock edit enabled cells against input
    CALL METHOD lo_grid->set_ready_for_input
      EXPORTING
        i_ready_for_input = 0.
  ENDIF.
ENDFORM. " f_switch_edit_mode


*&---------------------------------------------------------------------*
*&      Form  F_UPDATE_GRID
*&---------------------------------------------------------------------*
FORM f_update_grid USING p_grid TYPE REF TO cl_gui_alv_grid.

  DATA vl_stable TYPE lvc_s_stbl.

  CHECK p_grid IS BOUND.

  CLEAR vl_stable.
  MOVE abap_true TO:
    vl_stable-col,
    vl_stable-row.

  CALL METHOD p_grid->refresh_table_display
    EXPORTING
      is_stable = vl_stable
    EXCEPTIONS
      OTHERS    = 99.

  IF sy-subrc NE 0.
    RETURN.
  ENDIF.

ENDFORM.                    "f_update_grid

Code for the screen being called:

PROCESS BEFORE OUTPUT.
  MODULE status_0100.
  MODULE show_orders.

PROCESS AFTER INPUT.
  MODULE user_command_0100.

 

I hope it becomes useful for someone out there 😀

Edit: forgot to add the image lol

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Reto Fischer
      Reto Fischer

      There is a wonderful github project around alv grids. worth checking out

      https://github.com/fidley/falv

      Author's profile photo Victor Floret
      Victor Floret

      This is very interesting. Thanks for sharing! 😄

      Author's profile photo Sandra Rossi
      Sandra Rossi

      It's ALV, not AVL.

      I'm surprised that you didn't find code in the forum about CL_GUI_ALV_GRID in editable mode. Also, lots of demo programs by SAP.

      Just restricting the search on SAP blog posts:

      google%20CL_GUI_ALV_GRID%20editable

      google CL_GUI_ALV_GRID editable

      Author's profile photo Victor Floret
      Victor Floret

      Hi Sandra.

      The "AVL" was a typo. My mistake. I'm still trying to find how to fix it.

      And yes, there are some forum posts with code for creating and editable cl_gui_alv_grid, but none of the ones I tried have worked the way I wanted. Some would even make the cells editable, but the inputs wouldn't get saved to the internal table in the program. Most of the ones I read didn't mention that you have to call the method register_edit_event of the class cl_gui_alv_grid to save the data. That is a point where ChatGPT helped me.

      Thank you for your feedback and sorry for possible grammar mistakes and code mistakes. English is not my first language and I'm new to ABAP.

      Author's profile photo Sandra Rossi
      Sandra Rossi

      Thanks for the feedback. You can still fix the title typo => button Edit. Simple as that.

      register_edit_event is not needed to save the data.

      What is needed is to call the method CHECK_CHANGED_DATA to transfer the data from the screen to the internal table.

      Author's profile photo Nic Teunckens
      Nic Teunckens

      Check the dotabap website for Opensource projects.
      You can search for "ALV" and it will give you some popular resources on ALV-projects ...

      Kind regards

      Nic T.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Interesting, using CL_GUI_ALV_GRID directly works better than use the FM REUSE_ALV_GRID_DISPLAY_LVC. We had a popup with an editable ALV, using the FM. The problem was that if you changed a value and clicked on the green tick, the change wasn't registered. You had to press enter first.

      Using the class directly fixed this issue.

      A few points on your sample code, if I may.

      You're using L as a prefix in the same context as you're using G as a prefix. For your program, these are all global, not local, so the comment about local variables is incorrect. If you're going to use prefixes, they should be used consistently, otherwise it's pointless.

      Variables that are only used within a subroutine should be defined in that subroutine, not globally. Global variables should be used only where strictly necessary, otherwise you can end up with some very hard to fix bugs.

      FORMs have been obsolete for ages; except in very specific circumstances they shouldn't be used in new developments.

      Finally, you're using quite old fashioned syntax. Instead of:

          CREATE OBJECT lo_grid
            EXPORTING
              i_parent = cl_gui_container=>screen0.
      
          CALL METHOD lo_grid->set_table_for_first_display
            EXPORTING
              i_structure_name = 'LT_DATA'
              is_layout        = gs_alv_layout
            CHANGING
              it_outtab        = lt_data
              it_fieldcatalog  = lt_fieldcat.

      You could have

      lo_grid = NEW #( i_parent = cl_gui_container=>screen0 ).
      lo_grid->set_table_for_first_display( EXPORTING i_structure_name = 'LT_DATA'
                                                      is_layout        = gs_alv_layout
                                             CHANGING it_outtab        = lt_data
                                                      it_fieldcatalog  = lt_fieldcat ).

      Instead of

          e_orders_c-mu = 'KG'.
          e_orders_c-quant = '2000'.
          e_orders_c-quant2 = '2'.
          e_orders_c-mu2 = 'TO'.
          APPEND e_orders_c TO lt_data.

      you could have

      INSERT VALUE #( mu = 'KG' quant = '2000' quant2 = '2' mu2 = 'TO' ) INTO TABLE lt_data.

      I recommend looking at the Clean Code github. https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md

      Author's profile photo Victor Floret
      Victor Floret

      Hi Matthew!

      Thank you for your helpful tips! I'll try to keep them in mind for my next programs.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thanks for sharing! When I had to do this a few years ago, I poached the code from always reliable Naimesh Patel here: http://zevolving.com/2015/06/salv-table-20-editable-yes-as-per-this-standard-sap-application/

      Author's profile photo Paul Hardy
      Paul Hardy

      You might wonder why there are no standard SAP examples of how to use CL_GUI_ALV_GRID in editable mode. That is because according to the official SAP notes editing data using that class is not officially supported! Amazing but true.

      That being said there are hundreds of examples on the web as to how to do this. After all if you ask ChatGPT something and it comes back with the correct answer, where do you think it is getting that information from?

      As mentioned earlier the secret sauce is calling CHECK_CHANGED_DATA which magically pulls back the changed values from the screen to your internal table used ton populate that screen.

      As another fun fact did you know that CL_SALV_TABLE (the successor to CL_GUI_ALV_GRID) is not editable at all? Again, amazing but true.

      Lastly my programs fill the STABLE structure with ABAP_TRUE before doing a REFRESH as at some point in the past the default behaviour was to move the cursor from where it was on the screen to back to the start, so you had to force the issue.

      In later release e.g. ABAP 7.50 the REFRESH class has been changed - in CL_SALV_TABLE but probably not CL_GUI_ALV_GRID - such that the default behaviour is to fill the STABLE structure with ABAP_TRUE values.

      Cheersy Cheers

      Pau;