Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

DATA_CHANGED event handler is not triggered after error.

Former Member
0 Likes
2,096

Hi all,

My program is using the function 'REUSE_ALV_GRID_DISPLAY_LVC' to having the

cells as editable. When u2018ENTERu2019 is pushed the event DATA_CHANGED is triggered doing the checkings.

The program checks a particular cell to see if it is empty. If it is then an error is displayed in a popup window using er_data_changed->add_protocal_entry.

The problem is when the pop up message window is closed and u2018ENTERu2019 is pushed again (cell is still empty) the DATA_CHANGED is not triggered.

If a cell with a value has an error the event is triggered no matter how many times the u2018ENTERu2019 is pushed.

There anyone has any ideas on this problem?

Thanks in advance

/Rena

10 REPLIES 10
Read only

former_member209703
Active Contributor
0 Likes
1,817

Hi

It should trigger again, despite no changes have been made since the last time.

I suggest you to take a look at the standard demo program BCALV_EDIT_04 and try to adapt your code following that sample.

Regards.

Read only

0 Likes
1,817

Hi Jose,

I check the program BCALV_EDIT_03 instead of 04 which I bellieve that is more relevant because it has the event MCEVT_ENTER and I couldn't find any solution to my problem.

The check_changed_data event is declared in TOP_OF_PAGE as the following:

Any ideas would be helpful.

Thanks in advance

/Rena

****************************************************************************************

if ref1 is initial.

call function 'GET_GLOBALS_FROM_SLVC_FULLSCR'

importing

e_grid = ref1.

call method ref1->register_edit_event

exporting

i_event_id = cl_gui_alv_grid=>mc_evt_enter.

create object g_event_receiver.

set handler g_event_receiver->handle_data_changed for ref1.

call method cl_gui_cfw=>dispatch.

call method ref1->check_changed_data

importing e_valid = l_valid.

endif.

*Refresh if there is no error

if not ref1 is initial.

call method ref1->check_changed_data

importing e_valid = l_valid.

call method cl_gui_cfw=>dispatch.

endif.

ls_stable-row = 'X'.

ls_stable-col = 'X'.

call method ref1->refresh_table_display

exporting

is_stable = ls_stable

exceptions

finished = 1

others = 2.

if sy-subrc = 0. endif.

call method cl_gui_cfw=>flush.

endif.

Read only

0 Likes
1,817

Hi.

The key is in the code of the HANDLE_DATA_CHANGED event handler. As long as you give the corresponding error (adding a new entry to the protocol entry when the field has no value), the event will fired every time you press INTRO, despite you're not changing the actual value.


CLASS lcl_event_receiver IMPLEMENTATION.
  METHOD handle_data_changed.
*
    DATA: ls_good TYPE lvc_s_modi,
          l_price TYPE s_price,
          ls_new TYPE lvc_s_moce.

    error_in_data = space.

    LOOP AT er_data_changed->mt_good_cells INTO ls_good.
      IF ls_good-value. IS INITIAL.  <=== If the field you're checking is empty, throw the error. (This is the key part)
        CALL METHOD er_data_changed->add_protocol_entry
          EXPORTING
            i_msgid     = '0K'
            i_msgno     = '000'
            i_msgty     = 'E'
            i_msgv1     = 'JOSE'
            i_fieldname = ls_good-fieldname
            i_row_id    = ls_good-row_id.

      ENDIF.
    ENDLOOP.

Read only

0 Likes
1,817

Hi Jose,

the problem is that the HANDLE_DATA_CHANGED event handler isn't triggered by ENTER so the code

that you have proposed me wiil not be implemented. Do you think that my problem hasn't a solution ???

Have a nice day

/Rena

Read only

0 Likes
1,817

I think it does have a solution, in fact, I was testing it by modifying the standard demo program BCALV_EDIT_04 and it works as expected.

I'll try to paste the code over here:

Basically what I'm trying to show is that if you reset the value of SEATSMAX the system throws an error and the HANDLE_DATA_CHANGED is fired every time, however if you type a value that is not zero, after the first change and not having added the protocol entry that event is not fired anymore.


