Claude Media
Claude CodeでABAPのコードを解析し、Zプログラムの仕様書を起こす

Claude CodeでABAPのコードを解析し、Zプログラムの仕様書を起こす

abapGitで落としたABAPソースをClaude Codeに読ませ、画面項目・テーブルアクセス・呼び出し先の3表に起こす手順。ファイル名の規則、読み取り専用のサブエージェント、grepでの検算、動的呼び出しの扱いまでまとめます。

ABAPのZプログラムから仕様書を起こすなら、成果物を「画面項目表」「テーブルアクセス表」「呼び出し先表」の3枚に分けると読み取りが安定します。画面項目表は、どの画面にどの入力項目があり、どのモジュールが処理するかの一覧です。テーブルアクセス表は、どのテーブルを読み、どこへ書くかを1行ずつ並べたものです。呼び出し先表は、他のプログラムやファンクションを呼ぶ箇所を集めます。

前提は、ソースをabapGitでGitに落としてあることです。SAPシステムへ直接つなぐ話ではなく、手元のファイルをClaude Codeに読ませる話に絞ります。abapGitのファイル構成の読み解き、読み取り専用のサブエージェント、grepによる検算、grepでは追えない動的呼び出しの扱いを順に示します。

abapGitのファイルは「1オブジェクト複数ファイル」になっている

abapGitのファイル名は、<オブジェクト名>.<オブジェクト種別>.<拡張子>、または <オブジェクト名>.<オブジェクト種別>.<部品名>.<拡張子> の形です。メタデータは .xml か .json、コードは .abap で、ファイル名は小文字になります。

プログラム(prog)は2つ以上のファイルに分かれます。abapGitのテスト用リポジトリにあるサンプルでは、次の3ファイルで1つのレポートが構成されています。

ファイル中身
zag_unit_test.prog.abap中身レポートのコード本体
zag_unit_test.prog.screen_2000.abap中身画面2000のフローロジック(PROCESS BEFORE OUTPUT と PROCESS AFTER INPUT)
zag_unit_test.prog.xml中身プログラム属性、画面の項目定義(DYNPROS)、テキスト要素(TPOOL)

画面項目表の材料は、.abap ではなく .prog.xml の側にあります。このサンプルでは、DYNPROS の下の FIELDS に項目の種別・長さ・入力可否が入っていました。TPOOL には、ID が S で KEY が P_FOO のエントリーがあり、パラメーター P_FOO の選択テキストが「foobar」になっています。ソースだけを読ませると、画面項目の名前は取れても画面上の見出し文言が取れません。

クラスは zcl_example.clas.abap に加えて、ローカルクラス用の locals_def.abap や locals_imp.abap、テストクラス用の testclasses.abap などに分かれます。空の部品はファイルとして作られません。

リポジトリの構造は .abapgit.xmlから読む

リポジトリのルートに置かれる .abapgit.xml には、メインの言語、ソースを置くフォルダー(STARTING_FOLDER)、フォルダーの割り当て規則(FOLDER_LOGIC)が入っています。abapGit自身のリポジトリでは、次の値です。

<MASTER_LANGUAGE>E</MASTER_LANGUAGE>
<STARTING_FOLDER>/src/</STARTING_FOLDER>
<FOLDER_LOGIC>PREFIX</FOLDER_LOGIC>

FOLDER_LOGIC が PREFIX のとき、パッケージ名は親パッケージ名を接頭辞として持つ必要があります。ZFOO の下に ZFOO_BAR、その下に ZFOO_BAR_QUX があれば、フォルダーは /src/bar/qux になります。FULL ならパッケージ名がそのままフォルダー名になり、MIXED はルートのパッケージ名だけを接頭辞にします。

この規則を知らないと、フォルダー名から元のパッケージ名を逆算できません。仕様書にパッケージ名を書きたいなら、最初に .abapgit.xml を読ませて、フォルダーとパッケージの対応を表にさせるのが近道です。パッケージ名そのものは保存されず、package.devc.xml にあるのはパッケージのメタデータだけです。

ABAP専用の読み方はpaths付きルールに置く

読み方の規約は CLAUDE.md に書けますが、ABAPを触らない作業にまで毎回載せる必要はありません。.claude/rules/ に置いたルールファイルは、paths で対象ファイルを絞れます。パスに一致するファイルをRead・Write・Editで扱うとき、あるいは cat や head のような読み取り扱いのBashで開くときに読み込まれる仕組みです。

---
paths:
  - "src/**/*.abap"
  - "src/**/*.prog.xml"
---
 
# ABAP読解ルール
 
