☰
【ABAP】介绍ALV 网格控件(CL_GUI_ALV_GRID)中几个常用事件
2026/10/14 1:02:57 网站建设 项目流程

目录

前言

一、data_changed 数据变更事件

核心能力与常用方法

(1)获取所有被修改过的单元格清单(pr_data->mt_mod_cells)

a. 是什么

b. 关键字段(最重要3个)

c. 作用

(2)取最新编辑值(pr_data->get_cell_value)

a. 是什么

b. 入参出参

c. 作用

(3)ALV 单元格级消息提示(add_protocol_entry)

a. 是什么

b. 示例代码

c. 参数详细说明

(4)标准函数检查字符串是否为数字

a. 是什么

b. 完整代码

c. 参数说明

二、data_changed_finished 数据变更事件

三、handle_hotspot_click 单击热点事件

a. 前置条件

b. 实现案例:

四、handle_onf4 自定义搜索帮助事件

a. 事件作用

b. 事件定义

c. 方法实现

五、handle_toolbar 工具栏定制事件

a. 事件作用

b. 动态工具栏按钮示例

c. 动态刷新工具栏

六、handle_user_command 用户功能码事件

a. 事件定位

b. 最佳实践

c. 实现案例

七、handle_double_click 双击事件

a. 事件作用

b. 参数说明

c. 代码示例


前言

在 OO ALV 开发中,CL_GUI_ALV_GRID基于 SAP Control Framework 采用「事件驱动 + 回调处理」的交互模式:用户在网格上执行编辑、点击、按钮触发等操作时,ALV 实例会抛出对应事件(如data_changed、 handle_modify、 hotspot_click),我们通过自定义事件接收类绑定处理方法,即可实现各类业务逻辑。

一、 data_changed 数据变更事件

用户修改单元格内容、回车 / 切走焦点后立刻触发(编辑过程中实时触发)。

CLASS lcl_event_receiver DEFINITION. PUBLIC SECTION. METHODS data_changed FOR EVENT data_changed OF cl_gui_alv_grid IMPORTING er_data_changed e_onf4 e_onf4_before e_onf4_after e_ucomm. ENDCLASS. "LCL_EVENT_RECEIVER DEFINITION * CLASS lcl_event_receiver IMPLEMENTATION * 定义方法 * ----------------------------------------------------------------------* CLASS lcl_event_receiver IMPLEMENTATION. METHOD data_changed. PERFORM handle_data_changed USING er_data_changed. ENDMETHOD. ENDCLASS. "LCL_EVENT_RECEIVER IMPLEMENTATION
核心参数说明
er_data_changed变更协议对象,类型为CL_ALV_CHANGED_DATA_PROTOCOL,是所有校验操作的入口
e_onf4本次事件由 F4 搜索帮助触发时为ABAP_TRUE,可用于区分触发来源
e_ucomm触发事件的功能码,例如回车对应ENTER

核心能力与常用方法

(1)获取所有被修改过的单元格清单(pr_data->mt_mod_cells)

a. 是什么

系统标准内表 LVC_T_MODI,记录所有被修改的单元格明细,是遍历校验的数据源。

b. 关键字段(最重要3个)
  • row_id:ALV 界面行唯一ID(关键定位字段)
  • fieldname:被修改的字段名
  • tabix:对应ALV内表真实行号
c. 作用

用于循环遍历所有改动单元格,性能高。

FORM handle_data_changed USING pr_data TYPE REF TO cl_alv_changed_data_protocol. LOOP AT pr_data->mt_mod_cells INTO DATA(ls_mod). "被修改单元格清单内表 * 逐行处理每个修改的字段 READ TABLE gt_alv ASSIGNING <gfs_alv> INDEX ls_mod-row_id. "ALV 界面行唯一ID IF sy-subrc = 0. ... ENDIF. ENDLOOP. ENDFORM.

(2)取最新编辑值(pr_data->get_cell_value)

a. 是什么

ALV 标准方法,专门用来读取界面刚修改、还没刷新到内表的新值。

  • 直接读取内表 → 获取旧值
  • 调用 get_cell_value → 获取用户最新输入值
b. 入参出参
  • i_row_id:mt_mod_cells-row_id
  • i_fieldname:mt_mod_cells-fieldname
  • e_value:返回界面最新输入值
" 单单元格取值 CALL METHOD pr_data->get_cell_value EXPORTING i_row_id = ls_mod-row_id i_fieldname = ls_mod-fieldname IMPORTING e_value = DATA(lv_new_value).
c. 作用