PROGRAM zbcalv_edit_04.

DATA: ok_code LIKE sy-ucomm,
      save_ok LIKE sy-ucomm,
      g_container TYPE scrfname VALUE 'BCALV_GRID_DEMO_0100_CONT1',
      g_grid  TYPE REF TO cl_gui_alv_grid,
      g_custom_container TYPE REF TO cl_gui_custom_container,
      gt_fieldcat TYPE lvc_t_fcat,
      gs_layout TYPE lvc_s_layo,
      g_max TYPE i VALUE 100,
      gs_spfli TYPE spfli,                                  "#EC NEEDED
      g_success TYPE c.

*local class to handle semantic checks
CLASS lcl_event_receiver DEFINITION DEFERRED.

DATA: g_verifier TYPE REF TO lcl_event_receiver.

DATA: BEGIN OF gt_outtab OCCURS 0.     "with header line
        INCLUDE STRUCTURE sflight.
DATA: celltab TYPE lvc_t_styl.
DATA: END OF gt_outtab.

DATA: g_carrid LIKE sflight-carrid,
      g_connid LIKE sflight-connid.


CLASS lcl_event_receiver DEFINITION.

  PUBLIC SECTION.

    TYPES: BEGIN OF sflight_key.
    TYPES:   carrid TYPE s_carr_id.
    TYPES:   connid TYPE s_conn_id.
    TYPES:   fldate TYPE s_date.
    TYPES: END OF sflight_key.

    TYPES: sflight_keys TYPE STANDARD TABLE OF sflight_key,
           sflight_table TYPE STANDARD TABLE OF sflight.

    METHODS:
      handle_data_changed
         FOR EVENT data_changed OF cl_gui_alv_grid
             IMPORTING er_data_changed.

    METHODS:
      get_inserted_rows
           EXPORTING
              inserted_rows TYPE sflight_keys.

    METHODS:
      get_deleted_rows
          EXPORTING
              deleted_rows TYPE sflight_table.

    METHODS:
       refresh_delta_tables.

    METHODS: set_table_is_initial.

    METHODS: set_table_is_not_initial.

    METHODS: table_is_initial
                RETURNING value(initial) TYPE char01.


  PRIVATE SECTION.


    DATA: inserted_rows TYPE sflight_keys,
          deleted_rows TYPE STANDARD TABLE OF sflight.
    DATA: error_in_data TYPE c.

    DATA: initial_table TYPE c.


ENDCLASS.                    "lcl_event_receiver DEFINITION


CLASS lcl_event_receiver IMPLEMENTATION.
  METHOD handle_data_changed.
*
    DATA: ls_good TYPE lvc_s_modi,
          l_price TYPE s_price,
          l_seatsmax TYPE s_seatsmax,
          ls_new TYPE lvc_s_moce.

    error_in_data = space.

    LOOP AT er_data_changed->mt_good_cells INTO ls_good.

      IF ls_good-fieldname EQ 'SEATSMAX'.

        CALL METHOD er_data_changed->get_cell_value
          EXPORTING
            i_row_id    = ls_good-row_id
            i_fieldname = ls_good-fieldname
          IMPORTING
            e_value     = l_seatsmax.

        IF l_seatsmax IS INITIAL.

          CALL METHOD er_data_changed->add_protocol_entry
            EXPORTING
              i_msgid     = '0K'
              i_msgno     = '000'
              i_msgty     = 'E'
              i_msgv1     = 'My Error'
              i_fieldname = ls_good-fieldname
              i_row_id    = ls_good-row_id.

        ENDIF.

      ENDIF.
    ENDLOOP.

    IF error_in_data = 'X'.
      CALL METHOD er_data_changed->display_protocol.
    ENDIF.

  ENDMETHOD.                    "handle_data_changed


  METHOD get_inserted_rows.
    inserted_rows = me->inserted_rows.
  ENDMETHOD.                    "get_inserted_rows
