ALV 选择框勾选不更新
一、需求:ALV新增一个选择框字段
在ALV上加一列"末道工序",可勾选,勾了之后带进建单逻辑。
代码长这样:
abap
mac_fill_fcat 'ZLASTPROCESS' TEXT-269 '2' 'X' '' 'X' '' ''. "末道工序
* 字段名 标题 长度 edit hotspot checkbox ref_f ref_t
事件那边也齐活:
abap
CALL METHOD grid1->register_edit_event
EXPORTING i_event_id = cl_gui_alv_grid=>mc_evt_enter.
CALL METHOD grid1->register_edit_event
EXPORTING i_event_id = cl_gui_alv_grid=>mc_evt_modified.
SET HANDLER g_alv_application->handle_data_changed FOR grid1.
SET HANDLER g_alv_application->handle_data_changed_finished FOR grid1.
WHEN 'ZLASTPROCESS' 的分支也写好了:
abap
WHEN 'ZLASTPROCESS'.
READ TABLE it_eban INTO wa_eban INDEX wa_mod_data-row_id.
IF sy-subrc = 0.
wa_eban-zlastprocess = wa_mod_data-value.
MODIFY it_eban FROM wa_eban INDEX wa_mod_data-row_id TRANSPORTING zlastprocess.
ENDIF.
然后跑起来:点勾选框,毫无反应。
HANDLE_DATA_CHANGED 不触发;点了"生成采购订单"触发 CHECK_CHANGED_DATA,IT_EBAN-ZLASTPROCESS 还是空的。
二、初步排查
| 常见情况 | 查到什么 |
|---|---|
缺 edit = 'X' |
有 |
缺 checkbox = 'X' |
有 |
没注册 mc_evt_modified |
注册了,enter 和 modified 都注册了 |
没 SET HANDLER |
有 |
没调 CHECK_CHANGED_DATA |
调了(GRID1->CHECK_CHANGED_DATA,包在 FM_REFRESH_ALV_CHANGE 里,点按钮时先执行) |
内表字段不是 CHAR1 |
查 DD03L → DD01L:域 ZLASTPROCESS = CHAR × 1,完全合规 |
| 域有固定值被渲染成下拉框 | 查 DD07L:无固定值 |
| 单元格被样式禁用 | 布局用了 stylefname = 'CELLSTYLE',但样式表里只有 ZKGLIFNR 和 ZQY 的开关,没碰这个字段 |
三、尝试修正
发现有一段意料之外的代码:
mac_fill_fcat 宏里有这么一段
abap
DEFINE mac_fill_fcat.
it_fieldcatalog-edit = &4. "是否编辑
...
IF &4 = 'X' AND &7 = ''. "edit='X' 且没给 ref_field
it_fieldcatalog-f4availabl = 'X'. "就自动打上 F4
ENDIF.
而我写的时候偷懒没有加ref_field: 'ZLASTPROCESS' TEXT-269 '2' 'X' '' 'X' '' '' ------ edit='X'、ref_field 为空,必然命中。
给普通文本框挂 F4 无所谓(反而方便),但复选框单元格挂上 F4 之后,前端不再按"可勾选的复选框"来渲染。后果是:
点击单元格时,前端既不切换勾选状态,也不把它登记为"待提交的变更"。
于是后端两个通道同时落空:
DATA_CHANGED事件永远不会来(前端根本没产生变更事件);CHECK_CHANGED_DATA也无变更可取 ------ 它取的是"前端缓冲区里的待提交修改",而缓冲区是空的。
这也正好解释了一个细节 :如果只是"事件没注册",CHECK_CHANGED_DATA 是能兜住的(先把值捞回内表,再统一处理);正因为连它都捞不到,才说明问题出在前端压根没把这次点击当成一次修改。
四、复盘:几条值得抄下来的经验
1. 勾选框别挂 F4。
edit='X' + checkbox='X' 是必要条件,但不充分。如果生成 fieldcat 的宏有"edit='X' 且无 ref_field 就自动补 F4"这类逻辑,勾选框列会被误伤。这类宏很常见,值得回头查一遍自己的项目。
2. 判断一个勾选框"是不是真走事件通道",看它有没有 hotspot。
带 hotspot='X' 的勾选框,通常是靠 HOTSPOT_CLICK + 手工翻转 + 刷新实现的。它能用,但不代表 checkbox-edit 通道是通的。用错对照案例,会让你在错误的方向上排除掉正确的怀疑对象。
3. CHECK_CHANGED_DATA 捞不到值,是"前端没把这次点击当修改"的信号。
如果只是事件注册漏了,CHECK_CHANGED_DATA 还能兜底把值捞回来。两者同时失效,说明问题在前端渲染层面,不要再去后端事件逻辑里找了。