ABAP フィールドシンボル(Field Symbol)の使い方

  データ定義&編集

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

ABAPではDATA命令を使い、変数・構造・内部テーブル等を宣言し実体のある箱(物理的なメモリ)を確保しているが、フィールドシンボルでは実体がなく、割り当てられた(Assign)されたデータに直接アクセスする事ができる命令となる。
個人的には、内部テーブルを更新する際に使用する事が多い。
実際のサンプルを用い違いを確認してみよう。

フィールドシンボルの宣言

フィールドシンボルを宣言するには、以下の構文を使用する。

FIELD-SYMBOLS [< データ型 >|STRUCTURE <s> DEFAULT <wa>].
例:
FIELD-SYMBOLS <FS> TYPE MATNR.

タイプを指定しない場合は、TYPE ANYで宣言することができる。
例:
FIELD-SYMBOLS TYPE ANY.
FIELD-SYMBOLS TYPE ANY TABLE.

基本的な使い方

筆者は、下記のようにMODIFY命令を省略する際にフィールドシンボルを使う事が多い。LOOPの中でAPPEND命令を使って、異なる内部テーブルを作るようなケースではどちらを使っても差異は特にないと考えられる。

サンプルコード:内部テーブルの更新方法の違い

DATA命令を使った場合:

DATA IT_MARA TYPE TABLE OF MARA.
DATA WA_MARA TYPE MARA.

LOOP AT IT_MARA INTO WA_MARA.
  WA_MARA-XXXX = 'XXXXXXXXXXXXX'.
  MODIFY IT_MARA FROM WA_MARA.
ENDLOOP.

SQLは省略している為、MARAのデータを取得した後に動いていると想像してください。内部テーブル:IT_MARAをLOOPし、WA_MARAに格納している。
そして、WA_MARAの各項目を編集して、編集した結果を内部テーブル:IT_MARAに反映するという処理になっている。
この処理をフィールドシンボルを使って書くと以下になる。

フィールドシンボルを使った場合:

DATA IT_MARA TYPE TABLE OF MARA.
FIELD-SYMBOLS <WA_MARA> TYPE MARA.

LOOP AT IT_MARA ASSIGNING <WA_MARA>.
<WA_MARA>-XXXX = 'XXXXXXXXXXXXX'.
ENDLOOP.

フィールドシンボルの変数は必ず<>(括弧)で括る必要がある。
またLOOPではINTOを使用していたものを、ASSIGNとする必要がある。
前述したようにASSIGN元であるIT_MARAに直接アクセスして変更している為、MODIFY命令で更新せずとも、<WA_MARA>を変更した瞬間にIT_MARAの値も更新される事となる。

サンプルコード:定義の省略

上記の例をもう少し簡略化して書いてみよう。

DATA IT_MARA TYPE TABLE OF MARA.
LOOP AT IT_MARA ASSIGNING FIELD-SYMBOL(<WA_MARA>).
  <WA_MARA>-XXXX = 'XXXXXXXXXXXXX'.
ENDLOOP.

簡略化できているとは言いづらいが、フィールドシンボルの定義を上記のように書く事も可能だ。

フィールドシンボルの割り当て

ASSIGN命令を使用して割り当てを行います。

DATA: text(20)  TYPE c VALUE 'Hello, how are you?'.
DATA: v_text(20) TYPE c VALUE 'Hello world'.
FIELD-SYMBOLS: <f1> TYPE any.

ASSIGN v_text TO <f1>. 

フィールドシンボルの割り当て済みチェック

LOOPで使うフィールドシンボルの場合は必ず割り当てられている為、必要ありませんが、READ TABLEした際にSY-SUBRCを確認していない場合や、個別にASSIGN命令を使って割り当てた場合は必ず割り当て済みかをチェックしましょう。もし割りあたっていないフィールドシンボルを使用した場合、プログラムはショートダンプとなってしまうので是非気をつけていただきたい点です。

IF <fs> IS ASSIGNED.
*** フィールドシンボルを使う事ができる
ENDIF.

フィールドシンボルの割り当て解除

一度しか使わないフィールドシンボルであれば意識する必要はないが、繰り返し使用されるフィールドシンボルの場合は解除して割り当てるようにしよう。

IF <fs> IS ASSIGNED.
  UNASSIGN <fs>.
ENDIF.
ASSIGN v_text TO <fs>.