migrate-custom-code について
migrate-custom-code は、SAP カスタムコードの S/4HANA 移行を支援するスキルです。ATC で問題を検出・分類・説明し、ARC-1 によるシステムアクセスと mcp-sap-docs の文書検索を使って修正案を提示します。選択した変更は適用後に検証できます。
主な機能
- 01ATC による移行準備チェック
- 02優先度とカテゴリ別の検出結果整理
- 03文書に基づく移行問題の説明
- 04SAP Quick Fix とコード修正案の提示
- 05修正適用後の構文・ATC 再検証
活用シーン
- 01ABAP オブジェクトの 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 が空の場合の動作では、代わりに Code Inspector バリアント 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 のクイックフィックスを先に確認する(LLM 生成の修正より先に)
各調査結果の箇所について、まず SAP がネイティブのクイックフィックスを提供しているか確認します。
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")を使って結果を書き込みます。同じオブジェクトに複数の修正を適用する場合は、書き込みごとに各調査結果の行を再解決してください(先行する編集によって後続の行番号がずれるため)。または、上から順に修正してください。
クイックフィックスが利用できるかどうかはシステムによって異なります。 SAP がクイックフィックスの提案を提供するのは、対応するチェック/クラウド化コンテンツがシステムにインストールされている場合のみです。ABAP のトライアル環境や Clean-Core の修正コンテンツがないシステムでは、
getFixProposalsが[]を返し、ATC の調査結果にhasQuickfix=falseが付くことがあります。これは想定どおりで、バグではありません。その場合は、LLM 生成の修正(以下の選択肢)に進んでください。SAP のクイックフィックスは、実際に返された場合にのみ優先してください。
提案を調査結果に照らして選んでください。
proposals[0]を盲目的に適用しないでください。quickfixは、そのソース位置に適用可能なすべての提案を返します。その中には、調査結果と無関係な汎用的な リファクタリング が含まれることがよくあります(S/4HANA 2023 でのライブ検証では、ある位置から「Rename」、「Convert to attribute」、「Convert to importing parameter」、「Extract local variable」などが返されました)。name/descriptionが実際に調査結果に対応している提案を選び、ほかは無視してください。
保存前にクイックフィックスの差分を確認してください。
userContentは空文字列も含め、変更せずに渡してください。/providers/refactoring/だけを理由に提案を未対応と判断しないでください。apply_quickfixは保存せずに編集内容を返します。影響を受けるオブジェクトを確認し、SAPWriteの前に構文チェックを実行してください。SAP の提案には追加の入力が必要なものや、修正が必要な型を提示するものがあります。
修正の選択肢
各調査結果について、次の 4 つの選択肢を提示します。
- 適用 — ARC-1 経由で修正を自動書き込みします
- 表示 — 適用せずに変更前後の差分を表示します
- スキップ — 次の調査結果に進みます
- SAP クイックフィックス — 利用可能な場合に SAP のクイックフィックス提案を適用します(LLM 生成の修正より優先)
まとめて適用できる関連修正(たとえば、同じメソッド内にある複数の非推奨ステートメント)をグループ化してください。
一般的な移行パターン
修正を生成する際は、次の置換パターンを使用してください。
| 旧パターン | 新パターン | 備考 |
|---|---|---|
CALL FUNCTION '<fm>' | クラスメソッドの呼び出し | ドキュメントで置換先のクラスを確認してください |
SELECT...ENDSELECT | SELECT INTO TABLE +ループ | 1 行ずつの処理を避けます |
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 ) | 組み込み関数です |
| 従来の DB ビュー | 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 構文を使用しているため、移行の焦点は異なります。従来の ABAP 構文ではなく、非推奨となったリリース済み API が対象です。ABAP Cloud では最新のパターンが強制されるため、検出事項は少なくなると予想されます。
- オンプレミス:S/4HANA 対応バリアント(2020、2021、2022、2023 以降)が幅広く利用できます。従来の ABAP オブジェクトでは、多くの検出事項が発生する可能性があります。FORM/PERFORM、関数モジュール、従来のレポート、DB ビューは、よくある移行対象です。Custom Code Migration Worklist(SCMA)から追加の情報を得られる場合があります。
クイックフィックスの利用可否
- SAP のクイックフィックスは、よくある ATC 検出事項(たとえば、廃止された文、宣言の不足、単純な構文の問題)に対して利用できます。
- すべての検出事項にクイックフィックスがあるわけではありません。非推奨 API の置換やアーキテクチャレベルの再設計には、通常、手動または LLM の支援によるリファクタリングが引き続き必要です。
このスキルでできないこと
- トランスポート管理は行いません:トランスポートリクエストの作成とリリースはユーザー自身で行ってください
- 移行ドシエは作成しません:1つのオブジェクト、または1つのパッケージの検出結果のワークフローを扱います。レビュー済み、保存済み、またはパッケージ全体を対象とするビジュアル形式のドシエには、sap-migration-dossier を使用してください
- カスタム ATC バリアントは作成しません:システム上にある既存の ATC バリアントを使用します
- テーブル構造の移行は行いません:DDIC テーブル構造は変更できません(S/4HANA 向けのフィールド長の変更など)
- テストは実行しません:修正後の回帰テストは実行しません。ユーザー自身で検証するか、generate-abap-unit-test スキルを使用してください
このスキルを使用する場面
- S/4HANA 移行に向けてカスタムコードを準備する場合
- コードが ABAP Cloud 対応基準を満たしているか確認する場合
- ATC 検出結果を調査し、説明と修正案が必要な場合
- レガシー ABAP コードのパターン(FORM、廃止されたステートメントなど)をモダナイズする場合
- グリーンフィールド開発には使用しないでください。新しいオブジェクトには generate-rap-service を使用してください