*------------------------------------------------------

  METHOD get_deleted_rows.
    deleted_rows = me->deleted_rows.
  ENDMETHOD.                    "get_deleted_rows
*------------------------------------------------------
  METHOD refresh_delta_tables.
    CLEAR me->inserted_rows[].
    CLEAR me->deleted_rows[].
  ENDMETHOD.                    "refresh_delta_tables
*------------------------------------------------------
  METHOD set_table_is_initial.
    initial_table = 'X'.
  ENDMETHOD.                    "set_table_is_initial
*------------------------------------------------------
  METHOD set_table_is_not_initial.
    initial_table = space.
  ENDMETHOD.                    "set_table_is_not_initial
*------------------------------------------------------
  METHOD table_is_initial.
    IF initial_table = 'X'.
      initial = 'X'.
    ELSE.
      initial = space.
    ENDIF.
  ENDMETHOD.                    "table_is_initial


ENDCLASS.                    "lcl_event_receiver IMPLEMENTATION

Read only

0 Likes
1,817


TABLES sflight.

PARAMETERS: p_ds TYPE c AS CHECKBOX.   "delete selection

SELECT-OPTIONS s_carrid FOR sflight-carrid
                            NO INTERVALS NO-EXTENSION DEFAULT 'LH'.
SELECT-OPTIONS s_connid FOR sflight-connid
                           NO INTERVALS NO-EXTENSION DEFAULT '0400'.

START-OF-SELECTION.

  g_carrid = s_carrid-low.
  g_connid = s_connid-low.

* first check airline and connection
  SELECT SINGLE * FROM spfli INTO gs_spfli
                     WHERE carrid = g_carrid
                     AND connid = g_connid.

  IF sy-subrc NE 0.
    CALL FUNCTION 'POPUP_TO_INFORM'
      EXPORTING
        titel = text-i01
        txt1  = text-i02
        txt2  = text-i03
        txt3  = text-i04
        txt4  = text-i05.
  ELSE.

    IF g_success EQ 'X'.
*      call screen 100.
    ELSE.
      MESSAGE i000(0k) WITH text-i10.
    ENDIF.
  ENDIF.

END-OF-SELECTION.
  PERFORM alv.


FORM build_fieldcat CHANGING pt_fieldcat TYPE lvc_t_fcat.

  DATA ls_fcat TYPE lvc_s_fcat.

  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING
      i_structure_name = 'SFLIGHT'
    CHANGING
      ct_fieldcat      = pt_fieldcat.

  LOOP AT pt_fieldcat INTO ls_fcat.
    ls_fcat-edit = ''.
    IF    ls_fcat-fieldname EQ 'PRICE'
       OR ls_fcat-fieldname EQ 'PLANETYPE'
       OR ls_fcat-fieldname EQ 'FLDATE'.
      ls_fcat-checktable = '!'.        "do not check foreign keys
      MODIFY pt_fieldcat FROM ls_fcat.
    ELSEIF ls_fcat-fieldname = 'CARRID'
       OR ls_fcat-fieldname = 'CONNID'
       OR ls_fcat-fieldname = 'CURRENCY'.
      ls_fcat-auto_value = 'X'.
      ls_fcat-checktable = '!'.   "do not check foreign key relations
    ELSEIF ls_fcat-fieldname EQ 'SEATSMAX'.
      ls_fcat-edit = 'X'.
    ENDIF.
    MODIFY pt_fieldcat FROM ls_fcat.

  ENDLOOP.

ENDFORM.                    "build_fieldcat

