!--a11y-->

ASSIGN 命令の基本フォームは、 次のとおりです。
プログラミング時にフィールドシンボルに割り当てる項目の名前が分かっている場合は、静的 ASSIGN 命令を使用します。
ASSIGN <f> TO <FS>.
データオブジェクトを割り当てると、データオブジェクト <f> の技術属性がフィールドシンボル <FS> のデータ型指定のいずれかと対応しているかがチェックされます。フィールドシンボルは、自分のデータ型指定に含まれない<f> のジェネリック属性を採用します。割当後は、メモリ内の <f> を指します。

REPORT demo_field_symbols_stat_assign .
FIELD-SYMBOLS: <f1> TYPE ANY, <f2> TYPE i.
DATA:
text(20) TYPE c VALUE 'Hello, how are you?',
num
TYPE i VALUE 5,
BEGIN OF line1,
col1 TYPE f VALUE
'1.1e+10',
col2 TYPE i VALUE '1234',
END OF line1,
line2 LIKE line1.
ASSIGN text TO
<f1>.
ASSIGN num
TO <f2>.
DESCRIBE FIELD <f1>
LENGTH <f2>.
WRITE: / <f1>, 'has
length', num.
ASSIGN line1 TO
<f1>.
ASSIGN line2-col2 TO
<f2>.
MOVE <f1> TO
line2.
ASSIGN 'LINE2-COL2 =' TO
<f1>.
WRITE: / <f1>,
<f2>.
出力は次のようになります。
Hello, how are you? has length 20
LINE-COL2 = 1,234
この例では、<F1> と <F2> という 2 つのフィールドシンボルが宣言されています。<F2> のデータ型は I なので、データ型 I の項目しか割り当てることができません。<F1> と <F2> は、プログラム内の別の項目を指しています。
静的 ASSIGN 命令では、ポジティブオフセットと長さを指定して、項目の一部をフィールドシンボルに割り当てることができます。
ASSIGN <f>[+<o>][(<l>)] TO <FS>.
項目の一部をフィールドシンボルに割り当てる場合は、以下の特別な条件が適用されます。
キ 選択された部分が項目 <f> に含まれるかどうかはチェックされません。オフセット <o> と長さ <l> が、<f> より長い場合があります。<f> の外のメモリをアドレスすることもできますが、フィールドシンボルのデータ領域の外のメモリはアドレスできません。
キ 長さ <l> を指定しない場合、項目 <f> の長さが自動的に使われます。<o> が 0 より大きい場合は、<FS> は常に <f> の外の領域を指します。
キ <o> が <f> より短い場合は、<l> にアスタリスク (*) を入力して、<FS> が <f> の外のアドレスを参照するのを防ぐことができます。

REPORT demo_field_symbols_stat_as_off .
FIELD-SYMBOLS <fs> TYPE ANY.
DATA: BEGIN OF line,
string1(10) VALUE
'0123456789',
string2(10) VALUE
'abcdefghij',
END OF line.
WRITE / line-string1+5.
ASSIGN line-string1+5 TO
<fs>.
WRITE /
<fs>.
ASSIGN line-string1+5(*)
TO <fs>.
WRITE /
<fs>.
出力は次のようになります。
56789
56789abcde
56789
この例では、WRITE 命令のオフセット指定と ASSIGN 命令のオフセット指定の違いを見ることができます。WRITE では、LINE-STRING1 の最後の出力は切り詰められます。9 より大きいオフセットを指定すると、構文チェックでエラーとなります。1 つ目の ASSIGN 命令では、LINE-STRING1 のオフセット 5 から長さ 10 のメモリ領域が、フィールドシンボル <FS> に割り当てられます。LINE-STRING1 の後のメモリ領域は LINE-STRING2 に属するので、この出力は役立ちます。2 つ目の ASSIGN 命令では、長さ指定 * により、LINE-STRING1 の後のメモリ領域はアドレスされません。

