READ TABLE は指定した内部テーブルから特定の1レコードを読み取るABAPの命令です。
参考 内部テーブルとは?
READ TABLE <itab> [options]. * <itab> は読み取る内部テーブル
このページではABAP初心者向けにREAD TABLEの使い方やコツ、注意点をわかりやすく3分で解説します。
ABAPer/SAPエンジニアを目指す方であれば知らないと恥ずかしい超・基本知識の1つです。是非最後までご覧ください。
参考 ABAPの基本構文ルール
READ TABLE命令
READ TABLE命令は、内部テーブルから1つのレコードを読み取るために使用されます。特定のキーまたはインデックスを指定して、特定のレコードを選択的に読み取ることができます。
READ TABLE命令は内部テーブルの単一行を抽出する命令です。複数レコードを抽出することはできません。あくまでも単一レコードのみを読み込む処理を行うのが、READ TABLE命令という点を押さえておきましょう。
この点、SELECT-SINGLEと似たような動きをします。この機会に、整理して理解しておくように心がけましょう。
前提を押さえたところで、READ TABLE文の書き方・使い方を学習していきましょう。
構文ルール:READ TABLE
READ TABLE <itab> [options]. * <itab> は読み取る内部テーブル
READ TABLEの基本的なサンプルコードをお見せしつつ、オプションの利用方法もあわせてご説明していきます。
READ TABLE:WITH KEY
WITH KEY オプションを利用することで特定のキーで内部テーブルを検索することができます。
例えば、persons
という内部テーブルがあり、その中から name
が 'John' という人物を探す場合は以下のようになります。
DATA: lt_persons TYPE TABLE OF person_type, wa_person TYPE person_type. READ TABLE lt_persons WITH KEY name = 'John' INTO wa_person.
lt_persons
という内部テーブルから name
が 'John' の行を探し、そのデータを wa_person
というワークエリアに格納します。この時、データが見つからない場合は SY-SUBRC
というシステム変数に 4 が設定されます。
SY-SUBRC | 意味 |
---|---|
0 | 読み取りに成功 |
0以外 | 読み取りに失敗(条件により4や8が設定される) |
READ TABLE:INDEX
INDEXオプションを使用してREAD TABLE文を書くと、内部テーブルから特定の位置の行を読み取ることができます。INDEXは1から始まります。
DATA: lt_persons TYPE TABLE OF person_type, wa_person TYPE person_type. " 仮に、3番目のレコードを取得したい場合 READ TABLE lt_persons INDEX 3 INTO wa_person. IF sy-subrc = 0. WRITE: / '名前:', wa_person-name. ELSE. WRITE: / '指定したインデックスのレコードは存在しません'. ENDIF.
この例では、lt_persons
という内部テーブルから3番目のレコードを取得し、そのデータをwa_person
というワークエリアに格納しています。その後、システムフィールドsy-subrc
をチェックして、読み込みが成功したかどうかを確認し、結果を表示しています。
このように、INDEXオプションを使用すると、内部テーブルの任意の位置にあるレコードを直接読み取ることができます。ただし、テーブルのサイズを超えるインデックスを指定すると、エラーになるので注意が必要です。
READ TABLE:TRANSPORTING
TRANSPORTINGオプションを使用すると、内部テーブルからデータを読み取る際に特定のフィールドだけを読み取ることができます。これは主にパフォーマンスを改善するために用いられます。
DATA: lt_persons TYPE TABLE OF person_type, wa_person TYPE person_type. " 仮に、名前が 'John' の人物の年齢(age)だけを読み取りたい場合 READ TABLE lt_persons WITH KEY name = 'John' TRANSPORTING age INTO wa_person. IF sy-subrc = 0. WRITE: / '年齢:', wa_person-age. ELSE. WRITE: / '指定した名前のレコードは存在しません'. ENDIF.
この例では、lt_persons
という内部テーブルから name
が 'John' のレコードを探し、そのデータの age
フィールドだけを wa_person
というワークエリアに格納しています。その後、システム変数 sy-subrc
をチェックして読み取りが成功したかどうかを確認し、結果を表示しています。
このように、TRANSPORTINGオプションを使用すると、必要なフィールドだけを読み取ることができます。
READ TABLE:INTO
INTOオプションを使用すると、内部テーブルから読み取ったデータを指定した変数(ワークエリアやフィールドシンボル)に格納することができます。
DATA: lt_persons TYPE TABLE OF person_type, wa_person TYPE person_type. " 仮に、名前が 'John' の人物のデータを読み取りたい場合 READ TABLE lt_persons WITH KEY name = 'John' INTO wa_person. IF sy-subrc = 0. WRITE: / '名前:', wa_person-name, '年齢:', wa_person-age. ELSE. WRITE: / '指定した名前のレコードは存在しません'. ENDIF.
この例では、lt_persons
という内部テーブルから name
が 'John' のレコードを探し、そのデータを wa_person
というワークエリアに格納しています。その後、システム変数 sy-subrc
をチェックして読み取りが成功したかどうかを確認し、結果を表示しています。
このように、INTOオプションを使用すると、読み取ったデータを他の変数に直接格納することができます。
READ TABLE:ASSIGNING
INTOの代わりに、ASSIGNINGオプションを利用することで、読み込んだレコードをフィールドシンボルに代入することができます。
実際の現場では、INTOよりもASSIGNINGの方が頻繁に利用されます。
参考 フィールドシンボルとは?
DATA: lt_persons TYPE TABLE OF person_type, fs_person TYPE REF TO person_type. " 仮に、名前が 'John' の人物のデータを読み取りたい場合 READ TABLE lt_persons WITH KEY name = 'John' ASSIGNING FIELD-SYMBOL(<fs_person>). IF sy-subrc = 0. WRITE: / '名前:', <fs_person>-name, '年齢:', <fs_person>-age. ELSE. WRITE: / '指定した名前のレコードは存在しません'. ENDIF.
この例では、lt_persons
という内部テーブルから name
が 'John' のレコードを探し、そのデータを <fs_person>
というフィールドシンボルに割り当てています。その後、システム変数 sy-subrc
をチェックして読み取りが成功したかどうかを確認し、結果を表示しています。
フィールドシンボルを使うと、データのコピーを作成せずにデータを操作することができ、パフォーマンスを改善することができます。また、行を直接変更する場合もフィールドシンボルを使うことが一般的です。
READ TABLE
は非常に強力で、その機能は多岐にわたります。上記で説明したオプションは、基本的なものをカバーしていますが、他にもいくつかの重要なオプションが存在しますので、以下に補足的にご紹介させていただきます。
READ TABLEの基本的な使い方はこれで以上です。最後に、より実践的な使い方をTipsとしてご紹介します。
Tips1:READ TABLEで複数レコードを読み取る
READ TABLE
は通常、内部テーブルから1つのレコードを読み取るために使用されます。が、複数のレコードを取得したいようなシーンも存在することもしばしば。
ここでは、LOOP命令を利用することでREAD TABLE文で複数レコードを取得する方法をご紹介します。
DATA: lt_persons TYPE TABLE OF person_type, wa_person TYPE person_type. LOOP AT lt_persons INTO wa_person. WRITE: / wa_person-name. ENDLOOP.
参考 LOOP命令
この例では、LOOP AT ... ENDLOOP
構造を使用して lt_persons
内部テーブルのすべてのレコードを順番に読み取り、それぞれの名前を出力しています。このようにループを使用することで、複数のレコードを一度に処理することが可能です。
なお、特定の条件を満たすすべてのレコードを選択的に読み取る場合には、READ TABLE
と組み合わせて LOOP AT ... WHERE
構造を使用することもできます。
以下の例では、名前が 'John' のすべてのレコードを読み取り、それぞれの名前を出力しています。
DATA: lt_persons TYPE TABLE OF person_type, wa_person TYPE person_type. LOOP AT lt_persons INTO wa_person WHERE name = 'John'. WRITE: / wa_person-name. ENDLOOP.
Tips2:TRANSPORTING NO FIELDS
TRANSPORTING NO FIELDSオプションを使用すると、内部テーブルの特定の行が存在するかどうかを確認することができます。このオプションはデータを読み込むのではなく、単に行が存在するかどうかをチェックします。
DATA: lt_persons TYPE TABLE OF person_type. " 仮に、名前が 'John' の人物がテーブル内に存在するかを確認したい場合 READ TABLE lt_persons WITH KEY name = 'John' TRANSPORTING NO FIELDS. IF sy-subrc = 0. WRITE: / '指定した名前のレコードが存在します'. ELSE. WRITE: / '指定した名前のレコードは存在しません'. ENDIF.
この例では、lt_persons
という内部テーブルから name
が 'John' のレコードが存在するかをチェックしています。その後、システム変数 sy-subrc
をチェックして該当する行が存在したかどうかを確認し、結果を表示しています。
このように、TRANSPORTING NO FIELDSオプションを使用すると、特定の行が存在するかどうかを確認することができます。
SAP/ABAPを1から勉強したい方は
初めてABAPを勉強するのは結構難しいですよね。
でもその悩みを抱えているのは一人じゃありません。全てのABAP使いが同じ道を進んできました。
ABAPをはじめとするプログラミングスキルを武器に、時間と場所に捉われない自由な生き方を目指してみませんか?
読者料典 【完全無料】ABAP:学習カリキュラム ←こちらから!