ALV 回调事件中,主内表 gt_alv 里还是旧值!peri

只要在 DATA_CHANGED 事件里:

  • 直接读内表 = 旧值
  • 调用 get_cell_value = 用户刚输入的新值

与上面第一条中获取哪些单元格修改过搭配使用:

FORM handle_data_changed USING pr_data TYPE REF TO cl_alv_changed_data_protocol. LOOP AT pr_data->mt_mod_cells INTO DATA(ls_mod). * 逐行处理每个修改的字段 READ TABLE gt_alv ASSIGNING <gfs_alv> INDEX ls_mod-row_id. IF sy-subrc = 0. "封装写法 begin PERFORM sub_get_cell_data USING ls_mod-fieldname "被修改的字段名 pr_data "修改单元格清单 ls_mod-row_id "ALV 界面行唯一ID CHANGING lv_tsl. "用户修改的值 "封装写法 end ENDIF. ENDLOOP. ENDFORM. FORM sub_get_cell_data USING VALUE(p_value) pr_data TYPE REF TO cl_alv_changed_data_protocol VALUE(pv_id) CHANGING pc_value. CALL METHOD pr_data->get_cell_value EXPORTING i_row_id = pv_id i_fieldname = p_value IMPORTING e_value = pc_value. ENDFORM.

(3)ALV 单元格级消息提示(add_protocol_entry)

a. 是什么

该方法是 CL_ALV_CHANGED_DATA_PROTOCOL 标准方法,专属 DATA_CHANGED 事件,用于给指定编辑单元格挂载单元格级警告/错误提示,精准定位报错位置。

b. 示例代码
CALL METHOD pr_data->add_protocol_entry EXPORTING i_msgid = '00' i_msgty = 'W' i_msgno = '001' i_msgv1 = '输入的批号已在工厂打印,请注意包号' i_fieldname = ls_mod-fieldname i_row_id = ls_mod-row_id.
c. 参数详细说明
  • i_msgid:消息类,00为系统通用基础消息类,搭配通用消息号可自定义文本
  • i_msgty:消息类型,核心区分业务逻辑;W(Warning 黄色警告):仅提示,不拦截数据保存,可正常提交;E(Error 红色报错):单元格标红,强制拦截数据保存,必须修改后才能提交;I(信息提示):终止程序(ALV编辑场景几乎不用)
  • i_msgno:消息编号,配合00通用消息类,用于承载自定义提示文本
  • i_msgv1:自定义提示文案,界面最终展示给用户的提示内容
  • i_fieldname:绑定报错字段,精准挂载到用户当前编辑的字段上
  • i_row_id:绑定报错行,精准定位到用户当前编辑的ALV行

(4)标准函数检查字符串是否为数字

a. 是什么

该函数是SAP标准工具函数,用于清洗字符字段、校验纯数值内容,专门解决 CHAR 字段带空格、隐形字符、无法数值判断的问题

b. 完整代码
CALL FUNCTION 'IF_CA_MAKE_STRING_NUMERICAL' EXPORTING input_string = 【待校验字符串】 EXCEPTIONS not_numerical = 1. IF sy-subrc <> 0. " 包含非数字字符,校验不通过 ENDIF.
c. 参数说明
  • input_string:需要校验的字符型字段
  • EXCEPTIONS-not_numerical:存在非数字内容时触发
  • sy-subrc = 0:纯数字(含空格)合法
  • sy-subrc = 1:非法字符,不是纯数字

注意❌:DATA_CHANGED 内禁止直接调用refresh_table_display,会导致事件递归触发引发程序 Dump,刷新操作请放到 DATA_CHANGED_FINISHED 中执行。

二、 data_changed_finished 数据变更事件

DATA_CHANGED_FINISHED 是 ALV 网格在用户完成所有单元格编辑后触发的事件,用于统一处理所有修改过的数据,常配合 ET_GOOD_CELLS 参数逐行检查并响应数据变更。