REPORT demo_field_symbols_stat_as_of2 .
FIELD-SYMBOLS <fs> TYPE ANY.
DATA: BEGIN OF line,
a TYPE c VALUE '1', b TYPE c
VALUE '2',
c TYPE c VALUE '3', d TYPE c
VALUE '4',
e TYPE c VALUE '5', f TYPE c
VALUE '6',
g TYPE c VALUE '7', h TYPE c
VALUE '8',
END OF line,
off TYPE i,
len TYPE i VALUE 2.
DO 2
TIMES.
off = sy-index * 3.
ASSIGN line-a+off(len) TO <fs>.
<fs> = 'XX'.
ENDDO.
DO 8
TIMES.
off = sy-index - 1.
ASSIGN line-a+off(1) TO <fs>.
WRITE <fs>.
ENDDO.
出力は次のようになります。
1 2 3 X X 6 X X
この例では、フィールドシンボルによって一般的な構造へのアクセスや構造の操作が簡単になることが分かります。ただし、このように項目の外のメモリの内容を柔軟に操作することは、危険でもあり、実行時エラーにつながる可能性もあることに注意してください。
プログラミング時にフィールドシンボルに割り当てる項目の名前が分からない場合は、動的 ASSIGN 命令を使用します。
ASSIGN (<f>) TO <FS>.
この命令で、項目 <f> に名前が含まれる項目がフィールドシンボル <FS> に割り当てられます。動的 ASSIGN では、オフセットと長さを指定することはできません。
実行時には、対応するデータオブジェクトが次の順序で検索されます。
...
1. ASSIGN 命令がプロシージャ内にある場合、まずローカルデータが検索されます。
2. ローカルデータ内にオブジェクトがない場合 ( または ASSIGN 命令がプロシージャ内にない場合) は、プログラムのローカルデータが検索されます。
3. 項目がプログラムのグローバルデータにない場合は、現在のプログラムグループのメインプログラムで TABLES 命令によって宣言されたテーブル作業領域が検索されます。プログラムグループは、メインプログラムと他のプログラムコールにより同じ内部セッションにロードされたすべてのプログラムから構成されます。
検索が正常に終了し、項目がフィールドシンボルに割り当てられた場合、SY-SUBRC は 0 に設定されます。検索が正常に終了しなかった場合は、4 に設定され、フィールドシンボルは変更されません。セキュリティを確保するために、動的 ASSIGN の実行後は SY-SUBRC の値を必ずチェックして、フィールドシンボルが間違った領域を指すのを防いでください。
このように項目を検索するとプログラムは遅くなります。したがって、動的 ASSIGN はどうしても必要な場合のみ使用してください。フィールドシンボルにテーブル作業領域を割り当てることがプログラミング時に分かっている場合は、次の動的 ASSIGN 命令バリアントを使用することもできます。
ASSIGN TABLE FIELD (<f>) TO <FS>.
この場合、フィールドシンボルに割り当てられるデータオブジェクトが検索されるのは、現在のプログラムグループのメインプログラムのテーブル作業領域だけです。ABAP オブジェクトはテーブル作業領域をサポートしていないので、このオプションは ABAP オブジェクトでは使用できません。

3 つのプログラムがあるとします。メインプログラム
REPORT demo_field_symbols_dynami_as_1.
TABLES sbook.
sbook-fldate = sy-datum.
PERFORM form1 IN PROGRAM demo_form1.
他の 2 つのプログラム
REPORT demo_form1.
FORM form1.
PERFORM form2 IN PROGRAM demo_form2.
ENDFORM.
および
REPORT
demo_form2.
FORM
form2.
DATA name(20) TYPE c VALUE 'SBOOK-FLDATE'.
FIELD-SYMBOLS
<fs> TYPE ANY.
ASSIGN (name) TO <fs>.
IF sy-subrc EQ 0.
WRITE / <fs>.
ENDIF.
ENDFORM.
出力は次のようになります。
02.06.1998
この時点の内部セッションのプログラムグループは、プログラム DEMO 、MYFORMS1 、MYFORMS2 で構成されています。フィールドシンボル <FS> は、MYFORMS2 で定義されています。動的 ASSIGN 命令の実行後フィールドシンボルが指すのは、メインプログラム DEMO で宣言されたテーブル作業領域 SBOOK のコンポーネント FLDATE です。

