【ABAP】FIELD-SYMBOLS―フィールドシンボル―意味と使い方

ABAP

本ページではフィールドシンボル(FIELD-SYMBOLS命令)の解説をします。

「フィールドシンボル」は、フィールドシンボル単体で説明するとかえって混乱します。というのも、「フィールドシンボル」単体で利用するシーンがほとんどないためです。

このページでは、FIELD-SYMBOLS命令とセットで使うことが多いLOOP処理をもとに解説を進めていきます。

本ページでは、DATA命令がなんとなくわかっていることと、内部テーブル・構造がなんとなくわかっていること、そしてLOOP処理がなんとなくわかっている前提の説明となります。

それぞれに関して詳しく説明した記事を以下に記載しますので、不安な方は一度そちらを読んでから本編にお進みください。

それでは早速説明を始めます。

スポンサーリンク
スポンサーリンク

構文ルール:FIELD-SYMBOLS命令

FIELD-SYMBOLS <フィールドシンボル名> .

FIELD-SYMBOLS命令では<>が必須です。<>によって、それがフィールドシンボルであると識別されます。<>は必ず指定する必要があります。

FIELD-SYMBOLS <フィールドシンボル名> TYPE ~.

のようにDATA命令と同じくデータ型を定義することも可能です。実際はデータ型を指定する後者の利用がメインです。

フィールドシンボルとは?

フィールドシンボルとは何か?

一言で言えば、データオブジェクトを間接的に指し示す「カーソル」のような役割を果たします。プログラミングに明るい人であれば「デリファレンス」するようなものとお考え下さい。

言葉で説明しても、うまく理解できない人が大半かと思いますので、LOOP処理の中での実際の使われ方を見て理解をしていきましょう。

フィールドシンボルを利用した構文例

LOOP AT IT_test001 ASSIGNING  FIELD-SYMBOL(<fs001>)
  WHERE VBELN IS NOT INITIAL.
  LW_VBELN-SIGN   = 'I'.
  LW_VBELN-OPTION = 'EQ'.
  LW_VBELN-LOW    = <fs001>-VBELN.
  APPEND LW_VBELN TO LIT_VBELN.	 
ENDLOOP.

LOOP処理の中でフィールドシンボルを利用したコーディングです。

最終的にこのコードが理解できれば、OKです。

フィールドシンボルを利用する場合、利用しない場合をそれぞれ説明していきます。その中でどのようにフィールドシンボルが働いているかをイメージしていきましょう。

フィールドシンボルを利用しない場合の構文例

DATA: (構造a) LIKE LINE OF (内部テーブルa).
LOOP AT (内部テーブルa) INTO (構造a).
  WHERE VBELN IS NOT INITIAL.
  CLEAR LW_VBELN.
  LW_VBELN-SIGN   = 'I'.
  LW_VBELN-OPTION = 'EQ'.
  LW_VBELN-LOW    = (構造a)-VBELN.
  APPEND LW_VBELN TO LIT_VBELN.	 
ENDLOOP.

フィールドシンボルを利用しない普通のLOOP~ENDLOOP構文です。

1行目:  DATA: (構造名)LIKE LINE OF (内部テーブル).

1行目では、上記構文を用いて、構造を定義しています。

2行目:  LOOP AT (内部テーブル) INTO (構造名).

2行目~9行目では、LOOP~ENDLOOPの処理を定義してします。

内部テーブルのレコードを構造に格納していくLOOP処理です。8行目までの処理が完了したら、また3行目に戻って、次のレコードの処理に移ります。

3行目:  WHEREVBELN IS NOT INITIAL.

"VBELN" とは、内部テーブルの項目のことで、この項目が空欄ではない場合に4行目以降の処理を実行することを定義しています。

3行目~8行目:LOOP内の実際の処理を定義します。

4行目:  CLEAR LW_VBELN.

4行目:事前定義していた "LW_VBELN" の値を消去しています。LOOPの処理が始まる前に入っていた値がある想定の記述です。今回の場合はこの記載が無くても問題ありませんが、LOOP ATを利用する場合は毎回記述しておくとよいでしょう。ほぼ「おまじない」的に毎回コーディングしておきましょう。

5行目:  LW_VBELN-SIGN= 'I'.
      LW_VBELN-OPTION
= 'EQ'.
      LW_VBELN-LOW
= (構造名)-VBELN.

5行目~7行目: "LW_VBELN" に値を格納しています。5行目、6行目では固定値を、7行目には2行目(LOOP AT~)で構造に格納されたレコードを格納しています。

※念のための解説ですが、ABAPの世界では "=" (イコール)で結んだ場合、右から左に値が格納されるということを表します・

8行目:  APPEND LW_VBELNTO LIT_VBELN.

8行目では、"LW_VBELN" (構造)に格納されたデータを "LIT_VBELN" (内部テーブル)に格納します。

いたって単純なLOOP処理ですが、このLOOP処理には欠陥があり今ではあまり利用されません。

