业务菜单在升级后一夜之间消失,这可能是我见过最让 SAP 项目组夜不能寐的场景。系统升级本身往往顺风顺水,真正把人逼疯的,是升级完成后用户打开 Fiori 启动板,发现以前常用的磁贴少了一半,或者角色里挂着的 Business Catalog 全部显示为灰色。这个问题的背后,就是标题里提到的“废弃 Business Catalog 的接管与治理”。
这篇文章我不会和你绕概念,直接按生产环境实操的顺序来讲。适合正在做 S/4HANA 升级或 Fiori 前端升级的 BASIS、权限顾问、Fiori 开发人员,以及被升级后遗症困住的运维团队。看完全文,你可以直接拿着里面的核查思路和代码去你的系统里做一次目录体检。
1. 为什么升级后 Business Catalog 会“废弃”
1.1 先分清 Fiori Catalog、Group 和 PFCG 角色之间的关系
很多项目出问题,是从一开始就把 Catalog、Group、PFCG 角色这几个概念混在一起。要理解目录废弃后的接管,必须先把这个三层结构掰清楚。
- Business Catalog(业务目录):Fiori 里的“应用分类目录”,它决定了一个应用能不能被用户在技术上看到和访问到,也关联了后端的 OData 服务授权。
- Group(组):启动板上用户实际看到的磁贴分组,类似于手机桌面上的文件夹。Group 本身不含权限,只负责展示。
- PFCG 角色:通过角色把 Catalog 挂载给用户。用户登录后,启动板根据角色分配的 Catalog 渲染磁贴,根据 Catalog 里的配置去校验应用访问权限。
很多公司升级之后出现“磁贴消失”,第一反应是查门户配置,查网络层,查启动板本身,但最后发现根因都落在 Catalog 这一层。Catalog 在 PFCG 角色里被引用,升级后 SAP 标准功能把旧的目录标记为废弃,角色里的引用还在,但启动板不再渲染废弃目录里的应用。这种问题不深入到 Catalog 生命周期里,根本无法找到真正答案。
1.2 升级路径里 Catalog 的生命周期变化
Business Catalog 不是永恒不变的主数据。每升级一个支持包,或者从 ECC 迁移到 S/4HANA,SAP 都会同步发布一份新的应用清单,里面会标注哪些 Catalog 处于“激活”“推荐”“废弃”状态。
以 S/4HANA 升级为例,大量旧 ECC 时代的功能被新 Fiori 应用替代,相应的目录编号也会有变化。比如物料管理模块,以前挂在旧 MM 目录里的功能,升级后可能被新的SAP_BCR_MM_...系列目录收纳,旧目录虽然还存在系统里,但功能上已经被新目录全面替代。如果你不主动把角色里的旧目录引用替换掉,用户看到的启动板就会停留在旧时代,甚至某些应用因为 OData 服务版本冲突,直接报错无法打开。
更隐蔽的情况是系统里同时存在新旧两套目录。比如 Fiori 前端服务器升了一个版本,Test 环境验证时可能没发现问题,因为角色同时挂了新旧目录,用户还能访问。但生产环境做严格目录清理时,旧目录一旦被置为废弃,所有只挂旧目录的角色菜单立刻失效。这类问题影响面往往覆盖几十甚至上百个角色,处理起来压力非常大。
1.3 升级后“废目录”出现的三种典型现象
我在项目里碰到过实际表现不同的废弃目录问题,基本可以归纳成三类。
第一种是启动板磁贴直接消失。用户刷新 FLP 后,整个分组的磁贴不见了,但角色授权查询里仍然能看到相关对象。这种情况通常是 Catalog 的状态已经从可用变为废弃,启动板不再对它进行渲染。
第二种是磁贴在但点击报错。应用图标存在,打开后提示 OData 服务无法启动,或者提示应用不属于当前 Fiori 启动板框架。这种情况多半是新版本前端框架不再支持旧目录引用的某些应用注册信息。
第三种是角色同步失败。PFCG 修改角色后执行同步,系统报错要求先处理废弃目录。这类错误最直接,因为它会阻塞整个权限修改流程,导致权限顾问无法交付业务部门的需求。
很多人问过我:为什么升级前没办法提前发现?其实是可以的,只是很多项目在升级方案里根本没有把目录治理作为独立工作包。目录清理这件事看起来不难,实际却横跨 BASIS、权限、Fiori 开发、业务线多个领域,没有明确负责人,升级一结束,矛盾自然集中爆发。
2. 接管思路与方案选型
2.1 接管到底要接管什么
用一个更生活化的理解方式来解释:Business Catalog 相当于一屋子功能钥匙,PFCG 角色相当于员工的工牌,升级之后这间屋子要换新锁,工牌上的钥匙码不匹配了。接管要做的不是把旧钥匙重新打磨,而是把工牌上绑定的钥匙列表同步成新钥匙码。
所以接管的核心动作有两个。第一,把旧目录里仍然有业务价值的应用映射到新目录;第二,把 PFCG 角色中旧目录的引用替换成新目录的引用。如果只是把目录删掉,或者把旧目录强制拉回来,等于把风险埋到了下一个支持包升级周期。
还要注意一个很容易被遗忘的点:目录接管不只是菜单层面的接管,还包含权限层面的接管。某些旧目录里嵌了对事务代码的授权,换到新目录后如果新目录的权限对象配置不一致,用户虽然看得到磁贴,进到应用里却会被权限拒绝弹窗挡在门外。
2.2 先确认接管边界
动手之前必须先画清边界,否则批量替换时很容易误伤。
一份完整的接管清单至少包含四项信息:旧目录编号、旧目录里的应用清单、新目录编号、新目录里对应的应用清单。这里我建议不要凭经验拍脑袋,而是要按模块拆分,比如财务、物料、销售、生产各出一张映射表,由各模块业务关键用户确认功能确实等价。
另一个边界条件是区分“纯菜单目录”和“权限相关目录”。有些目录只是为了让启动板显示磁贴,里面的应用不涉及独立权限分配;有些目录本身关联了 OData 服务授权范围。处理后者时必须做单独的权限比对,确认替换后目标用户的权限范围没有缩小。
我见过一个项目,把物料管理的旧目录批量替换成新目录后,采购员发现下载采购订单报表导出功能不能用了,因为新目录里缺少旧目录设置的文件下载权限节点。这就是边界没有提前划清楚的典型代价。
2.3 三种接管方案的对比
接管方案没有绝对好坏,关键看你的系统阶段和团队资源。我常用三种做法:
| 方案 | 适用场景 | 优点 | 风险 |
|---|---|---|---|
| 方案A:新建中间目录,再批量替换角色引用 | 目录体系比较乱,新旧版本混用 | 能在测试环境完整验证再切生产 | 需要额外维护一套“过渡”目录 |
| 方案B:直接改旧目录的应用清单 | 旧目录数量少,应用变动小 | 操作路径最短,可快速恢复服务 | 后续升级还会再次失效,治标不治本 |
| 方案C:完全按新标准目录重建角色 | 正好赶上权限角色体系重构 | 彻底摆脱历史包袱,结构最干净 | 工作量大,业务验证周期长 |
如果是大版本升级,比如 ECC 迁 S/4HANA,我推荐方案A,用一个中间目录完成过渡,等 SIT 和 UAT 全部通过后再切到最终标准目录。如果你只是 Fiori 平滑升级,方案C更符合长期治理目标,因为角色重构和升级窗口重叠时,管控效率最高。
3. 接管前数据核查实操
3.1 找出所有引用废弃目录的角色清单
无论选哪种方案,第一步都是先搞清楚哪些 PFCG 角色挂了废弃目录。在 SAP 里,角色和权限数据存在AGR_*系列授权表中。要查角色里挂载的目录引用,核心是AGR_TCODES这张表,它保存了角色关联事务代码和 Fiori 目录的映射记录。
用 SE16N 打开AGR_TCODES,按角色名输入查询条件,就可以看到每个角色引用的 TCODE / 目录标识。不要只查一个角色,要把AGR_NAME留空,用TCODE的关键字去匹配废弃目录编号,一次性拉出所有受影响的角色。实际操作中,我习惯先在 SE11 里看TSTC或目录相关视图确认废弃目录在数据表中的存储格式,避免用错匹配字段。
如果你用的系统版本支持 CDS 查询视图,也可以用 SE38 写一个简单的 ABAP 报表来批量导出。查询逻辑大约是这样:
PARAMETERS: p_cat TYPE agr_tcodes-tcode OBLIGATORY. DATA: lt_agr TYPE TABLE OF agr_tcodes, ls_agr TYPE agr_tcodes. SELECT agr_name object tcode FROM agr_tcodes INTO CORRESPONDING FIELDS OF TABLE lt_agr WHERE tcode EQ p_cat. IF sy-subrc EQ 0. LOOP AT lt_agr INTO ls_agr. WRITE: / ls_agr-agr_name, ls_agr-object, ls_agr-tcode. ENDLOOP. ELSE. WRITE: / '未找到引用该目录的角色'. ENDIF.这套逻辑虽然发布为多个版本的系统都能跑,但建议你在开发机先验证AGR_TCODES的字段内容,特别是TCODE字段在不同版本里到底存的是目录编号还是内部生成的动作标识。因为有的升级场景里,目录引用会保存到AGR_FUNCS或其他扩展表中,没有统一规律。
3.2 摸清旧目录里的应用清单
拿到角色清单后,下一步是打开旧目录本身,看它里面到底有哪些应用。Fiori 目录的配置通常会持久化在/UI2/前缀的存储表里,包括目录头、目录分配的应用、应用参数等。
实践中我会在 SE16N 里查目录应用分配表,把旧目录编号带入条件,导出所有应用 ID。这一步的目的不是看应用名称,而是要和最新标准目录做差异比对。SAP 的标准升级指南或者SF01应用库资料里,通常会有一张“旧目录到新目录推荐映射表”,拿着你导出的清单去对照,就能发现哪些应用在新目录里完全对应,哪些应用在新目录里已经不存在。
关于这一环节,再提醒一个容易翻车的地方:千万不能用 Excel 直接对应用 ID 做 VLOOKUP。因为系统里可能有多个应用 ID 相同但应用类型不同的记录,比如同为显示类应用,官方版和增强版 ID 不同。你要结合应用描述、组件包、OData 服务名称综合判断。
3.3 核查权限对象差异
目录替换最容易被遗漏的就是权限对象比对。旧目录里的应用,可能在角色生成时自动带上了某些权限对象,而新目录没有继承这些配置。你批量替换角色之后,菜单功能没问题,但用户执行操作时会报权限不足。
核查方法是:在 PFCG 里分别打开新旧目录所属的角色,用“比较角色”功能查看权限差异。更细的做法是进入SUIM,按目录对应的权限对象做一次用户权限快照,对比替换前后差异。
这个环节我给的建议是:一次对比跑完所有核心用户。如果用户量太大,按部门抽取业务代表账号,覆盖采购、销售、财务、仓库四条主链路,基本就能把权限差异扫出来了。权限差异处理完成后,再启动角色批量替换,遗留问题和返工量会少非常多。
4. 批量迁移与脚本级操作
4.1 把角色引用从旧目录切到新目录
目录清单和权限差异确认完,就开始实际操作。如果你走的是方案A,先在 PFCG 里建立一个中间目录,目录 ID 建议遵循ZC_<模块>_<版本>_TEMP这种清晰命名。中间目录的应用清单从旧目录复制,并补齐新目录里出现的新版本应用。
角色替换不要在生产环境手工一个一个改。万幸的是,大多数替换逻辑比较简单,可以用 ABAP 报表去更新AGR_TCODES中的目录标识。下面是一个简化的更新脚本框架,实际运行时建议加传输请求范围控制:
TYPES: BEGIN OF ts_update, agr_name TYPE agr_tcodes-agr_name, tcode TYPE agr_tcodes-tcode, END OF ts_update. DATA: lt_update TYPE TABLE OF ts_update, ls_update TYPE ts_update. SELECT agr_name tcode FROM agr_tcodes INTO CORRESPONDING FIELDS OF TABLE lt_update WHERE tcode = p_old_cat. LOOP AT lt_update INTO ls_update. ls_update-tcode = p_new_cat. MODIFY agr_tcodes FROM ls_update. ENDLOOP. IF sy-subrc = 0. COMMIT WORK. ENDIF.这个脚本只用在你确认过目标字段没有其他依赖的情况下。说实话,在真实项目里我不建议直接用 ABAP 修改权限表,因为AGR_TCODES是权限角色的核心持久层,动了它之后,连接 PMCG 的动作会出现缓存不一致。更稳妥的方式是,批量导出受影响的角色清单,在测试环境用自动化的角色复制工具生成新角色,再执行 PFCG 同步。
如果领导层给定的人力有限,必须用脚本直改,那务必先完整备份AGR_TCODES对应的请求,并且操作只放在字符会话中执行,不要用 HTTP 任务,否则报错后回滚非常痛苦。
4.2 同步角色并验证权限一致性
角色数据改动后,不能直接用 SU01 分配结果当最终状态。每个被修改的角色,都要在 PFCG 里进入“角色”选项卡,点击“比较”并执行“完整同步”操作。这一步会把 ABAP 授权层与菜单层重新绑定,确保 Fiori 目录映射真正生效。
同步完成后,建议跑一遍SUSR_UTILITIES里标准或者项目自定义用户角色对比报表,核对同步前后的角色引用差异。系统若存在多客户端或者 Fiori 前端与后端分离架构,还要注意后端角色维护后,前端启动板用户缓存的刷新问题。必要的时候,在网关客户端用事务代码/UI2/FLP_CUS_CONF或者/UI2/INVALIDATE_CACHE清一次相关缓存,否则旧目录引用可能仍残留在用户会话缓存中。
4.3 上线切换前的回归验证
角色批量替换完成后,绝不能直接宣告结束。更安全的验证方式是,抽出几个代表业务场景的关键用户账号,逐个登录启动板,检验应用可达性。
验证项目至少包括三块:磁贴是否正常显示;应用点击后能否正常打开且不出 OData 权限报错;应用内的操作,比如单据查找、保存、打印,是否正常完成。我建议把验证脚本做成一份主数据操作清单,比如财务科做一次凭证过账、物料科做一次采购订单审批、仓库做一次收货过账,每一条验证记录签署版本和验证人。
只有这套验证全部通过,你才可以把中间目录的角色引用切到最终新目录,再走一遍同样的验证流程。
5. 上线后的日常治理机制
5.1 建立目录基线清单与定期稽核
等切换完成、系统平复之后,日常工作才算真正开始。目录治理不该是升级时临时救火,而应该是一种持续化的例行活动。
首先,把系统里所有活动目录和废弃目录拉一张基线清单,记录目录编号、所属模块、负责人、启用日期、失效日期。这张表要放在团队的共享知识库里,至少每个季度审计一次。审计时重点看那些状态为“废弃”但仍被 PFCG 角色引用的目录,及早发现新引用的产生原因,避免拖着拖着又变成下一场事故。
5.2 制定目录命名与权限维护规范
新目录的命名直接影响后续排查效率。我见过有些公司用一长串毫无规律的字母数字做目录名,出了问题根本不知道属于哪个模块。建议按这样维护:
- 自定义目录:
ZC开头,如ZC_MM_PUR_2025_10 - 标准目录:保持 SAP 官方前缀
SAP_BCR_或SAP_BRN_ - 临时过渡目录:
ZCT_开头,并明确备注有效截止日
权限维护层面,每个目录都要在描述栏写明业务负责人和技术负责人。PFCG 角色只能引用本部门和关联功能目录,禁止跨模块乱引。这个要求听起来基础,但在大型项目里,只要有一个懒角色跨了模块,后续访问分析就是一团乱麻。
5.3 把目录治理嵌入升级流程
目录治理不应该在升级确认单上只占一个小格子。更好的做法是把“目录废弃影响分析”作为升级方案评审的一项前置任务,对应负责人在升级前就拿出旧目录清单、新目录清单、差异映射以及用户验证计划。
这项前置评审里有一点心得特别重要:标准目录和自定义目录要分开评。标准目录的废弃原因多半来自 SAP 应用更迭,相对好推演;自定义目录则往往承载了项目团队的特殊改造,这些目录的权限对象、增强逻辑没人敢轻易动,需要预留更长的验证时间。
5.4 利用运营监控主动发现仓库以外的僵尸引用
常见误区是认为目录清理只需要管理 Fiori 启动板菜单。实际上,目录引用有时会藏在 Web Dynpro 配置、UI5 应用仓库、甚至移动端 App 配置文件里。只用 PFCG 查一遍,可能遗漏很大一块。
建议在运维监控中加入一条专门的检查项,定期扫描与目录相关的配置字段,将异常的废弃引用自动生成报警工单。运行一段时间后,你会发现很多顾问以为不会再用的旧目录,其实还在被某个移动端应用引用。这种自动化的主动巡检,比开一大堆项目会议管用得多。
6. 常见问题与排查技巧实录
放在末尾,是因为这些问题大多发生在切换完成之后,掌握了它们能让你未来的运维少走弯路。
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| 用户启动板磁贴消失 | 角色引用的目录被置为废弃 | 查询AGR_TCODES角色引用,换成新目录并同步 |
| 磁贴可点击但应用报错 | 新目录缺少应用注册信息或 OData 服务未激活 | 检查新目录应用清单,激活对应 OData 服务 |
| 角色比较提示目录不一致 | 旧目录在角色生成时写了硬编码映射 | 进入 PFCG 删除失效目录引用,重新添加新目录 |
| 替换目录后权限报错 | 新旧目录关联的权限对象不同 | 对比SUIM权限快照,补发缺失授权 |
| 角色同步后其他事务消失 | 目录替换过程误覆盖了非目标字段 | 核对传输请求,恢复受影响的角色数据 |
| 前端启动板仍显示旧内容 | 用户会话缓存或启动板数据缓存未刷新 | 执行 FLP 缓存清理,让用户重新登录 |
排查时有一套我很依赖的顺序:先数据后缓存,先角色后目录,先测试后生产。不要在用户环境里反复试错,你每试一次,业务部门对 IT 的信心就少一分。合理的做法是在开发环境复现问题,找到根因,把修复方案输入到传输请求,再由测试环境验证完再上生产。
关于角色同步,这里再补充一个替代技巧。某些目录引用的失效问题,可以直接通过给角色添加“启动板推荐目录”豁免参数,让某个角色忽略废弃目录校验。这个办法适合极端紧急的情况,比如生产环境某个关键用户等不了完整的传输流程。但这种做法带有很强的临时性,上线稳定后务必移除,否则会让后续权限审计出现问题。
7. 关于这次接管,我最想跟你说的一句话
项目结束后复盘,我最大的感受是:废弃 Business Catalog 的接管与治理,真正难的不是技术动作,而是把它当成一个需要跨模块协作的专项工作。很多团队把精力全压在升级包的安装进度上,留给目录治理的时间往往只有上线前最后三天。等菜单消失、权限报错、用户嗓子冒烟的时候,才意识到一头扎进了一个没有标准答案的坑。
我的经验是,最迟要在升级项目的蓝图阶段就启动目录基线梳理。不要到要切换了才开始问“哪些角色用了旧目录”,而是提前把所有角色拉出来,标记执行策略。宁可前期多花两周做映射关系,也不要上线后在用户面前上演消防队救火。
如果你现在正好接手这种升级后的目录接管项目,可以先把这篇文章里的核查脚本和验证清单保存好,拟定好节点再动手。目录清理看起来繁琐,但每一步都不会白费,因为下一次升级时,你已经拥有了一个健康得多的目录底座。