ALV 选择框勾选不更新
一、需求:ALV新增一个选择框字段
在ALV上加一列"末道工序",可勾选,勾了之后带进建单逻辑。
代码长这样:
mac_fill_fcat 'ZLASTPROCESS' TEXT-269 '2' 'X' '' 'X' '' ''. "末道工序 * 字段名 标题 长度 edit hotspot checkbox ref_f ref_t事件那边也齐活:
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'的分支也写好了:
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宏里有这么一段
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还能兜底把值捞回来。两者同时失效,说明问题在前端渲染层面,不要再去后端事件逻辑里找了。