How to disable the Editable ALV Grid in case of an incorrect entry?

subham soni picture subham soni · Jul 31, 2018 · Viewed 8.3k times · Source

Whenever an invalid value is entered in an ALV Grid, how do I disable the other fields (grey out) in the grid and force the user to fix the incorrect field.

I have tried adding protocol in DATA_CHANGED event. But protocol list only shows the error in popup. Editing is still possible and no fields are disabled.

But how do I disable the other fields. Sample behavior as shown below:

enter image description here

Here, the other fields are greyed out and the invalid entry is highlighted. Until the user fixes this error, he/she cannot proceed further.

Answer

Suncatcher picture Suncatcher · Aug 15, 2018

Having screen 100 with container CCONTAINER1 paste this snippet

CLASS zcl_alv_test DEFINITION.

  PUBLIC SECTION.
    METHODS: constructor, display_grid, populate_grid.

    DATA: lr_rtti_struc   TYPE REF TO cl_abap_structdescr,
          it_fldcat       TYPE lvc_t_fcat,
          grid_container1 TYPE REF TO cl_gui_custom_container,
          grid1           TYPE REF TO cl_gui_alv_grid.

    DATA: BEGIN OF gs_outtab.
            INCLUDE TYPE spfli.
    DATA: celltab TYPE lvc_t_styl.
    DATA: END OF gs_outtab.
    DATA gt_outtab1 LIKE TABLE OF gs_outtab INITIAL SIZE 0.

    METHODS:
      handle_data_changed FOR EVENT data_changed OF cl_gui_alv_grid IMPORTING er_data_changed,
      handle_data_changed_finished FOR EVENT data_changed_finished OF cl_gui_alv_grid IMPORTING e_modified et_good_cells,
      create_dynamic_fcat.

  PRIVATE SECTION.
    TYPES: ty_tab LIKE LINE OF gt_outtab1.
    METHODS: refresh_grid, fill_celltab IMPORTING p_fieldname TYPE lvc_fname
                                        CHANGING  pt_celltab  TYPE lvc_t_styl.
ENDCLASS.

CLASS zcl_alv_test IMPLEMENTATION.
  METHOD constructor.
    CREATE OBJECT grid_container1 EXPORTING container_name = 'CCONTAINER1'.
    CREATE OBJECT grid1 EXPORTING i_parent = grid_container1.

    SET HANDLER handle_data_changed FOR grid1.
    SET HANDLER handle_data_changed_finished FOR grid1.

    CALL METHOD grid1->register_edit_event
      EXPORTING
        i_event_id = cl_gui_alv_grid=>mc_evt_enter.
  ENDMETHOD. "constructor

  METHOD fill_celltab.
    LOOP AT pt_celltab ASSIGNING FIELD-SYMBOL(<fs_fcat>).
      IF <fs_fcat>-fieldname = p_fieldname.
        <fs_fcat>-style = cl_gui_alv_grid=>mc_style_enabled.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.

  METHOD handle_data_changed.
    DATA: lt_celltab TYPE lvc_t_styl.

    LOOP AT it_fldcat ASSIGNING FIELD-SYMBOL(<fs_fcat>).
      INSERT VALUE lvc_s_styl( style = cl_gui_alv_grid=>mc_style_disabled fieldname = <fs_fcat>-fieldname ) INTO TABLE lt_celltab.
    ENDLOOP.
    MODIFY gt_outtab1 FROM VALUE ty_tab( celltab = lt_celltab ) TRANSPORTING celltab WHERE connid IS NOT INITIAL.

    LOOP AT er_data_changed->mt_mod_cells ASSIGNING FIELD-SYMBOL(<mods>).
      READ TABLE gt_outtab1 ASSIGNING FIELD-SYMBOL(<sym>) INDEX <mods>-row_id.
      fill_celltab( EXPORTING p_fieldname = <mods>-fieldname
                                CHANGING pt_celltab = <sym>-celltab ).
      MODIFY gt_outtab1 FROM <sym> INDEX <mods>-row_id.
    ENDLOOP.
    refresh_grid( ).
  ENDMETHOD.

  METHOD handle_data_changed_finished.
    DATA: lt_celltab TYPE lvc_t_styl.

    LOOP AT it_fldcat ASSIGNING FIELD-SYMBOL(<fs_fcat>).
      IF sy-tabix MOD 2 = 0.
        DATA(style) = cl_gui_alv_grid=>mc_style_disabled.
      ELSE.
        style = cl_gui_alv_grid=>mc_style_enabled.
      ENDIF.
      INSERT VALUE lvc_s_styl( style = style fieldname = <fs_fcat>-fieldname ) INTO TABLE lt_celltab.
    ENDLOOP.

    MODIFY gt_outtab1 FROM VALUE ty_tab( celltab = lt_celltab ) TRANSPORTING celltab WHERE connid IS NOT INITIAL.
    refresh_grid( ).
  ENDMETHOD.

  METHOD create_dynamic_fcat.
    lr_rtti_struc ?= cl_abap_structdescr=>describe_by_name( 'SPFLI' ).
    DATA(comps) = lr_rtti_struc->components.

    LOOP AT comps ASSIGNING FIELD-SYMBOL(<comps>).
      IF sy-tabix MOD 2 = 0.
        DATA(edit) = abap_false.
      ELSE.
        edit = abap_true.
      ENDIF.
      APPEND VALUE lvc_s_fcat( edit = edit fieldname = <comps>-name datatype = <comps>-type_kind inttype = <comps>-type_kind intlen = <comps>-length decimals = <comps>-decimals coltext = <comps>-name lowercase = 'X' ) TO it_fldcat .
    ENDLOOP.
  ENDMETHOD. "create_dynamic_fcat

  METHOD populate_grid.
    SELECT * UP TO 1000 ROWS
    FROM spfli
    INTO CORRESPONDING FIELDS OF TABLE gt_outtab1.
  ENDMETHOD. "CHANGE_TITLE

  METHOD display_grid.
    create_dynamic_fcat( ).
    grid1->set_table_for_first_display(
      EXPORTING
        is_layout       = VALUE lvc_s_layo( zebra = abap_true stylefname = 'CELLTAB' )
      CHANGING
        it_outtab       = gt_outtab1
        it_fieldcatalog = it_fldcat ).
  ENDMETHOD. "display_grid

  METHOD refresh_grid.
    cl_gui_cfw=>flush( ).
    grid1->refresh_table_display( ).
  ENDMETHOD.
ENDCLASS.

MODULE status_0100 OUTPUT.
  SET PF-STATUS 'MAIN100'.
  DATA: yalv TYPE REF TO zcl_alv_test.
  CREATE OBJECT yalv.
  yalv->populate_grid( ).
  yalv->display_grid( ).
ENDMODULE.

MODULE user_command_0100 INPUT.
  CASE sy-ucomm.
    WHEN 'BACK' OR 'EXIT' OR 'RETURN'.
      LEAVE PROGRAM.
    WHEN OTHERS.
  ENDCASE.
ENDMODULE.

START-OF-SELECTION.
  CALL SCREEN 100.

It uses the concept of cell styles, where each row in table is assigned a table of styles for each of the column in this row. There you can apply conditional attributes on a cell level, including editability.

When throwing an error through builtin checktables/domains, the grid is made not editable except erroneous cell, and when correcting the error, editability returns.