FORM select_data CHANGING pt_outtab LIKE gt_outtab[].
  DATA: lt_sflight TYPE TABLE OF sflight,
        ls_sflight TYPE sflight,
        ls_outtab LIKE LINE OF gt_outtab,
        l_index TYPE i,
        ls_spfli TYPE spfli,                                "#EC NEEDED
        lt_celltab TYPE lvc_t_styl.

  IF p_ds IS INITIAL.
    SELECT * FROM sflight INTO TABLE lt_sflight UP TO g_max ROWS
                     WHERE carrid = g_carrid
                       AND connid = g_connid.
  ENDIF.

  IF sy-subrc NE 0 OR NOT p_ds IS INITIAL.
    ls_outtab-carrid = g_carrid.
    ls_outtab-connid = g_connid.
    CASE g_carrid.
      WHEN 'LH'.
        ls_outtab-currency = 'DEM'.
      WHEN OTHERS.
        ls_outtab-currency = 'US'.
    ENDCASE.
    ls_outtab-seatsocc = 0.
    ls_outtab-paymentsum = 0.

    PERFORM fill_celltab USING 'RW'
                         CHANGING lt_celltab.
    INSERT LINES OF lt_celltab INTO TABLE ls_outtab-celltab.
    APPEND ls_outtab TO pt_outtab.

    CALL METHOD g_verifier->set_table_is_initial.
  ELSE.
    CALL METHOD g_verifier->set_table_is_not_initial.
    LOOP AT lt_sflight INTO ls_sflight.
      MOVE-CORRESPONDING ls_sflight TO ls_outtab.
      APPEND ls_outtab TO pt_outtab.
    ENDLOOP.

    LOOP AT pt_outtab INTO ls_outtab.
      l_index = sy-tabix.
      REFRESH lt_celltab.
      PERFORM fill_celltab USING 'RO'
                        CHANGING lt_celltab.

      INSERT LINES OF lt_celltab INTO TABLE ls_outtab-celltab.
      MODIFY pt_outtab FROM ls_outtab INDEX l_index.
    ENDLOOP.
  ENDIF.

ENDFORM.                               " select_data

Read only

0 Likes
1,817

FORM alv .
  DATA: lt_exclude TYPE ui_functions.
  DATA: g_repid TYPE syrepid.
  DATA: lt_evts      TYPE slis_t_event.
  g_repid = sy-repid.
  CREATE OBJECT g_verifier.
  PERFORM select_data CHANGING gt_outtab[].
  PERFORM build_fieldcat CHANGING gt_fieldcat.
  gs_layout-stylefname = 'CELLTAB'.
  PERFORM f01_set_evts CHANGING lt_evts.
  gs_layout-edit = 'X'.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program = g_repid
      is_layout_lvc      = gs_layout
      it_fieldcat_lvc    = gt_fieldcat
      it_events          = lt_evts
    TABLES
      t_outtab           = gt_outtab[]
    EXCEPTIONS
      program_error      = 1
      OTHERS             = 2.

ENDFORM.                    " ALV

FORM f01_set_evts CHANGING ct_events TYPE slis_t_event.

 FIELD-SYMBOLS: <ls_event> TYPE slis_alv_event.
  DATA: l_event  TYPE lvc_fname.
  CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
    EXPORTING
      i_list_type     = 4
    IMPORTING
      et_events       = ct_events
    EXCEPTIONS
      list_type_wrong = 1
      OTHERS          = 2.

  READ TABLE ct_events ASSIGNING <ls_event>
             WITH KEY name = 'CALLER_EXIT'.
  IF sy-subrc EQ 0.
    CONCATENATE 'F01_ALV_EVENT_'
                <ls_event>-name
                INTO <ls_event>-form.
  ENDIF.
ENDFORM.                    " f01_set_evts


FORM f01_set_evts CHANGING ct_events TYPE slis_t_event.

 FIELD-SYMBOLS: <ls_event> TYPE slis_alv_event.
  DATA: l_event  TYPE lvc_fname.
  CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
    EXPORTING
      i_list_type     = 4
    IMPORTING
      et_events       = ct_events
    EXCEPTIONS
      list_type_wrong = 1
      OTHERS          = 2.

  READ TABLE ct_events ASSIGNING <ls_event>
             WITH KEY name = 'CALLER_EXIT'.
  IF sy-subrc EQ 0.
    CONCATENATE 'F01_ALV_EVENT_'
                <ls_event>-name
                INTO <ls_event>-form.
  ENDIF.
