在 SAP GUI 的 ALV 时代,很多业务按钮都很直观。采购员在清单上筛出一批采购订单,点一下「全选」,再点「批量确认」。仓库同事在库存列表里过滤出某个工厂、某个物料组、某个日期范围内的项目,按下「Process All」。ABAP 程序员在后台拿到的通常就是一张完整的 internal table,用户眼前看到的数据,程序内存里也在,按钮事件一触发,LOOP 一遍就能处理。到了 Fiori Elements List Report,这个习惯一下子变得危险起来。界面看起来还是一个列表,业务用户的直觉也还是列表,可底层已经从有状态的 SAP GUI 会话,变成了基于 HTTP 和 OData 的无状态请求。OData 本身就是建立在 HTTP 和 REST 思路上的数据访问协议,它通过标准化的 URL 查询参数表达过滤、排序、分页等语义。([OData][1]) List Report 只是在页面上呈现当前批次的数据,并不等于前端已经拥有完整结果集。这就是 「Process All」 按钮在 Fiori List Report 里最容易出问题的地方。业务上说的「全部」,常常不是数据库里的全部,也不是当前页面已经加载出来的全部,而是「用户在 filter bar 里按下 Go 以后,当前筛选条件命中的那一整批业务对象」。这个定义必须讲清楚,否则前端全选、后端全量、用户眼前的过滤结果,很容易被混成一件事。ALV 的全选和 List Report 的全选不是一回事在经典 ALV 里,程序通常已经把选择条件对应的数据读入内表。即使 ALV 使用分页显示,业务程序的内存里也经常保存着完整结果。GUI Status 上挂一个按钮,用户选择多