Search code examples
abapalv

data_change using cl_gui_alv_grid - not reacting to Enter key


I want to populate a field when another field was edited. So this is the method in the implementation.

When I press Enter nothing happens, but when i double click the change applies.

Do you have any idea or fix? I am using the class cl_gui_alv_grid.

METHOD data_changed_finished.
DATA: ls_inr   TYPE LINE OF lvc_t_modi,
      lv_stbl  TYPE lvc_s_stbl,
      gt_out type standard table of SPFLI,
      ls_out   LIKE LINE OF gt_out.


LOOP AT et_good_cells INTO ls_inr
  WHERE fieldname = 'CITYFROM'. 
  EXIT.
ENDLOOP.

DATA:
  ld_REFRESH_MODE TYPE SALV_DE_CONSTANT ,
  ld_S_STABLE TYPE LVC_S_STBL.
  ld_S_STABLE-row = 'X'.
  ld_S_STABLE-col = 'X'.

IF sy-subrc = 0.
  LOOP AT et_good_cells INTO ls_inr.
    LOOP AT IT_SPFLI INTO ls_out
                   FROM ls_inr-row_id
                   TO ls_inr-row_id.
      
      ls_out-DISTANCE = '556'.
      MODIFY IT_SPFLI FROM ls_out.

    ENDLOOP.
  ENDLOOP.

ENDIF.


  lv_stbl-row = 'X'.
  lv_stbl-col = 'X'. 

  ld_S_STABLE-row = 'X'.
  ld_S_STABLE-col = 'X'.
  ld_REFRESH_MODE = 2. 
  
  CALL METHOD salv->REFRESH(
  EXPORTING
  REFRESH_MODE = ld_REFRESH_MODE
  S_STABLE = ld_S_STABLE ).

ENDMETHOD.

Solution

  • So, as I said in the comments, it's obvious to me that the question is more about CL_GUI_ALV_GRID (not CL_SALV_TABLE). By default, the Enter key does not trigger the events DATA_CHANGED and DATA_CHANGED_FINISHED.

    If you want this feature, you must call the method REGISTER_EDIT_EVENT and pass one of these two constants for the firing of the two events; you may call the method twice, once for the first constant and once for the second to combine their behaviors (EDIT Aug 10th/11th, 2024):

    • MC_EVT_ENTER:
      • The event DATA_CHANGED is fired if Enter is pressed and at least one cell is changed. always be fired when Enter is pressed, even if no cells have been changed
      • The event DATA_CHANGED_FINISHED is fired if Enter is pressed, even if no cell was changed.
    • MC_EVT_MODIFIED:
      • The two events are fired (DATA_CHANGED first, DATA_CHANGED_FINISHED second) if one cell is changed and either Enter is pressed or the focus is changed to somewhere else in the ALV Grid (press an ALV toolbar button, go to another cell, column or row selection, etc.)

    Demo program (NB: if the table SBOOK is empty, fill it by calling the program SAPBC_DATA_GENERATOR):

    REPORT z_demo.
    CLASS lcl_app DEFINITION DEFERRED.
    DATA go_app TYPE REF TO lcl_app.
    TABLES sscrfields.
    PARAMETERS enter AS CHECKBOX DEFAULT 'X'.
    PARAMETERS modified AS CHECKBOX DEFAULT 'X'.
    AT SELECTION-SCREEN.
      IF sscrfields-ucomm = 'ONLI' AND go_app IS NOT BOUND.
        CREATE OBJECT go_app TYPE ('LCL_APP').
        CALL METHOD go_app->('DISPLAY_ALV').
        LEAVE SCREEN. " Stop the Dynpro logic, don't go to START-OF-SELECTION.
      ENDIF.
    AT SELECTION-SCREEN ON EXIT-COMMAND.
      IF go_app IS BOUND.
        CALL METHOD go_app->('FREE'). " Stop the ALV display
        FREE go_app.
        LEAVE SCREEN. " Stop the Dynpro logic, don't leave the program.
      ENDIF.
    CLASS lcl_app DEFINITION.
      PUBLIC SECTION.
        METHODS display_alv.
        METHODS free.
        METHODS on_data_changed FOR EVENT data_changed OF cl_gui_alv_grid
          IMPORTING er_data_changed e_onf4 e_onf4_after e_onf4_before e_ucomm.
        METHODS on_data_changed_finished FOR EVENT data_changed_finished OF cl_gui_alv_grid
          IMPORTING et_good_cells e_modified.
        DATA go_alv   TYPE REF TO cl_gui_alv_grid.
        DATA gt_sbook TYPE TABLE OF sbook.
    ENDCLASS.
    CLASS lcl_app IMPLEMENTATION.
      METHOD display_alv.
        go_alv = NEW #( i_parent = cl_gui_container=>screen0 ).
        SET HANDLER on_data_changed FOR go_alv.
        SET HANDLER on_data_changed_finished FOR go_alv.
        IF enter = abap_true.
          go_alv->register_edit_event( EXPORTING  i_event_id = go_alv->mc_evt_enter
                                       EXCEPTIONS error      = 1
                                                  OTHERS     = 2 ).
        ENDIF.
        IF modified = abap_true.
          go_alv->register_edit_event( EXPORTING  i_event_id = go_alv->mc_evt_modified
                                       EXCEPTIONS error      = 1
                                                  OTHERS     = 2 ).
        ENDIF.
        SELECT * FROM sbook UP TO 1 ROWS INTO TABLE gt_sbook.
        go_alv->set_table_for_first_display( EXPORTING i_structure_name = 'SBOOK'
                                                       is_layout        = VALUE #( edit = abap_true )
                                             CHANGING  it_outtab        = gt_sbook ).
      ENDMETHOD.
      METHOD free.
        go_alv->free( ).
      ENDMETHOD.
      METHOD on_data_changed_finished.
        MESSAGE 'data_changed_finished' TYPE 'I'.
      ENDMETHOD.
      METHOD on_data_changed.
        MESSAGE 'data_changed' TYPE 'I'.
      ENDMETHOD.
    ENDCLASS.