CLASS lcl_event_receiver DEFINITION. PUBLIC SECTION. CLASS-METHODS: handle_finished FOR EVENT data_changed_finished OF cl_gui_alv_grid IMPORTING e_modified et_good_cells. ENDCLASS. CLASS lcl_event_receiver IMPLEMENTATION. METHOD handle_finished. CHECK e_modified EQ abap_true."已修改 READ TABLE et_good_cells ASSIGNING FIELD-SYMBOL(<ls_cell>) INDEX 1. CHECK: sy-subrc EQ 0. READ TABLE gt_out ASSIGNING FIELD-SYMBOL(<ls_out>) INDEX <ls_cell>-row_id. ...数据处理逻辑 ENDMETHOD. ENDCLASS.
核心参数说明
e_modified布尔值,本次操作是否有数据被修改
et_good_cells校验通过的单元格清单,结构同mt_mod_cells
et_bad_cells校验不通过的单元格清单

这是项目中最常见的需求:用户输入物料号自动带出描述、单位,输入供应商自动带出名称,输入采购订单自动控制字段可编辑性。

三、 handle_hotspot_click 单击热点事件

a. 前置条件

字段目录中对应字段的hotspot属性需设为'X',字段会显示为蓝色带下划线的链接样式。

CLASS lcl_event_receiver DEFINITION. PUBLIC SECTION. CLASS-METHODS handle_hotspot_click FOR EVENT hotspot_click OF cl_gui_alv_grid IMPORTING e_row_id e_column_id es_row_no. ENDCLASS.
参数名类型描述
e_row_idint4当前点击行的索引。
e_column_idlvc_s_fcat一个包含当前点击列信息的结构。最常用的组件是e_column_id-fieldname,它包含了被点击字段的名称。
es_row_nolvc_s_roid当前点击行的行信息结构。通常包含es_row_no-row_id用于读取内表中的行。
b. 实现案例:
METHOD handle_hotspot_click. " 转换为内表物理行号,兼容排序、筛选场景 DATA(lv_tabix) = go_alv->get_table_line_index( i_row_id = es_row_no-row_id ). CHECK lv_tabix > 0. READ TABLE gt_stock ASSIGNING FIELD-SYMBOL(<ls_stock>) INDEX lv_tabix. CHECK sy-subrc EQ 0. " 根据点击字段执行不同逻辑 CASE e_column_id-fieldname. WHEN 'EBELN'. " 采购单号跳转ME23N SET PARAMETER ID 'BES' FIELD <ls_stock>-ebeln. CALL TRANSACTION 'ME23N' AND SKIP FIRST SCREEN. WHEN 'MATNR'. " 物料号弹出详情 PERFORM frm_show_material_detail USING <ls_stock>-matnr. ENDCASE. ENDMETHOD.

四、 handle_onf4 自定义搜索帮助事件

a. 事件作用

覆盖标准搜索帮助,实现自定义的取值逻辑,例如根据当前行物料限定可选批号范围。

b. 事件定义
CLASS lcl_event_receiver DEFINITION. PUBLIC SECTION. CLASS-METHODS handle_onf4 FOR EVENT onf4 OF cl_gui_alv_grid IMPORTING e_fieldname e_fieldvalue es_row_no er_event_data et_bad_cells e_display. ENDCLASS.
c. 方法实现
METHOD handle_onf4. CASE e_fieldname. WHEN 'CHARG'. PERFORM frm_open_shlp_dialog USING es_row_no-row_id. ENDCASE. " 标记事件已处理,阻止标准搜索帮助叠加弹出 er_event_data->m_event_handled = abap_true. ENDMETHOD.

五、 handle_toolbar 工具栏定制事件

a. 事件作用

ALV 工具栏渲染前触发,用于新增自定义按钮、隐藏标准按钮、动态控制按钮显隐。

按钮类型说明:

butn_type 值类型说明
0普通按钮最常用,单击触发对应功能码
1菜单按钮带下拉箭头,可挂载子菜单
2分隔线垂直分隔线,用于按钮分组
3空白分隔空白占位,拉开按钮间距
b. 动态工具栏按钮示例

可以根据不同业务模式(新增 / 修改 / 删除 / 查询)动态显示不同按钮,也可以为分割成不同 alv 的屏幕设置工具按钮:

CLASS lcl_event_receiver DEFINITION. PUBLIC SECTION. CLASS-METHODS: "自定义 ALV 工具栏按钮 handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid IMPORTING sender e_object. ENDCLASS. CLASS lcl_event_receiver IMPLEMENTATION. "设置工具栏 METHOD handle_toolbar. " 移除本地标准按钮 DELETE e_object->mt_toolbar WHERE function CS |LOCAL|. DATA: ls_toolbar TYPE stb_button. CASE sender. WHEN go_alv1. "采购收货ALV1 专属按钮 APPEND VALUE stb_button( butn_type = 3 ) TO e_object->mt_toolbar. APPEND VALUE stb_button( function = 'CRE' text = TEXT-004 ) TO e_object->mt_toolbar. APPEND VALUE stb_button( function = 'DEL' text = TEXT-008 ) TO e_object->mt_toolbar. WHEN go_alv2. "生产投料ALV2 只显示保存 APPEND VALUE stb_button( butn_type = 3 ) TO e_object->mt_toolbar. APPEND VALUE stb_button( function = 'SAVE' text = TEXT-007 ) TO e_object->mt_toolbar. WHEN go_alv3. "生产入库ALV3 新增+导出 APPEND VALUE stb_button( butn_type = 3 ) TO e_object->mt_toolbar. APPEND VALUE stb_button( function = 'CRE' text = TEXT-004 ) TO e_object->mt_toolbar. APPEND VALUE stb_button( function = 'EXPORT' text = '导出入库数据' ) TO e_object->mt_toolbar. WHEN go_alv4. "销售出库ALV4 仅查询按钮 APPEND VALUE stb_button( butn_type = 3 ) TO e_object->mt_toolbar. APPEND VALUE stb_button( function = 'QUERY' text = '重新查询出库' ) TO e_object->mt_toolbar. ENDCASE. ENDMETHOD. ENDCLASS.
c.为 ALV 绑定 toolbar 事件
CREATE OBJECT go_alv1 EXPORTING i_parent = go_cc_alv1. SET HANDLER lcl_event_receiver=>handle_toolbar FOR go_alv1.
d. 动态刷新工具栏

运行中切换模式时,调用以下方法可重新触发 toolbar 事件,更新按钮状态:

go_alv->set_toolbar_interactive( ).

六、 handle_user_command 用户功能码事件

a. 事件定位

所有自定义工具栏按钮的点击逻辑都在此事件中处理,替代传统列表 ALV 的 AT USER-COMMAND 块。

b. 最佳实践

方法开头必须调用check_changed_data( ),强制将界面上未回车的编辑值同步到内表,避免用户改完数据直接点按钮导致修改丢失。

c. 实现案例
METHOD handle_user_command. " 强制同步界面未保存的编辑数据,核心最佳实践 DATA(lv_valid) = go_alv->check_changed_data( ). IF lv_valid = abap_false. MESSAGE '数据校验不通过,请修正红色单元格后再操作' TYPE 'E'. ENDIF. " 处理行选中标记 PERFORM frm_mark_selection USING 01. CASE e_ucomm. WHEN 'CRE'. PERFORM frm_create. WHEN 'DEL'. PERFORM frm_delete. WHEN 'SAVE'. PERFORM frm_check. " 数据业务校验 PERFORM frm_save. " 数据保存 WHEN 'PRINT'. PERFORM frm_print_function. ENDCASE. go_alv->refresh_table_display( is_stable = VALUE lvc_s_stbl( row = abap_true col = abap_true ) ). PERFORM frm_mark_selection USING 10. ENDMETHOD.

七、 handle_double_click 双击事件

a. 事件作用

用户双击任意单元格时触发,常用于行级详情查看、事务跳转。与热点点击的选型区别:

  • 热点点击:单击触发,仅作用于指定字段,适合单据号跳转
  • 双击事件:双击触发,作用于整行任意位置,适合查看行详情
b. 参数说明
参数类型说明
senderTYPE REF TO cl_gui_alv_grid触发事件的ALV对象。通过此参数可以判断双击发生在哪一个ALV中
es_row_nolvc_s_roid包含用户双击行的行ID。后续方法使用es_row_no-row_id从内表中读取对应行的数据
c. 代码示例
CLASS lcl_event_receiver DEFINITION. PUBLIC SECTION. CLASS-METHODS: handle_double_click FOR EVENT double_click OF cl_gui_alv_grid IMPORTING sender es_row_no. ENDCLASS. CLASS lcl_event_receiver IMPLEMENTATION. METHOD handle_double_click. IF sender = go_alv1. PERFORM frm_alv1_link_alv2 USING es_row_no. ELSEIF sender = go_alv2. PERFORM frm_alv2_link_alv3 USING es_row_no. ELSEIF sender = go_alv3. PERFORM frm_alv3_link_alv4 USING es_row_no. ENDIF. ENDMETHOD. ENDCLASS.

写的不完善的地方请多包容,欢迎指正

本文会持续补充更新~

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询