Wednesday 14 June 2023

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).

SAP ABAP, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Prep, SAP ABAP Preparation, SAP ABAP Tutorial and Materials
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.

No comments:

Post a Comment