关于 migrate-custom-code
migrate-custom-code 是面向 SAP 自定义代码的 S/4HANA 迁移技能,通过 ATC 检查发现问题、归类解释结果,并生成修复建议。它结合 ARC-1 的 SAP 系统访问与 mcp-sap-docs 文档检索,也可应用修复并重新验证。
主要功能
- 01运行 ATC 就绪检查
- 02按优先级和类别整理问题
- 03结合文档解释迁移发现
- 04提供 SAP Quick Fix 与代码建议
- 05应用修复并进行语法及 ATC 验证
适用场景
- 01检查单个 ABAP 对象的 S/4HANA 兼容性
- 02梳理包级迁移问题并确定优先级
- 03审阅或应用弃用 API 的替代方案
MCP 相关
技能通过 ARC-1 访问 SAP,并结合 mcp-sap-docs 查询文档;可选用 SAP Notes MCP 搜索 SAP Notes。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ arc-mcp/ arc-1 --skill migrate-custom-code安装后在 Claude Code 中输入/migrate-custom-code确认已加载。
详细介绍
迁移自定义代码
基于 ATC 的 S/4HANA 自定义代码迁移助手,可自动提供修复建议。
此技能结合 ARC-1(SAP 系统访问)和 mcp-sap-docs(文档与最佳实践),复现 SAP Joule 的“自定义代码迁移”能力。它会运行 ATC 就绪性检查,对检查结果进行分组和说明,并遵循现代 ABAP 模式生成替换代码。
智能默认值(静默应用,切勿询问)
| 设置 | 默认值 | 原因 |
|---|---|---|
| 对象类型 | 通过 SAPSearch 自动检测 | 无需让用户查找类型 |
| ATC 变体 | 系统默认值 | 省略 variant 后,ARC-1 会解析并发送 systemCheckVariant |
| 范围 | fix(说明 + 修复建议) | 最具可操作性的输出 |
| 优先级筛选 | 所有优先级(从优先级 1 错误开始) | 不遗漏任何问题,并优先修复最关键的问题 |
输入
用户提供要检查的对象或软件包(例如,ZCL_SALES_HANDLER、Z_REPORT_POSTING、ZSALES_PKG)。
只需提供对象名称。如果用户只提供对象名称,请自动检测类型,并使用默认变体和修复范围继续操作。
用户也可以选择指定:
- 对象类型(默认:通过 SAPSearch 自动检测)
- 目标版本变体(例如,
S4HANA_2023、S4HANA_READINESS;默认:系统默认值) - 范围 —
explain(仅检查结果)或fix(说明 + 修复建议;默认:fix)
步骤 1:运行 ATC 就绪性检查
ATC 注意事项(已在 S/4HANA 2023 上实时验证):
- ATC 会跳过
$TMP/ 本地对象。 对$TMP对象运行检查会解析出空对象集,并返回零条检查结果——这并不代表“代码干净”,而是“未检查”。请对可传输软件包中的对象运行 ATC。如果用户指定了$TMP代码,请说明这一点,并要求他们先将其分配到可传输软件包中。- 检查变体必须存在于系统中。
ABAP_CLOUD_READINESS是 SAP BTP ABAP / S/4HANA Cloud 上的标准名称,但本地部署系统通常提供S4HANA_READINESS_<release>(例如,S4HANA_READINESS_2023)或SAP_CLOUD_PLATFORM_DEFAULT。如果指定的变体不存在,ARC-1 会拒绝调用(SAP 会静默运行DEFAULT)——使用SAPDiagnose(action="atc_variants")列出实际名称,或省略variant,以使用系统配置的默认值。
1a. 对目标对象运行 ATC
SAPDiagnose(action="atc", type="<type>", name="<object_name>", variant="<variant>")
如果未指定变体,请先使用系统默认值运行(省略 variant 后,ARC-1 会从 ATC 自定义设置中解析 systemCheckVariant 并明确发送它——SAP 自身在 checkVariant 为空时会运行代码检查器变体 DEFAULT):
SAPDiagnose(action="atc", type="<type>", name="<object_name>")
然后,如果有就绪性变体,请建议使用(例如,S4HANA_READINESS_2023、ABAP_CLOUD_READINESS)。如果预期会被标记的代码运行后返回零条检查结果,请先确认该对象不在 $TMP 中(参见上面的注意事项)。
1b. 对软件包级别运行检查——先查找所有对象
SAPRead(type="DEVC", name="<package_name>")
这会返回软件包中的所有对象。然后逐个对象运行 ATC。对于大型软件包,请优先处理 PROG、CLAS、FUGR、FUNC 类型,因为它们通常包含最相关的迁移检查结果。
步骤 2:对检查结果进行分组和排序
将检查结果整理成结构化摘要。对于多个位置上 checkTitle 相同的检查结果,请去重。
汇总表
按优先级和类别对检查结果进行分组:
Migration Readiness Report for <object_name>
=============================================
Total findings: <N>
Priority 1 (Errors): <n>
Priority 2 (Warnings): <n>
Priority 3 (Info): <n>
| # | Priority | Check | Category | Count | Affected Objects |
|---|----------|-------|----------|-------|------------------|
| 1 | 1 | Use of obsolete statement MOVE | Syntax Change | 3 | Z_REPORT_POSTING |
| 2 | 1 | Call to released API CL_GUI_ALV_GRID | Deprecated API | 1 | Z_REPORT_POSTING |
| 3 | 2 | SELECT...ENDSELECT pattern | Performance | 5 | Z_REPORT_POSTING |
| ...
类别
将检查结果归入以下类别:
- 弃用的 API:调用在 S/4HANA 中已弃用或未发布的函数、类或方法
- 语法变更:必须替换的过时 ABAP 语句
- 语义变更:S/4HANA 中的行为差异(例如,表结构变更、字段移除)
- 性能:需要针对 S/4HANA 优化的模式
- 简化:S/4HANA 简化清单中的项目
询问用户:“你希望我说明并修复哪些检查结果?(全部 / 指定编号 / 仅错误)”
第 3 步:解释发现的问题
针对每项选定的问题,提供详细说明。
3a. 阅读受影响的源代码
SAPRead(type="<type>", name="<object_name>")
展示每项问题附近的代码上下文(包含存在问题的行及其前后几行)。
3b. 搜索文档中的迁移指南
search("<checkTitle> S/4HANA migration")
search("<deprecated_api> replacement ABAP")
针对特定的简化项目:
search("<simplification_item_id> simplification list")
3c. 搜索 SAP Notes(如果 SAP Notes MCP 可用)
sap_notes_search(q="<checkTitle>")
sap_notes_search(q="<deprecated_api> replacement")
3d. 逐项说明发现的问题
针对每项发现的问题,说明:
- 内容:问题描述及其所在位置(文件、行)
- 原因:这为什么会对 S/4HANA 造成问题(兼容性、移除、行为变更)
- 替代方案:建议使用的现代 ABAP 模式或 API
- 影响:变更的风险等级(低 = 语法替换,中 = 逻辑变更,高 = 需要重新设计)
第 4 步:生成修复方案
针对每项可修复的问题,根据文档和现代 ABAP 模式生成替换代码。
4a. 首先检查 SAP quickfix(早于 LLM 生成的修复)
针对每个问题所在位置,首先检查 SAP 是否提供原生 quickfix:
SAPDiagnose(action="quickfix", type="<type>", name="<object_name>", source="<current_source>", line=<finding_line>, column=0)
如果返回了建议:
- 将其作为 SAP 验证的修复展示(可信度高于 LLM 生成的修复)
- 如果用户选择其中一项,则应用该修复并获取精确的文本差异:
SAPDiagnose(action="apply_quickfix", type="<type>", name="<object_name>", source="<current_source>", line=<finding_line>, column=0, proposalUri="<proposal_uri>", proposalUserContent="<proposal_user_content>")
apply_quickfix返回的是带范围的文本差异,不会持久化保存。请自行将返回的差异应用到源代码中,然后通过SAPWrite(action="update")写入结果。对同一个对象应用多个修复时,每次写入后都要重新确定各项发现问题所在的行(之前的编辑会导致后续行号偏移),或者按从上到下的顺序修复。
Quickfix 是否可用取决于系统。 SAP 仅在系统安装了相应的检查内容或云化内容时提供 quickfix 建议。在未经配置的 ABAP 试用版系统,或未安装 Clean-Core 修复内容的系统中,
getFixProposals会返回[],且 ATC 发现的问题会带有hasQuickfix=false——这是预期行为,并非错误。这种情况下,直接跳过 SAP quickfix,使用 LLM 生成的修复(以下选项)即可。只有在实际返回 SAP quickfix 时,才优先使用。
让建议与发现的问题相匹配——不要盲目应用
proposals[0]。quickfix会返回适用于该源代码位置的所有建议,其中往往包括与发现的问题无关的通用重构(在 S/4HANA 2023 上进行的实时验证中,同一位置返回了“重命名”“转换为属性”“转换为导入参数”“提取局部变量”等建议)。选择name/description确实针对该问题的建议;忽略其余建议。
保存前检查 quickfix 差异。 原样传递其
userContent(包括空字符串)。仅凭/providers/refactoring/并不意味着建议不受支持。apply_quickfix返回编辑内容,但不会保存;检查受影响的对象,并在执行SAPWrite前运行语法检查。部分 SAP 建议需要额外输入,或建议使用需要修正的类型。
修复选项
针对每项发现的问题提供 4 个选项:
- 应用 — 通过 ARC-1 自动写入修复
- 显示 — 显示修改前后的差异,但不应用修复
- 跳过 — 转到下一项发现的问题
- SAP Quick Fix — 有 SAP quickfix 时应用该修复(优先于 LLM 生成的修复)
将可以一起应用的相关修复分组(例如,同一方法中的多条已弃用语句)。
常见迁移模式
生成修复方案时,请使用以下替换模式:
| 旧模式 | 新模式 | 备注 |
|---|---|---|
CALL FUNCTION '<fm>' | 类方法调用 | 在文档中查找替代类 |
SELECT...ENDSELECT | SELECT INTO TABLE + 循环 | 避免逐行处理 |
MOVE-CORRESPONDING src TO dst | dst = CORRESPONDING #( src ) | 新版 ABAP 语法 |
READ TABLE itab WITH KEY k = v | line_exists( itab[ k = v ] ) 或 VALUE #( itab[ k = v ] OPTIONAL ) | 使用表表达式 |
FORM/PERFORM | 方法调用 | 提取为类方法 |
DESCRIBE TABLE itab LINES lv_cnt | lv_cnt = lines( itab ) | 内置函数 |
CALL METHOD obj->method | obj->method( ) | 函数式调用语法 |
CREATE OBJECT obj TYPE cls | obj = NEW cls( ) | NEW 运算符 |
TRANSLATE str TO UPPER CASE | str = to_upper( str ) | 内置函数 |
| 经典数据库视图 | CDS 视图实体 | 需要重新设计 |
WRITE: / ALV 列表 | Fiori / RAP 服务 | 需要重大重新设计 |
步骤 5:应用选定的修复
5a. 应用修复
对于类中的方法级修复:
SAPWrite(action="edit_method", type="CLAS", name="<class>", method="<method>", source="<fixed_source>", transport="<transport>")
对于完整源代码更新(程序、函数):
SAPWrite(action="update", type="<type>", name="<object_name>", source="<fixed_source>", transport="<transport>")
5b. 每批修复后进行验证
SAPRead(type="SYNTAX", objectType="<type>", name="<object_name>")
如果引入了语法错误:写回原始源代码进行回滚,并报告问题。
5c. 激活
SAPActivate(type="<type>", name="<object_name>")
步骤 6:重新验证
再次运行 ATC,确认问题已解决:
SAPDiagnose(action="atc", type="<type>", name="<object_name>", variant="<variant>")
报告结果
提供最终摘要:
Migration Fix Summary for <object_name>
========================================
Findings fixed: <n>
Findings remaining: <n>
Findings needing manual fix: <n>
Fixed:
- [FIXED] Use of obsolete statement MOVE (3 occurrences)
- [FIXED] SELECT...ENDSELECT replaced with SELECT INTO TABLE
Remaining:
- [MANUAL] CL_GUI_ALV_GRID replacement requires UI redesign
- [SKIPPED] User skipped FORM/PERFORM migration
Next steps:
- Address remaining manual findings
- Run full regression tests
- Consider running ATC on dependent objects
错误处理
常见问题及修复方法
| 错误 | 原因 | 修复方法 |
|---|---|---|
| 找不到 ATC 变式 | 此系统上不存在该变式(严重错误——否则 SAP 会静默运行 DEFAULT) | 使用 SAPDiagnose(action="atc_variants") 列出实际名称,或省略 variant 以使用系统默认值 |
| 对象被其他用户锁定 | 对象正在其他位置编辑 | 告知用户,建议稍后重试或联系锁定对象的用户 |
| 修复导致新的语法错误 | 生成的替换代码不正确 | 回滚到原始源代码,显示差异,并建议手动更正 |
| 没有可用的 mcp-sap-docs | 未配置文档 MCP | 仅根据 ATC 问题文本解释发现结果,并建议用户查看 SAP Help Portal |
| 包含的对象过多 | 大型包中有 100 多个对象 | 建议按子包或对象类型拆分为较小批次 |
| ATC 未返回任何发现结果 | 对象已符合 S/4HANA 要求 | 告知用户——没有发现结果是好消息,并建议使用更严格的变式进行检查 |
| 需要传输请求,但未提供 | 对象位于可传输包中 | 应用修复前,向用户索取传输请求编号 |
备注
BTP 与本地部署的差异
- BTP:可用的 ATC 变式有限,主要用于云就绪检查。BTP 对象已使用 ABAP Cloud 语法,因此迁移重点有所不同:关注已弃用的已发布 API,而不是经典 ABAP 结构。由于 ABAP Cloud 强制采用现代模式,预计发现的问题较少。
- 本地部署:提供完整范围的 S/4HANA 就绪变式(2020、2021、2022、2023+)。经典 ABAP 对象可能存在许多问题。FORM/PERFORM、函数模块、经典报表和数据库视图是常见的迁移目标。自定义代码迁移工作清单(SCMA)可能会提供更多上下文。
Quickfix 可用性
- 许多常见 ATC 问题(例如过时语句、缺少声明、简单的语法问题)都有 SAP quickfix。
- 并非每个问题都有 quickfix。已弃用 API 的替换和架构级重新设计通常仍需要手动或由大模型指导进行重构。
此技能不执行的操作
- 不管理传输:用户负责创建和发布传输请求
- 不生成迁移档案:仅处理单个对象或单个软件包的发现项工作流;如需经过审查、已保存或可视化的软件包级档案,请使用 sap-migration-dossier
- 不创建自定义 ATC 变体:使用系统上现有的 ATC 变体
- 不迁移表结构:无法修改 DDIC 表结构(例如,为 S/4HANA 更改字段长度)
- 不执行测试:修复后不会运行回归测试;用户应手动验证,或使用 generate-abap-unit-test 技能
何时使用此技能
- 为 S/4HANA 迁移准备自定义代码时
- 检查代码是否符合 ABAP Cloud 就绪标准时
- 调查 ATC 发现项并需要解释和修复方案时
- 现代化改造旧版 ABAP 代码模式(FORM、过时语句)时
- 不适用于全新开发——新对象请使用 generate-rap-service