こんにちは。
ABAP 7.4xから使用できるようになった、変数のインライン定義についてまとめてみました。インライン宣言を使いこなせるようになると、以下のような点で便利です。
- 事前宣言なしで変数が使える
- コードが簡潔になる
以下、インライン宣言の記述方法について説明を行っていきます。
内容
- インライン宣言とは?
- インライン宣言の定義方法
- まとめ
インライン宣言とは?
以下のように、これまでABAPの変数は使用する前に、事前の宣言が必要でした。
* 変数
data gf_xxxx type mara-matnr.
* 構造や内部テーブル(型定義も必要となる場合)
types: begin of sty_xxxx,
matnr type mara-matnr,
werks type marc-werks,
lgort type mard-lgort,
end of sty_xxxx,
tty_xxxx type standard table of sty_xxxx.
data: gs_xxxx type sty_xxxx,
gt_xxxx type tty_xxxx.
* フィールドシンボル
FIELD-SYMBOLS: <FS> type i.
インライン宣言は、「事前の変数定義が不要で、必要な場所で変数を定義し初期化することができる」記述方法です。
インライン宣言方法
パターンを見てみましょう。なお、参照データ型のインライン宣言については私の理解度が低いため省略させていただきます。![]()
1. 単一項目
以下のようにして単一項目をインライン宣言することができます。単一項目のインライン宣言の方法は、
DATA(変数名) = 値
となります。定義すると同時に値も設定します。
* 事前定義
DATA lf_integer type i.
lf_integer = 1.
DATA lf_text type c length 4.
lf_text = 'TEST'.
* インライン宣言
DATA(lf_integer) = 1. "整数型
DATA(lf_text) = 'TEST'. "文字型
設定値によって、変数の型は自動的に推察され定義されます。数字のみであれば整数型、文字列であれば文字型で定義されます。しかし、制限事項があります。
- データエレメントやDB項目の型の参照、項目長の指定をすることができません
- 金額や数量など、小数点を使った値をインライン宣言で定義することはできません(’’を使うと一律CHAR型で定義される)
SAPで扱うデータはDBのデータを扱うため、変数に特定の型を持つことが多くなります。上述のとおり、インライン宣言では項目の長さや型を明示的に定義することはできないので、こういったインライン宣言を使う場所は、ワーク変数として使うなどの限定的に状況になると思います。「こんなのABAPHELPのサンプルコードだけで、実際のアドオンのコードには使えないな」と思った方も多いのではないでしょうか。下記はテーブルのエントリにインデックスを採番したい場合のサンプルです。ええ、「これならSY-TABIXでいいでしょ?」なサンプルですが、キーブレイクごとに採番を1からにしたい、など場合などに使うときの基となるコードとして捉えてください![]()
* インライン宣言変数のテーブルインデックスとしての活用
TYPES: BEGIN OF sty,
field1 TYPE c LENGTH 4,
index TYPE i,
END OF sty,
tty TYPE STANDARD TABLE OF sty WITH EMPTY KEY.
DATA(intab) = VALUE tty( ( field1 = 'AAAA' )
( field1 = 'BBBB' )
( field1 = 'CCCC' ) ).
DATA(lw_index) = 1. "テーブルインデックスとしての活用
LOOP AT intab ASSIGNING FIELD-SYMBOL(<fs>) .
<fs>-index = lw_index.
lw_index += 1.
ENDLOOP.
cl_demo_output=>display( intab ).
2. SELECT文内でのデータ格納先
有名かつ有用な内容です。SELECT文内の格納先をインライン宣言で変数定義する方法です。
* 事前宣言の場合
* 格納先の事前宣言(内部テーブルなので型定義から必要)
types: begin of sty_xxxx,
matnr type mara-matnr,
werks type marc-werks,
lgort type mard-lgort,
end of sty_xxxx,
tty_xxxx type standard table of sty_xxxx.
data: gt_xxxx type tty_xxxx.
SELECT from mara as t1
inner join marc as t2
on t1~matnr = t2~matnr
inner join mard as t3
on t2~matnr = t3~matnr
and t2~werks = t3~werks
fields t1~matnr, t2~werks, t3~lgort
into table gt_xxxx.
* インライン宣言の場合
SELECT from mara as t1
inner join marc as t2
on t1~matnr = t2~matnr
inner join mard as t3
on t2~matnr = t3~matnr
and t2~werks = t3~werks
fields t1~matnr, t2~werks, t3~lgort
into table @data(gt_xxxx). "インライン宣言
上記のように記述すると、SELECTで取得する項目の型から自動的に内部テーブルgt_xxxxが作成されます。SELECT SINGLEの場合はINTO〜とすればインライン宣言された変数は構造になります。各項目の型は、定義されたテーブル項目の定義に従って定義され、単一型のような制約は発生しません。SQLでインライン宣言を使う場合は必ずDATA()の先頭に「@」が必要となります。
これにより、内部テーブルや構造の事前宣言(宣言に必要な型定義も含めて)不要となります。
これを見て、「なんだ、SELECTで取ってくる内部テーブルのTYPESは不要にできるのか、じゃあ内部テーブルは全部インライン宣言にしちゃおう」と思ったそこのあなたに、私から耳寄り
なお知らせがあります。
インライン宣言で定義する変数は グローバル項目では使用せず 、サブルーチンやフォーム内で使用するローカルオブジェクトとして使用してください。
アドオンの主要なデータを格納しているテーブルはこれまでどおりTYPESでの型定義をして事前宣言で定義してグローバル項目とすることをお勧めします。理由としては、
- インライン宣言で定義する項目は、宣言した箇所のスコープ(処理ブロックやサブルーチン)でしか使用できない
- プログラム全体で参照するデータに使用するには不向きな上に、サブルーチンなどでの利用もしづらい(テーブル内容を常に全部渡しする必要が発生する)
- TYPESで型が明示的に定義されていないので、コードを見てもテーブルの型がわかりづらい
などが挙げられます。もちろん、そういう記述方法でもOK、というプロジェクトでしたらそれに従っていただければよいかと思います。
3. LOOP文での構造/フィールドシンボルのインライン宣言
こちらも有名かと思いますが、LOOP文の格納先となる構造やフィールドシンボルもインライン宣言で活用できます。
* 事前宣言
(省略)
data: ls_xxxx type sty_xxxx.
Loop at it_xxxx into ls_xxxx.
* インライン宣言
** 構造(新規ではこの書き方はおすすめしません)
loop at it_xxxx into data(ls_xxxx).
** フィールドシンボル
loop at it_xxxx assigning field-symbol(<FS>).
昨今ではフィールドシンボルへのASSIGNINGが主流になっていると思いますが、構造においてもインライン宣言を使用することができます。なお、フィールドシンボルの事前定義は「FIELD-SYMBOLS」ですがインライン宣言の場合は「FIELD-SYMBOL」となります。
4.構造/内部テーブルの定義
構造や内部テーブルもインライン宣言で直接定義できるようになりました。ただし、型定義が必要な場合もあります。以下は内部テーブルの定義のサンプルとなります。
* 型定義が必要な場合
types: begin of sty_xxxx,
matnr type mara-matnr,
werks type marc-werks,
lgort type mard-lgort,
end of sty_xxxx,
tty_xxxx type standard table of sty_xxxx.
** 事前定義型
data: gs_xxxx type sty_xxxx.
data: gt_xxxx type standard table of tty_xxxx.
gs_xxxx-matnr = '1'.
gs_xxxx-werks = '0001'.
gs_xxxx-lgort = '0001'.
append gs_xxxx into gt_xxxx.
gs_xxxx-matnr = '2'.
gs_xxxx-werks = '0001'.
gs_xxxx-lgort = '0001'.
append gs_xxxx into gt_xxxx.
* インライン宣言
data(gt_xxxx) =
value tty_xxxx( ( matnr = '1' werks = '0001' lgort = '0001' )
( matnr = '2' werks = '0001' lgort = '0001' ) ).
* 型定義が不要な場合(テーブルデータ型が事前に定義済みのものを使用する)
data(gt_xxxx) =
value string_table( ( `test1` ) ( `test2` ) (`test3`) ).
data(名称) = value テーブルデータ型( ( 各行の内容 ) … ).
という記述方法となります。各行の内容ごとに()が必要となります。また、構造を定義する場合は、
data(名称) = value 構造型( 内容 ).
となります。これも、1.と同様に、リテラル値を直接設定する事例は少ないのですが、インライン宣言、事前宣言に限らずいろいろな応用ができる記述方法です。今後順次記事を作成しますので、気になった方は今後もチェックをよろしくお願いいたします。
まとめ
以下について説明しました。
- インライン宣言は、必要な場所に定義と値設定を同時に行う便利な記述方法
- ABAP 7.4から利用可能
- インライン宣言を活用すればコード量削減や、見やすさの向上につながる
- インライン宣言で定義する変数は、ローカルオブジェクトとして扱う
- テーブルや構造の定義はいろいろな応用が利く
今回は以上となります。ありがとうございました。
参考にさせていただいた記事