この記事を読むメリット
受注登録(T-CODE:VA01)を例に、使えるユーザーExit を 2 通りの方法で探せるようになる
T-CODE:CMOD で拡張プロジェクトを作り、ZX インクルードに処理を書いて有効化する手順が分かる
作った拡張プロジェクトとインクルードを無効化・削除する手順が分かる
SAP の標準プログラムには、「ここに独自の処理を足してよい」という Exit があらかじめ用意されています。この記事でユーザーExit と呼ぶのは、そうした Exit のうち、SAP のヘルプで「カスタマ Exit」と呼ばれる仕組みです。T-CODE:SMOD と T-CODE:CMOD で扱います。
この記事では、受注登録(T-CODE:VA01)を例に、次の 3 つを実際の画面で 1 画面ずつ解説します。対象は ABAP を学び始めた開発者の方です。
使えるユーザーExit を 探す方法を 2 通り
見つけた Exit に 自分の処理を登録して有効化する手順
作ったものを 無効化して削除する手順
受注登録の MV45AFZZ にある、もう 1 つの USER-EXITS の 見方
博士!受注登録のときに、受注先を前もって入れておきたいって相談されたんです。標準の処理に、自分の処理を足すことってできるんですか?
うむ、SAP の標準プログラムには、処理を足せる Exit が用意されておるぞい。今回はユーザーExit の探し方と登録の仕方を、画面を追って説明していくぞい!
この記事のポイント
前提
確認した環境: この記事の画面は、SAP S/4HANA の SAP GUI for HTML の画面です(2026年10月)。
使うトランザクション: T-CODE:SE93、T-CODE:SMOD、T-CODE:SE38、T-CODE:CMOD。
作るもの: 拡張プロジェクト ZLABVA01 と、インクルード ZXVVAU04。どちらもローカルオブジェクトとして作ります。
ユーザーExit の仕組み
最初に、画面に出てくる言葉の関係を押さえておきます。
言葉 意味 扱うトランザクション SAP 拡張 SAP が Exit をまとめた単位です。1 つの SAP 拡張に複数の Exit が入ることもあります(例: V45A0002) T-CODE:SMOD(照会) 汎用モジュール Exit 標準プログラムから CALL CUSTOMER-FUNCTION '002' のように呼ばれる汎用モジュールです。名前は EXIT_ + プログラム名 + 3 文字の名前になります(例: EXIT_SAPMV45A_002) T-CODE:SE37 ZX で始まるインクルード 汎用モジュール Exit の中に用意された、利用者が処理を書く場所です(例: ZXVVAU04) T-CODE:SE38 拡張プロジェクト 使う SAP 拡張を登録し、まとめて有効化・無効化する入れ物です(例: ZLABVA01) T-CODE:CMOD
SAP のヘルプでは、次のように説明されています。
Exit そのものは機能を持たず、「フック(引っかけるための留め金)」として働きます。
汎用モジュール Exit の枠組みやインタフェース(パラメータ)は変更できません。処理を書けるのは、用意された ZX インクルードの中だけです。
拡張プロジェクトを有効化していないと、CALL CUSTOMER-FUNCTION は無視されます。
カスタマ Exit(T-CODE:CMOD による拡張)は古い技術とされ、代わりに BAdI などの拡張フレームワークを使うよう案内されています。
すでに動いているシステムでは、カスタマ Exit を使った処理に出会うことがあります。新しく作るときだけでなく、既存の処理を調べるときにも、探し方と登録の仕方を知っておくとよいでしょう。
受注登録のプログラム SAPMV45A のソースには、「USER-EXITS」という見出しの下に MV45AFZZ などのインクルードも並んでいます。これは T-CODE:SMOD・T-CODE:CMOD で扱う仕組みとは別のものです。中身の見方は、記事の後半「もう 1 つの USER-EXITS: MV45AFZZ」で説明します。
探し方1: トランザクションのパッケージから SAP 拡張を探す
たとえば、受注登録で「受注先を前もって入れておきたい」という要望を受けた場面を考えます。まず受注登録のプログラムとパッケージを調べ、そのパッケージに属する SAP 拡張を一覧にします。
1. T-CODE:SE93 で受注登録のトランザクションを照会する
コマンドフィールドに SE93 と入力して Enter キーを押します。「トランザクション更新」画面でトランザクションコードを入力し、「照会」を押します。
画面の見方
トランザクションコード : 調べたいトランザクションコードを入力します。
照会 : トランザクションの定義を表示します。
この例では VA01 を入力します。
2. プログラムとパッケージを確認する
「照会 ダイアログトランザクション」画面が開きます。
画面の見方
パッケージ : このトランザクションが属しているパッケージです。
プログラム : トランザクションに割り当てられたプログラムの名前です。
この例では、パッケージは VA、プログラムは SAPMV45A です。この 2 つを次の手順で使います。
3. T-CODE:SMOD の入力ヘルプでパッケージを指定して検索する
コマンドフィールドに /nSMOD と入力して Enter キーを押します(/n を付けると、別のトランザクションの画面からでも移れます)。「SAP 拡張」画面の「拡張」欄で F4 キーを押すと、「リポジトリ情報システム: Exit 検索」画面が開きます。
画面の見方
パッケージ : SAP 拡張が属するパッケージで絞り込みます。
実行 : 条件に合う SAP 拡張を一覧にします。
この例では、手順 2 で確認したパッケージ VA を入力します。パッケージで絞り込むので、別のパッケージに属する SAP 拡張はこの一覧に出ません。その場合は、後で説明する「探し方2」を使います。
4. 一覧から SAP 拡張を選ぶ
パッケージに属する SAP 拡張が一覧で表示されます。
画面の見方
SAP 拡張の行 : 左が拡張名、右が内容説明です。内容説明を読んで、目的に合いそうなものを探します。
この例では 15 件が表示されます。今回の目的に合うのは V45A0002 受注先事前定義 (販売伝票) です。この行をダブルクリックすると、「拡張」欄に V45A0002 が入ります。
5. SAP 拡張のコンポーネントを照会する
「コンポーネント」を選んで「照会」を押します。
画面の見方
拡張 : 調べる SAP 拡張の名前です。
コンポーネント : その SAP 拡張に含まれる Exit の一覧を表示します。
照会 : 選んだ内容を表示します。
6. どの種類の Exit が含まれているかを確認する
「SAP 拡張 V45A0002 のコンポーネント」画面が開きます。Exit は種類ごとに欄が分かれています。
画面の見方
汎用モジュール Exit : 標準プログラムから呼ばれる汎用モジュールです。ここに処理を足します。
機能コード : メニューに独自の項目を足すための Exit(メニュー Exit)です。
Dynpro 領域 : 標準画面の中に独自の画面(サブスクリーン)を表示するための Exit(画面 Exit)です。
この例では、V45A0002 に含まれる Exit は汎用モジュール Exit の EXIT_SAPMV45A_002 だけです。
7. 汎用モジュール Exit の中身を確認する
EXIT_SAPMV45A_002 をダブルクリックすると、「汎用モジュールビルダ: 照会 EXIT_SAPMV45A_002」画面が開きます。「ソースコード」タブで中身を確認します。
画面の見方
IMPORTING : 標準プログラムから受け取るパラメータです。
EXPORTING : 標準プログラムへ返すパラメータです。
INCLUDE ZXVVAU04 : 利用者が処理を書くインクルードです。
この例では、受け取るパラメータは I_TVAK(販売伝票タイプのテーブル TVAK の 1 行分)・I_TVTA(販売エリアのテーブル TVTA の 1 行分)・I_VKGRP(営業グループ)・I_VKBUR(営業所)の 4 つ、返すパラメータは E_KUNNR(得意先コード)の 1 つです。
探し方2: プログラムのソースから CALL CUSTOMER-FUNCTION を検索する
もう 1 つの方法として、プログラムのソースで Exit を呼んでいる箇所を検索します。
1. プログラム全体を検索する
コマンドフィールドに /nSE38 と入力して Enter キーを押し、プログラム SAPMV45A を「照会」で開きます。ツールバーの検索ボタン(虫めがね)を押すと、「検索/置換」画面が開きます。
画面の見方
検索語句 : 探す文字列を入力します。
メインプログラム : 検索する範囲をメインプログラムにします。
続行 : 検索を始めます。
この例では、Exit を呼ぶ命令 CALL CUSTOMER-FUNCTION を入力します。
2. 検索結果を見る
「プログラム内一括検索」画面に、見つかった箇所が並びます。
画面の見方
プログラム/拡張 : 命令が書かれているプログラム(インクルード)の名前です。
発生/内容説明 : 何行目に、どのような命令が書かれているかです。
検索 : この一覧の中から文字を検索します。
CALL CUSTOMER-FUNCTION の後ろの 3 文字の名前から、汎用モジュール Exit の名前が分かります。この例では、CALL CUSTOMER-FUNCTION '002' は EXIT_SAPMV45A_002 に当たります。
拡張プロジェクトに登録するのは、汎用モジュール Exit ではなく、それを含む SAP 拡張です。SAP 拡張の名前は、テーブル MODSAP(SAP 拡張)で項目 MEMBER に汎用モジュール Exit の名前を指定すると、項目 NAME で分かります。この例では EXIT_SAPMV45A_002 を含む SAP 拡張は V45A0002 です。
3. 一覧の中で特定の名前を探す
一覧が長いときは、③の検索で探します。
画面の見方
検索 : 探す文字を入力します。
検索 : 一覧の中を検索します。
この例では '002' と入力します。② を押すと、該当する行が表示されます。
画面の見方
見つかった行 : 左がプログラム(インクルード)の名前、右が行番号と、その行の内容です。
この例では、インクルード MV45AF0A_AG_VORSCHLAGEN の 26 行目に CALL CUSTOMER-FUNCTION '002' があります。
4. Exit を呼んでいる前後のソースを読む
T-CODE:SE38 でインクルード MV45AF0A_AG_VORSCHLAGEN を照会すると、Exit がどの条件で呼ばれ、返した値がどう使われるかを読めます。
画面の見方
CHECK KUAGV-KUNNR IS INITIAL. : 受注先(KUAGV-KUNNR)が空のときだけ、この先の処理に進みます。
CALL CUSTOMER-FUNCTION ‘002’ : 汎用モジュール Exit EXIT_SAPMV45A_002 を呼んでいる行です。
E_KUNNR = KUAGV-KUNNR : Exit から返した E_KUNNR が、受注先(KUAGV-KUNNR)に入ります。
このルーチン(FORM AG_VORSCHLAGEN)では、パラメータ ID VAU(販売伝票の受注先)の値を GET PARAMETER で読んだあとに Exit を呼んでいます。Exit から返った受注先が空でなければ、汎用モジュール VIEW_KUAG2 を呼んで処理を続けます。
Exit に処理を書く前に、このように呼び出し元のソースを読んで、いつ呼ばれ、返した値がどこに入るのかを確かめておくとよいでしょう。
登録の仕方: 拡張プロジェクトを作って有効化する
ここからは、見つけた SAP 拡張 V45A0002 を拡張プロジェクトに登録し、ZX インクルードに処理を書いて有効化します。
1. T-CODE:CMOD で拡張プロジェクトを登録する
コマンドフィールドに /nCMOD と入力して Enter キーを押します。「SAP 拡張プロジェクト管理」画面で、プロジェクト名を入力して「登録」を押します。
画面の見方
Project : 作る拡張プロジェクトの名前です。
登録 : 新しい拡張プロジェクトを作ります。
この例では、プロジェクト名を ZLABVA01 とします。
2. 内容説明を入れて保存する
「拡張プロジェクト ZLABVA01 の属性」画面が開きます。
画面の見方
内容説明 : 拡張プロジェクトの説明です。
Project ステータス : 「有効化」の見出しの下にある項目です。
保存 : 属性を保存します。
内容説明には、何のためのプロジェクトかが分かる文を入れておくとよいでしょう。この例では、作ったばかりなので Project ステータスは空です。
保存を押すと「オブジェクトディレクトリエントリ登録」画面が開きます。
画面の見方
パッケージ : 拡張プロジェクトを入れるパッケージです。
ローカルオブジェクト : 保存先をローカルオブジェクトにします。
この記事では学習用のプロジェクトとして作るので、「ローカルオブジェクト」を押します。
3. SAP 拡張を割り当てる
保存すると、属性画面のパッケージ欄に $TMP と表示されます。続けて「拡張割当」を押します。
画面の見方
ステータスバー : 処理の結果を示すメッセージが表示されます。
拡張割当 : 拡張プロジェクトに SAP 拡張を割り当てる画面に進みます。
この例では、ステータスバーに「ZLABVA01 の属性は保存されました」と表示されます。
「拡張」欄に SAP 拡張の名前を入力して Enter キーを押し、保存を押します。
画面の見方
拡張 : 割り当てる SAP 拡張の名前です。
保存 : 割り当てを保存します。
この例では V45A0002 を入力します。Enter キーを押すと内容説明に「受注先事前定義 (販売伝票)」と表示され、保存するとステータスバーに「ZLABVA01 のコンポーネントは保存されました」と表示されます。
SAP のヘルプによると、同じ SAP 拡張を 2 つの拡張プロジェクトに入れることはできません。使いたい SAP 拡張がすでに別の拡張プロジェクトに入っているときは、そのプロジェクトに処理を足すかどうかを、担当者と相談しましょう。
4. コンポーネントを表示する
ツールバーの「コンポーネント」を押すと、拡張プロジェクトの中身が表示されます。
画面の見方
状態のアイコン : 拡張プロジェクトと SAP 拡張の状態を表すアイコンです。
Function Exit : この拡張プロジェクトで使える汎用モジュール Exit です。
有効化する前は、アイコンが赤い丸で表示されます。EXIT_SAPMV45A_002 をダブルクリックします。
5. ZX インクルードを作る
汎用モジュール EXIT_SAPMV45A_002 のソースコードが表示されます。
画面の見方
INCLUDE の行 : 処理を書くインクルードの名前が書かれた行です。この行をダブルクリックします。
ステータスバーに警告が表示されます。
画面の見方
警告メッセージ : ZX で始まる名前は、Exit のインクルードのための名前だという警告です。
この例では「プログラム名 ZX… は Exit 用汎用グループの INCLUDE 用に予約されています」と表示されます。Enter キーを押すと先へ進みます。
インクルードを作るかを聞かれるので、「はい」を押します。
この例では「インクルード ZXVVAU04 はありません オブジェクトを登録しますか」と表示されます。
「オブジェクトディレクトリエントリ登録」画面で、手順 2 と同じく保存先を決めます。
画面の見方
Object : 作るオブジェクトの種類と名前です。
ローカルオブジェクト : 保存先をローカルオブジェクトにします。
この例では、PROG(プログラム)の ZXVVAU04 を作ります。
6. 処理を書いて有効化する
ABAP エディタでインクルードが開きます。ここに処理を書きます。
画面の見方
処理を書く場所 : このインクルードに書いた処理が、汎用モジュール Exit の中で実行されます。
ステータス : オブジェクトが有効化されているかどうかの表示です。
有効化 : 有効化します。
この例では、まだ有効化していないので、ステータスは「無効 (変更済)」です。また、処理を書く場所を示すためにコメント 1 行だけを書いています。たとえば、受け取ったパラメータ(販売伝票タイプや販売エリアなど)をもとに受注先の得意先コードを決め、E_KUNNR に入れる処理が考えられます。
SAP のヘルプによると、このインクルードは汎用モジュールの中(FUNCTION〜ENDFUNCTION の間)に入るため、FORM と ENDFORM を書かないよう案内されています。
有効化を押すと、有効化するオブジェクトを選ぶ画面が開きます。
画面の見方
オブジェクトの行 : 印が付いているオブジェクトが有効化されます。
続行 : 印を付けたオブジェクトを有効化します。
この例では、ZXVVAU04 のほかにも有効化されていないオブジェクトが一覧に並び、ZXVVAU04 にだけ印が付いています。今回作ったものだけに印が付いていることを確かめてから続行するとよいでしょう。
画面の見方
ステータス : オブジェクトが有効化されているかどうかの表示です。
ステータスバー : 処理の結果を示すメッセージが表示されます。
この例では、ステータスが「有効」になり、ステータスバーに「オブジェクト有効化」と表示されます。
7. 拡張プロジェクトを有効化する
インクルードを有効化しただけでは、拡張プロジェクトは有効になりません。T-CODE:CMOD に戻り、拡張プロジェクトを有効化します。
画面の見方
Project : 有効化する拡張プロジェクトの名前です。
プロジェクト有効化 : 拡張プロジェクトを有効にします。
画面の見方
ステータスバー : 処理の結果を示すメッセージが表示されます。
この例では「プロジェクト ZLABVA01 は有効化されました」と表示されます。
SAP のヘルプによると、有効化はプロジェクト単位で行い、プロジェクトの中の Exit を 1 つずつ有効化することはできません。また、開発システムから本番システムへ移送したあとも、移送先で有効化が必要です。
結果の確認
「コンポーネント」を選んで照会すると、状態が変わっていることを確かめられます。
画面の見方
状態のアイコン : 拡張プロジェクトと SAP 拡張の状態を表すアイコンです。
Function Exit の行の印 : 「登録の仕方」の手順 4 の画面には無かった印です。
この例では、アイコンが緑の四角に変わり、Function Exit の行にチェックマークが表示されます。
SAP のヘルプによると、有効化した Exit は、標準プログラムの CALL CUSTOMER-FUNCTION から呼ばれます。この例では、CALL CUSTOMER-FUNCTION '002' が実行されたときに、インクルード ZXVVAU04 に書いた処理が実行されます。
後片付け: 無効化して削除する
学習やテストのために作った拡張プロジェクトは、確かめ終わったら無効化し、削除しておくとよいでしょう。ここでは、この記事で作った拡張プロジェクトとインクルードを削除する手順を説明します。
1. 拡張プロジェクトを無効化する
T-CODE:CMOD でプロジェクト名を入力し、「プロジェクト無効化」を押します。
画面の見方
Project : 無効化する拡張プロジェクトの名前です。
プロジェクト無効化 : 拡張プロジェクトを無効にします。
画面の見方
ステータスバー : 処理の結果を示すメッセージが表示されます。
この例では「プロジェクト ZLABVA01 は有効化されていません」と表示されます。
2. ZX インクルードを削除する
T-CODE:SE38 でプログラム名にインクルードの名前を入力し、ツールバーの「削除」を押します。
画面の見方
プログラム : 削除するインクルードの名前です。
削除 : プログラム(インクルード)を削除します。
画面の見方
ステータスバー : 処理の結果を示すメッセージが表示されます。
この例では「プログラム ZXVVAU04 は正常に削除されました」と表示されます。
3. 拡張プロジェクトを削除する
T-CODE:CMOD でプロジェクト名を入力し、ツールバーの「削除」を押します。
画面の見方
Project : 削除する拡張プロジェクトの名前です。
削除 : 拡張プロジェクトを削除します。
続けて「オブジェクトディレクトリエントリ登録」画面が開き、保存先を聞かれます。ここで聞かれているのは拡張プロジェクトそのものではなく、画面の Object 欄に表示されるオブジェクト(この例では DOCV MOZZLABVA01)の保存先です。
画面の見方
Object : 保存先を決めるオブジェクトの種類です。
ローカルオブジェクト : 保存先をローカルオブジェクトにして処理を続けます。
この例では、「ローカルオブジェクト」を押すと拡張プロジェクト ZLABVA01 が削除されます。DOCV MOZZLABVA01 は、削除の後もローカルオブジェクトとしてオブジェクトディレクトリ(テーブル TADIR)に残ります。
もう 1 つの USER-EXITS: MV45AFZZ
受注登録のプログラム SAPMV45A には、T-CODE:SMOD・T-CODE:CMOD の仕組みとは別に、FORM で書く Exit が入ったインクルードもあります。ここでは、その場所と中身の見方を説明します。この記事では、このインクルードへの登録(書き込み)は行いません。
1. SAPMV45A のソースで USER-EXITS のインクルードを確かめる
T-CODE:SE38 で SAPMV45A を照会すると、ソースの最初の方に「U S E R – E X I T S」という見出しがあります。
画面の見方
USER-EXITS の見出し : コメントで書かれた見出しです。
インクルードの一覧 : 見出しの下に並ぶインクルードです。
INCLUDE mv45afzz : この節で中身を見るインクルードです。
この例では、MV45AOZZ(コメントは User-modules PBO)、MV45AIZZ(User-modules PAI)、MV45AFZZ(User-forms)などが並びます。
2. MV45AFZZ の中身を見る
T-CODE:SE38 で MV45AFZZ を照会します。
画面の見方
This include is reserved for user modifications : このインクルードの使い道を書いたコメントです。
The name of modification modules should begin with ‘ZZ’ : 独自に足すモジュールの名前の付け方を書いたコメントです。
FORM の見出しと説明 : 用意されている FORM と、その使い道・呼ばれる場所を書いたコメントです。
この例では、③の USEREXIT_DELETE_DOCUMENT のコメントに、販売伝票を削除するときに追加のテーブルのデータを削除するために使えること、FORM BELEG_LOESCHEN の終わりで呼ばれることが書かれています。
MV45AFZZ には、ほかにも USEREXIT_MOVE_FIELD_TO_VBAK、USEREXIT_SAVE_DOCUMENT、USEREXIT_SAVE_DOCUMENT_PREPARE などの FORM があります。たとえば USEREXIT_SAVE_DOCUMENT_PREPARE のコメントには、伝票を保存する前の変更やチェックに使えること、FORM BELEG_SICHERN の最初で呼ばれることが書かれています。
3. 変更しようとしたときの表示を確かめる
MV45AFZZ を照会した画面で「照会 <-> 変更」を押すと、情報のメッセージが表示されます。
画面の見方
メッセージ : 変更しようとしたオブジェクトについての情報です。
この例では「緊急の場合のみ外部名称領域で仮修正を行ってください」と表示されます。「ヘルプ」を押すと、メッセージの説明が表示されます。
この説明(メッセージ番号 TR852)によると、編集しようとしているオブジェクトは、SAP または別のソフトウェア製造業者に属するオブジェクトのために予約された名称領域にあります。そのため、緊急の仮修正だけを、名称領域の所有者に相談したうえで、または指示どおりに行うよう案内されています。
T-CODE:CMOD のカスタマ Exit では、利用者用の ZX インクルードに処理を書きました。MV45AFZZ は、SAP の名称領域にあるインクルードそのものです。MV45AFZZ に処理を足すときは、社内の開発ルールを確かめ、担当者と相談してから行うとよいでしょう。
動かないときに確かめること
インクルードを有効化したのに、Exit の処理が動かない : 拡張プロジェクトが有効化されていないと、CALL CUSTOMER-FUNCTION は無視されます。T-CODE:CMOD で拡張プロジェクトを有効化しているかを確かめましょう。
本番システムで Exit の処理が動かない : 移送したあとも、移送先で拡張プロジェクトの有効化が必要です。移送先で有効化したかを確かめましょう。
使いたい SAP 拡張を拡張プロジェクトに割り当てられない : 同じ SAP 拡張を 2 つの拡張プロジェクトに入れることはできません。すでに割り当てられている拡張プロジェクトを探して、そちらに処理を足すかどうかを相談しましょう。
処理を書くインクルードにサブルーチンを書きたい : このインクルードは汎用モジュールの中に入るため、FORM と ENDFORM は書かないよう案内されています。
まとめ
ユーザーExit は、T-CODE:SE93 でパッケージを調べて T-CODE:SMOD の Exit 検索で探すか、プログラムのソースで CALL CUSTOMER-FUNCTION を検索して探します。
処理は、汎用モジュール Exit の中の ZX インクルードに書きます。
受注登録には、MV45AFZZ の FORM で書く USER-EXITS もあります。こちらは SAP の名称領域のインクルードです。
T-CODE:CMOD で拡張プロジェクトに SAP 拡張を割り当て、プロジェクトを有効化すると Exit が使われます。
パッケージから探す方法と、ソースで CALL CUSTOMER-FUNCTION を検索する方法の 2 つがあるんですね!
うむ。処理は ZX インクルードに書いて、拡張プロジェクトを有効化すると Exit が使われるのじゃ。