例外テキストがアプリケーションに対して十分に具体的ではないことが判明しました。そのため、独自の例外クラスを定義し、それをコードで使用します。
タスク 1: テンプレートのコピー (オプション)
テンプレートクラス /LRN/CL_S4D401_EXS_HANDLING をコピーします。前の演習問題を完了した場合は、このタスクをスキップし、クラス ZCL_##_SOLUTION の編集を続行することができます。
ステップ
クラス /LRN/CL_S4D401_EXS_HANDLING を独自のパッケージのクラスにコピーします (推奨名: ZCL_##_SOLUTION、## はグループ番号)。
Project Explorer で、クラス /LRN/CL_S4D401_EXS_HANDLING を右クリックしてコンテキストメニューを開きます。
コンテキストメニューから Duplicate.... を選択します。
Package 項目にパッケージの名称を入力します。Name 項目に、ZCL_##_SOLUTION (## はグループ番号) と入力します。
Next を選択します。
移送依頼を確認し、Finish を選択します。
コピーを有効化します。
Ctrl + F3 を押してクラスを有効化します。
タスク 2: メッセージクラスの登録
新しいメッセージクラスを登録します (推奨名: Z##_MESSAGES、## は各自のグループ番号)。2 つのメッセージテキストを定義します。1 つは存在しない運送業者をレポートし、もう 1 つは不足している読込権限を報告します。両方のメッセージで、運送業者 ID のプレースホルダを使用します。
ステップ
新しいメッセージクラスを登録します (推奨名: Z##_MESSAGES、## は各自のグループ番号)。
Project Explorer で、パッケージを右クリックし、New→Other ABAP Repository Object を選択します。
検索項目に、メッセージと入力します。
検索結果から、テキスト→メッセージクラスを選択し、次を選択します。
Package 項目にパッケージ名が含まれていることを確認します。
Name 項目に、Z##_MESSAGES (## はグループ番号) と入力します。
内容説明項目に、例外クラスのメッセージと入力します。
Next を選択します。
移送依頼を確認し、Finish を選択します。
運送業者が存在しないことを通知するメッセージを定義します (推奨番号: 010)。運送業者 ID のプレースホルダを使用します。
最初の行の番号列で、 <新規値を入力> を選択し、010 を入力します。
同じ行のテキスト (短) 列に、運送業者 &1 は存在しませんと入力します。
ユーザに特定の航空会社を照会する権限がないことを通知するメッセージを定義します (推奨番号: 020)。運送業者 ID のプレースホルダを使用します。
2 行目で、番号列に <新規値を入力> を選択し、020 を入力します。
同じ行のテキスト (短) 列に、運送業者 &1 を照会する権限がありませんと入力します。
メッセージクラスを保存します。
注記
メッセージクラスを有効化する必要はなく、有効化することもできません。メッセージクラスでは、有効バージョンと無効バージョンは区別されません。
Ctrl + S を押して、メッセージクラスを保存します。
タスク 3: 例外クラス登録
スーパークラス CX_STATIC_CHECK から継承する新しいグローバル例外クラス (推奨名: ZCX_##_FAILED、## は各自のグループ番号) を登録します。登録したメッセージテキストを参照する 2 つのテキスト ID 定数を定義します。パブリックで読込専用のインスタンス属性 (推奨名: CARRIER_ID) を宣言し、実行時にメッセージ内のプレースホルダがこの属性の値に置き換えられていることを確認します。最後に、オプションのインポートパラメータを使用して CONSTRUCTOR メソッドを拡張し、新規属性を設定します。
ステップ
スーパークラス CX_STATIC_CHECK から継承する新しいグローバルクラスを登録します (推奨名: ZCX_##_FAILED、## は各自のグループ番号)。
Project Explorer で、パッケージを右クリックし、New→ABAP Class を選択します。
Package 項目にパッケージ名が含まれていることを確認します。
名称項目に、ZCX_##_FAILED (## はグループ番号) と入力します。
Description 項目に Instantiation Failed と入力します。
Superclass 項目に CX_STATIC_CHECK と入力します。
Next を選択します。
移送依頼を確認し、Finish を選択します。
コード完了を使用して、新しいテキスト ID 定数 (つまり、パブリック構造化定数) を定義します。
例外クラスの public セクションで、INTERFACES 命令の後に text を入力し、Ctrl + Space を押してコード完了を呼び出します。
候補リストから、textIDExceptionClass - 例外クラスのデフォルトテキスト ID を選択します。
コード完了により、コードが以下のように調整されます。
12345678910111213
PUBLIC SECTION.
INTERFACES if_t100_message.
INTERFACES if_t100_dyn_msg.
CONSTANTS:
BEGIN OF zcx_##_failed,
msgid TYPE symsgid VALUE 'msgid',
msgno TYPE symsgno VALUE 'msgno',
attr1 TYPE scx_attrname VALUE 'attr1',
attr2 TYPE scx_attrname VALUE 'attr2',
attr3 TYPE scx_attrname VALUE 'attr3',
attr4 TYPE scx_attrname VALUE 'attr4',
END OF zcx_##_failed.
クイックフィックスを使用して、定数の名前を変更します (推奨名: carrier_not_exist)。
BEGIN OF の後、zcx_##_failed (## は各自のグループ番号) にカーソルを置き、Ctrl + 1 を押して利用可能なクイックフィックスを呼び出します。
利用可能なクイックフィックスの一覧から Rename zcx_##_failed を選択します。
定数の名称が強調表示されている間は、新しい名称を入力します。
定数のコンポーネント値を調整します。メッセージクラスの名称と、最初のメッセージの番号を値として使用します。
コードを以下のように調整します。
123456789
CONSTANTS:
BEGIN OF carrier_not_exist,
msgid TYPE symsgid VALUE 'Z##_MESSAGES',
msgno TYPE symsgno VALUE '010',
attr1 TYPE scx_attrname VALUE 'attr1',
attr2 TYPE scx_attrname VALUE 'attr2',
attr3 TYPE scx_attrname VALUE 'attr3',
attr4 TYPE scx_attrname VALUE 'attr4',
END OF carrier_not_exist.
同じコードテンプレートおよびクイックフィックスを使用して、2 番目のメッセージテキストに別のテキスト ID 定数を定義します (推奨名: carrier_no_read_auth)。
以下のコードを追加します。
123456789
CONSTANTS:
BEGIN OF carrier_no_read_auth,
msgid TYPE symsgid VALUE 'Z##_MESSAGES',
msgno TYPE symsgno VALUE '020',
attr1 TYPE scx_attrname VALUE 'attr1',
attr2 TYPE scx_attrname VALUE 'attr2',
attr3 TYPE scx_attrname VALUE 'attr3',
attr4 TYPE scx_attrname VALUE 'attr4',
END OF carrier_no_read_auth.
タイプ /DMO/CARRIER_ID のパブリックの読込専用インスタンス属性を定義します (推奨名: CARRIER_ID)。
例外クラスのパブリックセクションで、以下のコードを追加します。
1
DATA carrier_id TYPE /dmo/carrier_id READ-ONLY.
テキスト ID 定数を調整します。コンポーネント attr1 の値として、新規属性の名称を使用します。
コードを以下のように調整します。
12345678910111213141516171819
CONSTANTS:
BEGIN OF carrier_not_exist,
msgid TYPE symsgid VALUE 'Z##_MESSAGES',
msgno TYPE symsgno VALUE '010',
attr1 TYPE scx_attrname VALUE 'carrier_id',
attr2 TYPE scx_attrname VALUE 'attr2',
attr3 TYPE scx_attrname VALUE 'attr3',
attr4 TYPE scx_attrname VALUE 'attr4',
END OF carrier_not_exist.
CONSTANTS:
BEGIN OF carrier_no_read_auth,
msgid TYPE symsgid VALUE 'Z##_MESSAGES',
msgno TYPE symsgno VALUE '020',
attr1 TYPE scx_attrname VALUE 'carrier_id',
attr2 TYPE scx_attrname VALUE 'attr2',
attr3 TYPE scx_attrname VALUE 'attr3',
attr4 TYPE scx_attrname VALUE 'attr4',
END OF carrier_no_read_auth.
CONSTRUCTOR メソッドの署名を拡張します。属性 carrier_id の値の設定に使用できるオプションのインポートパラメータを追加します (推奨名: carrier_id)。
コードを以下のように調整します。
12345
METHODS constructor
IMPORTING
!textid LIKE if_t100_message=>t100key OPTIONAL
!previous LIKE previous OPTIONAL
carrier_id LIKE carrier_id OPTIONAL.
注記
感嘆符 (!) を無視または削除することができます。既存のパラメータ名の前に配置します。パラメータ名が ABAP キーワードと区別可能である限り、これらはオプションです。グローバルクラスでは、デフォルトで挿入されます。
CONSTRUCTOR メソッドの実装を調整します。メソッドの最後に、オプションのパラメータ carrier_id が初期値であるかどうかをチェックします。初期値でない場合は、その値をインスタンス属性 carrier_id に保存します。
注記
インポートパラメータと属性に同じ名称を選択する場合は、自己参照 me を使用して属性を指定する必要があります。
コードを以下のように調整します。
12345678910
IF textid IS INITIAL.
if_t100_message~t100key = if_t100_message=>default_textid.
ELSE.
if_t100_message~t100key = textid.
ENDIF.
IF carrier_id IS NOT INITIAL.
me->carrier_id = carrier_id.
ENDIF.
ENDMETHOD.
例外クラスを有効化します。
Ctrl + F3 を押してコードを有効化します。
タスク 4: 例外クラスの使用
ローカルクラス LCL_CARRIER のメソッド GET_INSTANCE で、例外クラス CX_ABAP_INVALID_VALUE および CX_ABAP_AUTH_CHECK_EXCEPTION を独自の例外クラスに置き換えます。警告に従って、メソッド IF_OO_ADT_CLASSRUN~MAIN でメソッド定義および例外処理の RAISING 句を調整します。
ステップ
ローカルクラス LCL_CARRIER のメソッド GET_INSTANCE の実装にナビゲートします。
たとえば、Outline ビューで ZCL_##_SOLUTION→LCL_CARRIER を展開し、GET_INSTANCE を選択します。
例外クラス CX_ABAP_INVALID_VALUE を使用する RAISE EXCEPTION 命令を削除するか、またはコメントしてください。
パラメータ受渡しを含む RAISE EXCPETION 命令を選択し、Ctrl + < を押して選択した行の前にコメント記号を追加します。
独自の例外クラスを使用して RAISE EXCEPTION 命令を実装します。コード完了を使用して、CONSTRUCTOR の完全な署名を挿入します。
コメントされたコードの後にカーソルを置き、例外発生タイプ ZCX_## (## は各自のグループ番号) を入力します。
Ctrl + Space を押して、コード完了を呼び出します。
Shift + Enter を押して、完全な署名を挿入します。
コード完了に以下のコードが追加されていることを確認します。
12345
RAISE EXCEPTION TYPE zcx_##_failed
オプションの textid パラメータにテキスト ID 定数の 1 番目を指定し、オプションの carrier_id パラメータに i_carrier_id の値を指定します。
コードを以下のように調整します。
12345
RAISE EXCEPTION TYPE zcx_##_failed
EXPORTING
textid = zcx_##_failed=>carrier_not_exist
carrier_id = i_carrier_id.
同様に、2 番目の RAISE EXCEPTION 命令で独自の例外クラスを使用します。今回は、パラメータ textid の入力として他のテキスト ID 定数を使用します。
コードを以下のように調整します。
123456789
RAISE EXCEPTION TYPE zcx_##_failed
EXPORTING
textid = zcx_##_failed=>carrier_no_read_auth
carrier_id = i_carrier_id.
クイックフィックスを使用して、メソッド GET_INSTANCE の RAISING 句に独自の例外クラスを追加します。
2 つの RAISE EXCEPTION 命令のいずれかを含むコード行に移動し、左側の電球を含む警告アイコンを選択して、利用可能なクイックフィックスを呼び出します。
利用可能なクイックフィックスの一覧から、Add raising declaration を選択します。
メソッド GET_INSTANCE の RAISING 句から冗長な例外を削除またはコメントします。
コードを以下のように調整します。
123456789
CLASS-METHODS get_instance
IMPORTING
i_carrier_id TYPE /dmo/carrier_id
RETURNING
VALUE(r_result) TYPE REF TO lcl_carrier
RAISING
zcx_##_failed.
メソッド IF_OO_ADT_CLASSRUN~MAIN で例外処理を調整します。2 つの CATCH ブロックを、独自の例外クラスに対して 1 つの CATCH ブロックに置き換えます。
コードを以下のように調整します。
12345678910111213
TRY.
DATA(carrier) = lcl_carrier=>get_instance( i_carrier_id = c_carrier_id ).
out->write( name = `Carrier Overview`
data = carrier->get_output( ) ).
CATCH zcx_##_failed INTO DATA(exc_fail).
out->write( exc_fail->get_text( ) ).
ENDTRY.
コードを有効化してテストします。定数 c_carrier_id の値を調整して、さまざまな例外を発生させます。
Ctrl + F3 を押してコードを有効化します。
F9 を押して、コードをコンソールアプリとして実行します。
定数 c_carrier_id の値を XX に設定して、無効な値の例外を発生させます。
定数 c_carrier_id の値を UA に設定して、権限不足の例外を発生させます。