PR

【ABAP】READ TABLE―内部テーブルの読み込みを1分で解説

ABAP

READ TABLE は指定した内部テーブルから特定の1レコードを読み取るABAPの命令です。

参考 内部テーブルとは?

READ TABLE <itab> [options].
* <itab> は読み取る内部テーブル

このページではABAP初心者向けにREAD TABLEの使い方やコツ、注意点をわかりやすく3分で解説します。

このページで学べる内容
  • READ TABLE命令とSELECT文の違い
  • READ TABLE:構文ルール
    • WITH KEY オプション
    • IDNEX オプション
    • TRANSPORTING オプション
    • INTO オプション
  • Tips①:LOOP文との組み合わせ
  • Tips②:TRANSPORTING NO FIELDS

ABAPer/SAPエンジニアを目指す方であれば知らないと恥ずかしい超・基本知識の1つです。是非最後までご覧ください。

参考 ABAPの基本構文ルール

スポンサーリンク

READ TABLE命令

READ TABLE命令は、内部テーブルから1つのレコードを読み取るために使用されます。特定のキーまたはインデックスを指定して、特定のレコードを選択的に読み取ることができます。

SELECT文との混同に注意

SELECT文は、データベースからデータを取得するために使用されます。

よく初心者の方がSELECTとREAD TABLEを混同して理解してしまっているようなのでこの点は前提としてしっかり覚えておきましょう。

READ TABLE vs SELECT
  • READ TABLE
    内部テーブルからレコードを読み込む(取得する)
  • SELECT
    標準テーブル/アドオンテーブルからレコードを読み込む

参考 SELECT命令

READ TABLE命令は内部テーブルの単一行を抽出する命令です。複数レコードを抽出することはできません。あくまでも単一レコードのみを読み込む処理を行うのが、READ TABLE命令という点を押さえておきましょう。

この点、SELECT-SINGLEと似たような動きをします。この機会に、整理して理解しておくように心がけましょう。

前提を押さえたところで、READ TABLE文の書き方・使い方を学習していきましょう。

構文ルール:READ TABLE

READ TABLE:構文ルール
READ TABLE <itab> [options].
* <itab> は読み取る内部テーブル
READ TABLEのオプション
  • WITH KEY:
    特定のキーで内部テーブルを検索できます。
  • INDEX:
    特定のインデックス位置の行を読み取ることができます。
  • TRANSPORTING:
    特定のフィールドだけを読み取ることができます。
  • INTO:
    読み取ったデータを他の変数に格納することができます。
  • ASSIGNING:
    このオプションを使用すると、フィールドシンボルを使用して、読み込んだ行への参照を直接取得することができます。これにより、データのコピーを作成せずに、テーブルのデータを直接操作することができます。

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.

参考 DATA命令 / 内部テーブル定義

lt_persons という内部テーブルから name が 'John' の行を探し、そのデータを wa_person というワークエリアに格納します。この時、データが見つからない場合は SY-SUBRC というシステム変数に 4 が設定されます。

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のオプション
  • WITH KEY:
    特定のキーで内部テーブルを検索できます。
  • INDEX:
    特定のインデックス位置の行を読み取ることができます。
  • TRANSPORTING:
    特定のフィールドだけを読み取ることができます。
  • INTO:
    読み取ったデータを他の変数に格納することができます。
  • ASSIGNING:
    このオプションを使用すると、フィールドシンボルを使用して、読み込んだ行への参照を直接取得することができます。これにより、データのコピーを作成せずに、テーブルのデータを直接操作することができます。

READ TABLEは非常に強力で、その機能は多岐にわたります。上記で説明したオプションは、基本的なものをカバーしていますが、他にもいくつかの重要なオプションが存在しますので、以下に補足的にご紹介させていただきます。

  • BINARY SEARCH
    これは、内部テーブルがソートされている場合に、バイナリ検索を使用してデータを検索するために使用されます。バイナリ検索は、標準のリニア検索よりも高速であるため、大きなテーブルで有効です。
  • COMPARING
    このオプションを使用すると、特定のフィールドでのみ比較を行い、その他のフィールドを無視することができます。
  • NO BINARY SEARCH
    このオプションを使用すると、バイナリ検索を無効にし、リニア検索を使用します。これは、テーブルがソートされていない場合や、小さなテーブルで有効です。

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をはじめとするプログラミングスキルを武器に、時間と場所に捉われない自由な生き方を目指してみませんか?

あなたの技術、もっと価値ある場所で活かしませんか?
SAPエンジニアのキャリア支援はこちらから↓

No.1 > 外資系・IT業界などハイクラスの転職なら【アクシスコンサルティング】blank
4人に1人のコンサルタントが選ぶパートナー!
ビッグ4やアクセンチュアへの転職を実現し年収1000万へ。

No.2 > IT・Web転職特化エージェント【レバテックキャリアblank
blank
サービス利用者数20万人突破。

平均年収アップ率77%であなたの転職成功を保証します。

No.3 > blankリクルートエージェント
blank
\転職支援実績NO.1/

応募が殺到しすぎるが故に・・・非公開にせざるを得ない魅力的な求人が多数!

読者料典 【完全無料】ABAP:学習カリキュラム ←こちらから!

このWebサイトは現役のエンジニアが以下3点を目的として運営しています。

  1. 勉強:一度理解した内容を忘れないように。
    → アウトプットは「最強のインプット」である! 
  2. 備忘:忘れたとしても後から見返せるように。
    → 未来の自分への「お手紙」を書いています。 
  3. 共有:〇〇ってこうだったんだ!の感動をシェアできるように。
    → あなたの知識は誰かにとっての「価値ある情報」です。 

副業ブログの始め方はこちらから

スポンサーリンク
ABAPSAP
シェアする
ビズドットオンラインをフォローする
タイトルとURLをコピーしました