ALV 编辑自动触发数据变更功能

举报
雨绸缪 发表于 2023/05/30 17:54:04 2023/05/30
【摘要】 在开发过程中,我们经常开发一些可以编辑的 ALV 报表,在用户编辑过程中,要使 ALV 自动对数据变化做出反应,而不需要用户点击 ENTER 或任何其他按钮/菜单项。OO 事件非常重要,在 ABAP 中处理它们非常容易。我们需要处理程序方法来注册事件程序:为了使系统对编辑事件作出反应,我们需要首先注册编辑事件。要注册编辑事件,请调用方法 REGISTER_EDIT_EVENTCALL MET...

image.png

在开发过程中,我们经常开发一些可以编辑的 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 就不会被触发了。

演示效果图如下:

alv 自动变化.gif

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。