- 仕様書は画面項目表・テーブルアクセス表・呼び出し先表の3枚で返す
- 全行に「ファイル名:行番号」の根拠を付ける
- INCLUDE 先のファイルも読み、表の根拠は INCLUDE 先の行を指す
- テーブル名・ファンクション名が変数で渡されるときは「動的」と書き、推測しない
- コード中のコメントは仕様の根拠にせず、「コメントにはこうある」と別欄に分ける
- ソースは変更しない

CLAUDE.mdの目安は1ファイル200行以下とされています。長くなる規約を paths 付きのルールに逃がしておけば、ABAP以外の作業でコンテキストを消費しません。

読み取り専用のサブエージェントを定義する

プログラム1本ずつ読ませる担当は、.claude/agents/ に置くサブエージェントにします。tools を書くと使えるツールを絞れるので、書き込み系を外した定義にします。

---
name: abap-spec-reader
description: ABAPのZプログラム1本を読み、画面項目表・テーブルアクセス表・呼び出し先表を返す
tools: Read, Grep, Glob
---
 
渡されたプログラム名の .prog.abap と .prog.xml を読み、
3つの表を返します。表の書式と禁止事項は .claude/rules のABAP読解ルールに従います。
 
- FORM・MODULE・メソッドの呼び出し連鎖は、定義が別ファイルなら追って読む
- 読めなかった INCLUDE やファンクショングループは「未読」として一覧にする
- 表の最後に、読んだファイルの一覧を付ける

組み込みのExploreも読み取り専用ですが、表の書式を指定したいのは定義を自作するときです。プログラムごとに同じ書式の表を並べたいので、自作の定義を使います。

読ませる前にgrepで件数を数えておく

表が出てきてから数が合うか確かめるのでは遅いので、読ませる前にシェルで母数を数えます。次のコマンドは、対象フォルダーの各プログラムについて、DBの読み書きと呼び出しの記述を数えます。

cd src/zsales
for f in *.prog.abap; do
  echo "$f select=$(grep -ci '^ *select' $f)" \
       "write=$(grep -ciE '^ *(insert|update|modify|delete) ' $f)" \
       "func=$(grep -ci 'call function' $f)" \
       "perform=$(grep -ci '^ *perform' $f)" \
       "submit=$(grep -ci '^ *submit' $f)"
done

この数値は、仕様書の表の行数と照合する基準になります。SELECTが12あるのにテーブルアクセス表が8行なら、4件は同じテーブルへの重複か、読み落としです。複数行にまたがるSELECTは grep -ci では1と数えられるので、基準値としては近似です。

表の形の例

下は、架空の受注一覧レポートを想定した表の形の例です。実在のプログラムから取った値ではありません。

テーブルアクセス表の例です。

処理テーブル操作条件根拠
受注データ取得テーブルVBAK操作SELECT条件受注日が選択範囲内根拠zsales_list.prog.abap:42
明細取得テーブルVBAP操作SELECT条件VBAKのキーで結合根拠zsales_list.prog.abap:57
出力履歴登録テーブルZSALES_LOG操作INSERT条件一覧表示のたび根拠zsales_list.prog.abap:131

呼び出し先表の例です。

呼び出し元種別呼び出し先受け渡し根拠
メイン処理種別CALL FUNCTION呼び出し先Z_GET_CUSTOMER_NAME受け渡し得意先番号根拠zsales_list.prog.abap:88
出力処理種別SUBMIT呼び出し先ZSALES_PRINT受け渡し選択画面の値根拠zsales_list.prog.abap:140
全体種別CALL FUNCTION呼び出し先変数で指定受け渡し動的根拠zsales_list.prog.abap:155

3行目の「動的」が重要です。次の節で理由を説明します。

grepで追えない呼び出しを分けて書く

ABAPでは、呼び出し先を文字列の変数で渡せます。たとえば CALL FUNCTION lv_funcname や SUBMIT (lv_report) のような書き方です。呼び出し先の名前がソースに現れないので、grepでは追えません。Claude Codeがコードを読んでも、変数に入る値が画面入力や設定テーブル由来であれば、ソースだけからは決められません。

そのため、規約に「動的」と書かせたうえで、動的呼び出しの一覧を別表にします。変数に値を入れている箇所(lv_funcname = 'Z_...' のような代入)が近くにあれば、その行番号を付けます。値が設定テーブルから来るなら、テーブル名と、SAPシステム側で中身を確かめる必要があることを書きます。システムの実データを見ない限り、ここは埋まりません。

