You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ALV Grid:调用CHANGE_DATA_FROM_INSIDE()后如何手动触发DATA_CHANGED?

解决方案

核心思路

通过主动控制数据变更标记与ENTER键的事件触发逻辑,实现“填充不校验、ENTER触发校验”的需求:

  1. 自定义按钮填充数据时,直接更新内表并刷新ALV,不触发校验;
  2. 给ENTER键分配专属功能码,在USER_COMMAND中主动调用ALV的校验方法,触发DATA_CHANGED事件。

具体实现步骤

1. 自定义按钮填充数据逻辑

放弃CHANGE_DATA_FROM_INSIDE,直接更新ALV绑定的内表,用软刷新同步界面,避免触发自动校验:

METHOD handle_custom_fill_button.
  " 1. 更新绑定的内表数据(示例:填充第一行的COLUMN1字段)
  DATA(ls_data) = go_alv_grid->get_table_for_first_display( )->get_data( ).
  READ TABLE gt_alv_data INTO ls_data INDEX 1.
  ls_data-column1 = '填充内容'.
  MODIFY gt_alv_data FROM ls_data INDEX 1.

  " 2. 软刷新ALV,同步界面且不触发校验
  go_alv_grid->refresh_table_display(
    EXPORTING
      i_soft_refresh = abap_true
  ).

  " 3. 标记ALV数据为已修改(让CHECK_CHANGED_DATA能识别变更)
  go_alv_grid->set_modified( abap_true ).
ENDMETHOD.

2. 配置ENTER键的功能码

  • 打开屏幕对应的GUI状态(SE41),在功能键设置中,将ENTER键映射为自定义功能码(例如ENTR);
  • 确保该功能码在GUI状态的“功能码”列表中存在,且未被其他逻辑占用。

3. 在USER_COMMAND中触发校验

捕获ENTER键的功能码,主动调用CHECK_CHANGED_DATA触发DATA_CHANGED事件:

METHOD handle_user_command.
  CASE e_ucomm.
    WHEN 'ENTR'. " ENTER键的功能码
      " 强制ALV检查数据变更,触发DATA_CHANGED事件
      DATA(lv_changed) = abap_false.
      go_alv_grid->check_changed_data(
        IMPORTING
          e_valid = lv_changed
      ).
      " 若校验不通过,可在此处理后续逻辑(如提示)
      IF NOT lv_changed.
        MESSAGE '数据校验失败' TYPE 'E'.
      ENDIF.
    WHEN OTHERS.
      " 其他功能码处理
  ENDCASE.
ENDMETHOD.

4. DATA_CHANGED事件处理校验逻辑

在DATA_CHANGED事件的处理方法中,实现数据校验逻辑,仅当ENTER触发时执行(可通过全局标志区分):

DATA gv_enter_triggered TYPE abap_bool.

METHOD handle_data_changed.
  " 仅处理ENTER触发的校验
  IF gv_enter_triggered = abap_true.
    " 遍历变更的单元格,执行校验
    LOOP AT er_data_changed->mt_mod_cells INTO DATA(ls_mod_cell).
      READ TABLE gt_alv_data INTO DATA(ls_data) INDEX ls_mod_cell-row_id.
      " 示例校验:字段长度不能超过10
      IF strlen( ls_data-(ls_mod_cell-fieldname) ) > 10.
        er_data_changed->add_protocol_entry(
          EXPORTING
            i_msgid = 'ZMSG'
            i_msgno = '001'
            i_msgty = 'E'
            i_row_id = ls_mod_cell-row_id
            i_fieldname = ls_mod_cell-fieldname
        ).
      ENDIF.
    ENDLOOP.
    " 重置标志
    gv_enter_triggered = abap_false.
  ENDIF.
ENDMETHOD.

" 同时在USER_COMMAND的ENTR分支中设置标志
METHOD handle_user_command.
  CASE e_ucomm.
    WHEN 'ENTR'.
      gv_enter_triggered = abap_true.
      go_alv_grid->check_changed_data( IMPORTING e_valid = DATA(lv_changed) ).
      " ... 其他逻辑
  ENDCASE.
ENDMETHOD.

关键说明

  • SET_MODIFIED( abap_true ):标记ALV数据为已修改,确保CHECK_CHANGED_DATA能识别到变更;
  • CHECK_CHANGED_DATA:强制触发DATA_CHANGED事件,是实现“ENTER触发校验”的核心方法;
  • 全局标志gv_enter_triggered:用于区分DATA_CHANGED事件是否由ENTER键触发,避免其他场景(如单元格手动编辑后失焦)的干扰。

内容的提问来源于stack exchange,提问作者Cutter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:25:04