ENDFORM.                    " f01_set_evts


FORM f01_alv_event_caller_exit USING cs_data TYPE slis_data_caller_exit.
                                                            "#EC *


  DATA: ref1 TYPE REF TO cl_gui_alv_grid,
        ls_layo_lvc TYPE lvc_s_layo.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = ref1.

  CHECK ref1 IS BOUND.
* Set editable cells to ready for input initially
  CALL METHOD ref1->set_ready_for_input
    EXPORTING
      i_ready_for_input = 1.


  CALL METHOD ref1->register_edit_event
    EXPORTING
      i_event_id = cl_gui_alv_grid=>mc_evt_enter.

  CREATE OBJECT g_verifier.
  SET HANDLER g_verifier->handle_data_changed FOR ref1.


ENDFORM.                    "f01_alv_event_caller_exit


FORM fill_celltab USING value(p_mode)
                  CHANGING pt_celltab TYPE lvc_t_styl.
  DATA: ls_celltab TYPE lvc_s_styl,
        l_mode TYPE raw4.
* This forms sets the style of columns 'PRICE', FLDATE and PLANETYPE
* editable

  IF p_mode EQ 'RW'.
    l_mode = cl_gui_alv_grid=>mc_style_enabled.
  ELSE.                                "p_mode eq 'RO'
    l_mode = cl_gui_alv_grid=>mc_style_disabled.
  ENDIF.

  ls_celltab-fieldname = 'FLDATE'.
  ls_celltab-style = l_mode.
  INSERT ls_celltab INTO TABLE pt_celltab.
  ls_celltab-fieldname = 'PRICE'.
  ls_celltab-style = l_mode.
  INSERT ls_celltab INTO TABLE pt_celltab.
  ls_celltab-fieldname = 'PLANETYPE'.
  ls_celltab-style = l_mode.
  INSERT ls_celltab INTO TABLE pt_celltab.

ENDFORM.                               " FILL_CELLTAB

Read only

0 Likes
1,817

Hi,

Try registering "ENTER" event

CALL METHOD <alv_grid>->register_edit_event

EXPORTING

i_event_id = cl_gui_alv_grid=>mc_evt_enter.

Regards,

Sharin

Read only

0 Likes
1,817

Hi Sharin,

I have already tried this and it didn' work.

Regards

/Rena

Read only

0 Likes
1,817

Hi Jose,

Iu2019ve made some modifications in your program and now the problem can be reproduced :

Do the followings:

After: LOOP AT er_data_changed->mt_good_cells INTO ls_good.

Insert: CALL METHOD er_data_changed->get_cell_value

EXPORTING

i_row_id = ls_good-row_id

i_fieldname = 'CURRENCY'

IMPORTING

e_value = l_CURRENCY.

IF l_CURRENCY IS INITIAL.

CALL METHOD er_data_changed->add_protocol_entry

EXPORTING

i_msgid = '0K'

i_msgno = '000'

i_msgty = 'E'

i_msgv1 = 'EMPTY CURRENCY'

i_fieldname = 'CURRENCY'

i_row_id = ls_good-row_id.

ENDIF.

Comment:

  • IF l_seatsmax IS INITIAL.

*

  • CALL METHOD er_data_changed->add_protocol_entry

  • EXPORTING

  • i_msgid = '0K'

  • i_msgno = '000'

  • i_msgty = 'E'

  • i_msgv1 = 'My Error'

  • i_fieldname = ls_good-fieldname

  • i_row_id = ls_good-row_id

  • ENDIF.

Insert: clear ls_outtab-currency.

Before

modify pt_outtab from ls_outtab index l_index.

endloop.

endif.

endform. " select_data

Test Instructions:

a) The Currency is empty, change the ID, press ENTER, an error is displayed, press ENTER again, no error.

This is my problem !!!

b) Now, fill the currency with a value, press ENTER, no error, clear the currency, press ENTER, we have an error, if you press again and again the ENTER the error will be displayed every time.

This is what I want in the case a).

Best Regards

/Rena