システム側の情報が要るものは、ほかにもあります。

  • 拡張ポイントやBAdIの実装は、有効かどうかをシステムで確かめる必要がある
  • ユーザー出口やエンハンスメントで本体の外に処理が追加されている場合、リポジトリに含まれていないことがある
  • 権限チェック(AUTHORITY-CHECK)は、ソースから権限オブジェクトの名前までは取れても、誰に付与されているかは取れない

画面項目表はXMLとフローロジックを突き合わせて作る

画面項目表は、3つのファイルを突き合わせないと完成しません。項目の定義は .prog.xml の DYNPROS、項目を処理するモジュールの呼び出しは .prog.screen_<画面番号>.abap、モジュールの中身は .prog.abap にあります。サンプルのフローロジックでは MODULE STATUS_2000 と MODULE USER_COMMAND_2000 がコメントアウトされた状態でした。実プログラムでは、ここが画面とコードをつなぐ接点になります。

指示は、画面1つずつ次の順で出します。

zsales_list の画面2000について、画面項目表を作ってください。
1. zsales_list.prog.xml の DYNPROS から画面2000の項目を拾う
2. zsales_list.prog.screen_2000.abap から PBO / PAI のモジュール名を拾う
3. そのモジュールの中身を zsales_list.prog.abap で探し、項目ごとの処理を書く
4. 見出し文言は TPOOL から付ける。無い項目は「テキスト要素なし」と書く

画面の件数は、grep -c "<SCREEN>" zsales_list.prog.xml のようにXML側で数えられます。表の画面数と合わなければ、画面を丸ごと読み落としています。

Z名前空間とファイル名のエスケープ

社内のZプログラムなら名前は ZSALES_LIST のような形ですが、ABAPの名前空間(/ACME/ のような接頭辞)を使うシステムもあります。このときファイル名では /NAMESPACE/ が #namespace# に置き換えられ、JSONのファイル名では (namespace) になります。grepの検索語や、ルールの paths を書くときに # を含む名前が出てくるので、ファイルを探して見つからないときは、まずこの置換を疑います。

また、% や #、. のようにファイル名に使いにくい文字を含むオブジェクト名は、abapGitがエスケープして保存します。名前の見た目がソースと違っても、別オブジェクトではない場合があります。

つまずきやすい点

INCLUDEの先を読み落とす型が最も多くなります。メインのプログラムが薄く、処理の本体は INCLUDE で取り込む別プログラムにある構成は珍しくありません。サブエージェントの定義に「INCLUDE先も読む」と書き、返ってきた「読んだファイル一覧」にそのファイルが入っているかを確かめます。

ファンクショングループは、複数ファイルに分かれます。呼び出し先表の「Z_...」をたどった結果が「未読」になっていないか、表の最後を見ます。

画面項目の見出しが空欄になるのは、.prog.xml を渡していないときです。TPOOL と DYNPROS はこちらにあるので、担当に渡すファイルは .prog.abap と .prog.xml をセットにします。

Zプログラムがクラスに処理を寄せている場合は、.clas.abap だけでは足りません。ローカルクラスは locals_imp.abap にあり、メインのプログラムから呼ぶ処理がそちらに入っていることがあります。担当に渡す範囲に、同じオブジェクト名で始まるファイルをすべて含めます。ユニットテストの testclasses.abap は、入力と期待値の組が並ぶので、業務ルールの裏取りにも使えます。

行番号のずれにも注意します。示される行番号は、読んだ時点のファイルの行です。修正が入ると根拠がずれるので、仕様書を作る作業は git のコミットを固定した作業コピーで行います。

まとめ

abapGit経由のABAPソースは、コード・画面と属性・テキストが別ファイルで揃い、UTF-8で読めます。それぞれを3つの表に振り分け、読み取り専用のサブエージェントに行番号つきで返させるのが基本の流れです。grepの件数を先に取れば表の抜けを数で検算でき、動的呼び出しは「動的」として別表に隔離すれば、推測の混入を防げます。

システムの中でしか決まらない値は、表の空欄としてあらかじめ残す設計にしておくと、後から埋める作業が見通せます。SAP側のツールで読む方法はSAP HANA CLIのMCPの記事、ソースから設計書全体を組み立てる流れは詳細設計書を起こす記事、書いた仕様書のずれを継続的に検出する方法は設計書の乖離検出の記事にあります。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/memory
  2. code.claude.com/docs/en/sub-agents
  3. code.claude.com/docs/en/tools-reference
  4. docs.abapgit.org/user-guide/reference/folders-filenames.html
  5. docs.abapgit.org/user-guide/serializers/file-formats.html
  6. docs.abapgit.org/user-guide/repo-settings/dot-abapgit.html
この記事を共有:XはてブLinkedIn