フィールドシンボルを利用しない場合の欠陥

欠陥は何か?答えはパフォーマンスです。

上記処理では、1回のLOOPごとに予め定義した構造にデータを格納しています。LOOP処理では100回以上繰り返すこともごく普通に存在しますが、そのたび構造へ実データを格納していると、処理が非常に重くなってしまいます。

LOOP処理ではパフォーマンスの観点で欠点を持っていました。

その短所を補うために利用されるのが、フィールドシンボルなんです。

フィールドシンボルはデータを格納しない

フィールドシンボルは実データを格納しません。格納するのではなく、格納すべきデータを指し示す役割を担っています

早速下記コード例を見てみましょう。

FIELD-SYNBOL:<fs001> LIKE LINE OF IT_test001. 
LOOP AT IT_test001 ASSIGNING <fs001>
  WHERE VBELN IS NOT INITIAL.
  LW_VBELN-SIGN   = 'I'.
  LW_VBELN-OPTION = 'EQ'.
  LW_VBELN-LOW    = <fs001>-VBELN.
  APPEND LW_VBELN TO LIT_VBELN.	 
ENDLOOP.

今回の例では、1行目でフィールドシンボルを定義しています。先ほどは実データを格納するための構造を定義していましたが、今回のコードでは構造は利用しないため定義していません。

代わりに

FIELD-SYNBOL <fs001> LIKE LINE OF IT_test001.

という形で、フィールドシンボルを宣言しています。

LOOP AT ASSIGNING<フィールドシンボル名>

先ほどは "ASSIGNING" ではなく、"INTO" を利用していましたね。コーディング上で異なるのはこの点だけです。

では、処理の内容はどう変わるか?

フィールドシンボルを利用しない場合、構造に実データを格納していましたが、今回は「実データを格納していない」んです!

では何を格納しているか?

答えは、「何行目のデータを見ればよいか」という位置情報です。

フィールドシンボルはデータの位置情報

何度も説明しますが、フィールドシンボルに実データは格納されていません。

格納されているのは、データの位置情報です。

フィールドシンボルは、テーブルに当たっているカーソルのようなイメージで理解いただければわかりやすいかと思います。

ASSIGNINGとは、日本語で「割り当て」という意味です。つまり、LOOPする内部テーブルに「割り当て」て利用する(カーソルを当てておく)だけであってデータの格納はしないというのが正しい理解です。

その上で、以下の構文の意味を考えてみましょう。

LW_VBELN-LOW = <フィールドシンボル名>-VBELN.

先ほどは、"(構造名)"としていた箇所が、今回は フィールドシンボル名になっています。

※フィールドシンボルを表す場合は必ず<>でくくります。

データが格納されていないはずのフィールドシンボルから "LW_VBELN-LOW" に値を格納するロジックは以下の通りで流れます。

① フィールドシンボルが指し示すデータの位置情報を読み取る

② 位置情報が指し示す先のデータを読み取る

③ データを " LW_VBELN-LOW " に格納する

いかがでしょうか?

フィールドシンボルを利用すれば、LOOP処理の中で構造へのデータ格納がない分、メモリの消費を節約できるのです。

最新のフィールドシンボルのコード例 

以下のコードをご覧ください。

LOOP AT IT_test001 ASSIGNING  FIELD-SYMBOL(<fs001>)
  WHERE VBELN IS NOT INITIAL.
  LW_VBELN-SIGN   = 'I'.
  LW_VBELN-OPTION = 'EQ'.
  LW_VBELN-LOW    = <fs001>-VBELN.
  APPEND LW_VBELN TO LIT_VBELN.	 
ENDLOOP.

ここでは、フィールドシンボルを事前定義するのではなく、インライン定義しています。

先ほどは、LOOP処理の前に事前にフィールドシンボルの型を定義していました。が、ここではLOOP処理の記述の際、唐突にフィールドシンボルが現れます。

この場合、データ型を定義しなくて良いのか?という疑問が残りますが、大丈夫なんです。

もう一度、先ほどの構文を見てみましょう。

FIELD-SYNBOL:<fs001> LIKE LINE OF IT_test001. 
LOOP AT IT_test001 ASSIGNING <fs001>
  WHERE VBELN IS NOT INITIAL.
  LW_VBELN-SIGN   = 'I'.
  LW_VBELN-OPTION = 'EQ'.
  LW_VBELN-LOW    = <fs001>-VBELN.
  APPEND LW_VBELN TO LIT_VBELN.	 
ENDLOOP.

よく見てみてください。LOOPする内部テーブルの構造と、フィールドシンボルの構造は「常に同じ」ですよね?

なので、最新のABAPでは、わざわざ定義する必要をなくしたのです。

LOOP処理内で定義されたフィールドシンボルは、常に割り当てる内部テーブルと同じ構造を持っているという性質を利用し、インライン定義を可能にしています。

タイトルとURLをコピーしました