ALV 编辑自动触发数据变更功能
在开发过程中,我们经常开发一些可以编辑的 ALV 报表,在用户编辑过程中,要使 ALV 自动对数据变化做出反应,而不需要用户点击 ENTER 或任何其他按钮/菜单项。
OO 事件非常重要,在 ABAP 中处理它们非常容易。我们需要处理程序方法来注册事件
程序:
为了使系统对编辑事件作出反应,我们需要首先注册编辑事件。
要注册编辑事件,请调用方法 REGISTER_EDIT_EVENT
CALL METHOD gcl_alv_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter
EXCEPTIONS
error = 1
OTHERS = 2.
CALL METHOD gcl_alv_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_modified
EXCEPTIONS
error = 1
OTHERS = 2.
当用户按下 "ENTER "时,事件 MC_EVT_ENTER
被触发,自动将变量 M_cell_edit
设置为 X
。
但是如果用户绕过了回车键,那么变量 M_CELL_EDIT
就必须被明确设置,这是通过将 mc_evt_modified
传递到导出参数 I_EVENT_ID
而不是 mc_evt_enter
来完成的。
在 PAI 事件中,调用方法 CHECK_CHANGED_DATA
。这个方法会自动触发 data_changed
事件。
默认情况下,SAP 会识别 "ENTER "事件。 当在 PAI 事件中只调用了 CHECK_CHANGED_DATA
,那么系统就不会识别 "ENTER "事件。 为了让系统同时识别这两个事件,我们需要注册编辑事件。
示例代码:
*&---------------------------------------------------------------------*
*& 包含 ZFIU0XX_LCL
*&---------------------------------------------------------------------*
CLASS lcl_event_receiver DEFINITION. " LCL_EVENT_RECEIVER DEFINITION
PUBLIC SECTION.
METHODS data_changed FOR EVENT data_changed OF cl_gui_alv_grid
IMPORTING er_data_changed
e_ucomm.
METHODS handle_modify
FOR EVENT data_changed_finished OF cl_gui_alv_grid
IMPORTING e_modified et_good_cells.
ENDCLASS.
CLASS lcl_event_receiver IMPLEMENTATION.
METHOD data_changed.
PERFORM handle_data_changed USING er_data_changed.
ENDMETHOD.
METHOD handle_modify.
PERFORM handle_data_finish USING e_modified et_good_cells.
ENDMETHOD. " HANDLE MODIFY
ENDCLASS. " LCL_EVENT RECEIVER IMPLEMENTATION
*&---------------------------------------------------------------------*
*& Form HANDLE_DATA_CHANGED
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_ER_DATA_CHANGED text
*----------------------------------------------------------------------*
FORM handle_data_changed USING p_er_data_changed
TYPE REF TO cl_alv_changed_data_protocol.
DATA: mod_data TYPE lvc_t_modi,
gs_out_mod_data TYPE lvc_s_modi.
mod_data = p_er_data_changed->mt_mod_cells.
LOOP AT mod_data INTO gs_out_mod_data.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form HANDLE_DATA_FINISH
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_E_MODIFIED text
* -->P_ET_GOOD_CELLS text
*----------------------------------------------------------------------*
FORM handle_data_finish USING e_modified TYPE char01
et_good_cells TYPE lvc_t_modi.
DATA: eh_good_cells TYPE lvc_s_modi.
IF e_modified = 'X'.
LOOP AT et_good_cells INTO eh_good_cells. " 修改的行
UNASSIGN: <f_out>.
READ TABLE gt_out ASSIGNING <f_out> INDEX eh_good_cells-row_id.
IF sy-subrc = 0.
CLEAR: gs_out.
LOOP AT gt_out INTO gs_out WHERE asnum = <f_out>-asnum.
" 显示当前登录id
CALL METHOD cl_gui_frontend_services=>get_user_name
CHANGING
user_name = c_str
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
not_supported_by_gui = 3
OTHERS = 4.
CALL METHOD cl_gui_cfw=>flush
EXCEPTIONS
cntl_system_error = 1
cntl_error = 2.
CALL 'ThUsrInfo' ID 'OPCODE' FIELD opcode_usr_attr
ID'TERMINAL' FIELD terminal.
gs_out-erdat = sy-datum.
gs_out-erzet = sy-uzeit.
gs_out-ernam = c_str.
gs_out-zlogin = terminal.
CASE eh_good_cells-fieldname.
WHEN 'SAKNR'. " 手动更新SAKNR
SELECT COUNT( * ) FROM skat WHERE saknr = <f_out>-saknr.
IF sy-subrc = 0.
SELECT SINGLE txt20
FROM skat
INTO gs_out-txt20
WHERE saknr = <f_out>-saknr AND spras = sy-langu.
IF sy-subrc NE 0.
CLEAR: gs_out-txt20." ,gs_out-erdat,gs_out-erzet,gs_out-ernam,gs_out-zlogin.
ENDIF.
MODIFY gt_out FROM gs_out TRANSPORTING txt20 erdat erzet ernam zlogin .
CLEAR: gs_out.
ELSE.
MESSAGE '输入的总账科目有误,请检查!' TYPE 'E'.
ENDIF.
WHEN 'ZEKGRP_STR'.
IF sy-subrc NE 0.
CLEAR: gs_out-zekgrp_str.
ENDIF.
MODIFY gt_out FROM gs_out TRANSPORTING zekgrp_str erdat erzet ernam zlogin.
CLEAR: gs_out.
WHEN OTHERS.
ENDCASE.
ENDLOOP.
ENDIF.
ENDLOOP.
" 稳定刷新
gs_stbl-row = 'X'.
gs_stbl-col = 'X'.
CALL METHOD gcl_alv_grid->refresh_table_display
EXPORTING
is_stable = gs_stbl.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form REFRESH_TABLE_ALV
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM refresh_table_alv .
gs_stbl = 'X'. " 基于行的稳定刷新
gs_stbl = 'X'. " 基于列稳定刷新
CALL METHOD gcl_alv_grid->refresh_table_display
EXPORTING
is_stable = gs_stbl.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_EVENT
*定义事件
*&---------------------------------------------------------------------*
FORM frm_set_event.
CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
EXPORTING
i_list_type = 0
IMPORTING
et_events = gt_events
EXCEPTIONS
list_type_wrong = 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.
gs_events-name = 'CALLER_EXIT'.
gs_events-form = 'FRM_CALLER_EXIT'.
APPEND gs_events TO gt_events.
ENDFORM. " FRM_SET_EVENT
*&---------------------------------------------------------------------*
*& Form F_CALLER_EXIT
* 注册回车事件
*&---------------------------------------------------------------------*
FORM frm_caller_exit USING ls_data TYPE slis_data_caller_exit.
DATA gt_event_receiver TYPE REF TO lcl_event_receiver.
DATA: lt_f4 TYPE lvc_t_f4,
ls_f4 TYPE lvc_s_f4.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = gcl_alv_grid.
* 设置enter事件
CALL METHOD gcl_alv_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter
EXCEPTIONS
error = 1
OTHERS = 2.
CALL METHOD gcl_alv_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_modified
EXCEPTIONS
error = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suGT_OUTle error handling here
ENDIF.
CREATE OBJECT gt_event_receiver.
SET HANDLER gt_event_receiver->handle_modify FOR gcl_alv_grid.
SET HANDLER gt_event_receiver->data_changed FOR gcl_alv_grid.
ENDFORM. "F_CALLER_EXIT
当没有调用 REGISTER_EVT_MODIFIED
方法,而只是在 PAI 事件中调用 CHECK_CHANGED_DATA
方法。
当你改变数据并按下应用程序工具栏上的 "OK "按钮时,整个场景会正常工作。
但是,当你改变数据并按下 "ENTER "键时,事件 data_changed
就不会被触发了。
演示效果图如下:
- 点赞
- 收藏
- 关注作者
评论(0)