REPORT demo_field_symbols_dynami_as_2 .
TABLES sbook.
DATA: name1(20) TYPE c
VALUE 'SBOOK-FLDATE',
name2(20) TYPE c VALUE
'NAME1'.
FIELD-SYMBOLS <fs> TYPE ANY.
ASSIGN TABLE FIELD
(name1) TO <fs>.
WRITE: / 'SY-SUBRC:',
sy-subrc.
ASSIGN TABLE FIELD
(name2) TO <fs>.
WRITE: / 'SY-SUBRC:',
sy-subrc.
出力は次のようになります。
SY-SUBRC: 0
SY-SUBRC: 4
1 つ目の ASSIGN 命令では、テーブル作業領域 SBOOK と SY-SUBRC のコンポーネント FLDATE は 0 に設定されていることが認識されます。2 つ目の ASSIGN 命令では、項目 NAME1 は TABLES 命令ではなく DATA 命令で宣言されているので、項目 NAME1 を見つけることはできません。この場合は、SY-SUBRC は 4 に設定されます。
データオブジェクトの名前を使用せずに、フィールドシンボルを ASSIGN 命令の全バリアントのフィールドシンボルに割り当てることもできます。
ASSIGN <FS1>[+<o>][(<l>)] TO <FS2>.
静的 ASSIGN では、上のようになります。また、
ASSIGN [TABLE FIELD] (<f>) TO <FS2>.
動的 ASSIGN では上のようになります。項目 <f> には、フィールドシンボル<FS1> の名前が含まれています。 <FS1> と <FS2> は、同じ場合があります。

ユニコードシステムのコードは、ユニコード以外のシステムで実行すると別の実行結果になりますので注意してください。
REPORT demo_field_symbols_dynami_as_3 .
DATA: BEGIN OF s,
a TYPE c VALUE '1',
b TYPE c VALUE '2',
c TYPE c VALUE '3',
d TYPE c VALUE '4',
e TYPE c VALUE '5',
f TYPE c VALUE '6',
g TYPE c VALUE '7',
h TYPE c VALUE '8',
END OF s.
DATA off TYPE i.
FIELD-SYMBOLS <fs> TYPE ANY.
ASSIGN s-a TO <fs>.
DO 4 TIMES.
off = sy-index - 1.
IF <fs> IS
ASSIGNED.
ASSIGN
<fs>+off(1) TO <fs>.
IF <fs> IS
ASSIGNED.
WRITE <fs>.
ENDIF.
ENDIF.
ENDDO.
ユニコード以外のシステムでは、出力は次のようになります。
1 2 4 7
このプログラムは、S-A から S-H の 8 つのコンポーネントを持つ構造を宣言し、コンポーネントに 1 から 8 を書き込みます。この文字列は、メモリ内に通常どおり保存されます。コンポーネント S-A は、まずフィールドシンボル <FS> に割り当てられます。DO ループ では、この命令は次のように機能します。
ループパス 1
<FS> は S-A を指し、OFF は 0 で、S-A は <FS> に割り当てられます。
ループパス 2
<FS> は S-A を指し、OFF は 1 で、S-B は <FS> に割り当てられます。
ループパス 3
<FS> は S-B を指し、OFF は 2 で、S-D は <FS> に割り当てられます。
ループパス 4
<FS> は S-D を指し、OFF は 3 で、S-G は <FS> に割り当てられます。
ユニコード環境 (ABAP エディタにユニコード区分が設定されている環境) では、出力は単に次のようになります。
1
2 つ目のループパス以降は、<FS> にはデータオブジェクトは割り当てられません。
