内部テーブル編集(READ、SORT、DESCRIBE)

17.2 内部テーブル編集(READ、SORT、DESCRIBE)

2. 内部テーブル編集(READ、SORT、DESCRIBE)

ここでは、内部テーブルの編集方法として以下を説明します。
内部テーブルを操作する方法として、下記の3つがあります。

  • READ
  • SORT
  • DESCRIBE

READ

READ TABLE命令による内部テーブルの読み込み処理について解説します。
READ TABLE命令は、内部テーブルの単一行を抽出する命令です。
主にREAD TABLE命令の場合は、内部テーブルのレコードを抽出する場合に用います。

READ TABLE命令は指定した内部テーブルから単一行を読み込み、指定した構造に格納します。
読み込むレコードは、WITH KEYオプションで指定します。

例えば「WITH KEY VBELN = ‘100000000’」 とすれば、受注伝票 100000000のレコード(行)が対象となります。
もし、読み込む行が一意にならない場合は、最初に一致するレコードが読み込み対象となります。

したがって、キーの指定が不十分な場合(レコードを一意に特定できない場合)には、意図したものと違うレコードが抽出されてしまいます。
基本は、レコードを一意に指定できるようにKEYを指定しましょう。

READ TABLE命令のイメージ

サンプルコード READ

REPORT ZCUSLIST1_INTERNAL_READ.

DATA: BEGIN OF RECORD1,
COLP TYPE I,
COLQ TYPE I,
END OF RECORD1.

DATA MYTABLE LIKE SORTED TABLE OF RECORD1 WITH UNIQUE KEY COLP.

DO 6 TIMES.
RECORD1-COLP = SY-INDEX.
RECORD1-COLQ = SY-INDEX + 5.
INSERT RECORD1 INTO TABLE MYTABLE.
ENDDO.

READ TABLE MYTABLE  INTO RECORD1 WITH KEY COLQ = 8.

WRITE: 'SY-SUBRC =', SY-SUBRC.
SKIP.
WRITE: / RECORD1-COLP,RECORD1-COLQ.

このサンプルにおけるREAD TABLE命令部分の説明(青字部分)

内部テーブル:MYTABLEから、
項目:COLQの値が8の行を読み込み、
構造:RECORD1に格納しなさい、

という意味の命令になります。

内部テーブル:MYTABLEは、項目:COLPを一意キーとして定義されています。
DO命令の中で、項目:COLP にSY-INDEX(※1参照) の値を代入、
項目:COLQにSY-INDEX + 5の値を代入しています。
よって、項目:COLQの値は、項目:COLPに5を加算した値になります。

従って、READ TABLE命令により内部テーブル:MYTABLEを読み込み際に、項目:COLQをキーとして指定すると、内部テーブル:MYTABLEの行を一意に識別できます。

(※1)SY-INDEXはループカウンタですので、6回DO命令を繰り返す処理の中で、現在何回目を実行中なのかを、システムが返してくれます。

デバッグ機能を利用し、READ TABLE命令実行時の値を確認

実行結果

SORT

内部テーブルを昇順・降順に並び替えるSORT命令について解説します。

SORT命令は並び替え(ソートの優先順や、昇順・降順の混合など)を行う命令です。
SORT命令の処理は、キーによって内部テーブルのレコードをソートします。

この命令では、明示的なソートキーを指定せず、内部テーブル:itabをソートします。
明示的なソートキーを 指定しないと、内部テーブル itab はテーブルキーに従ってソートされます。
オプションASCENDING(昇順)または DESCENDING(降順)を使用して、ソート順を明示的に指定することができます。
指定しないと、デフォルトで昇順にソートされます。
 ASCENDING  ⇒ 昇順(デフォルト)
 DESCENDING ⇒ 降順

昇順ソートの例

内部テーブル:ITAB1のテーブルキーがNUMBERの場合、
 SORT ITAB1.
と記述とすれば、図のようにレコードが並び変えられます。

SORT命令は、キー項目であるNUMBER項目を優先してソートします。

キーは、内部テーブルの宣言時に指定しているものや、標準テーブルのキー項目を参照している項目が該当します。

また、ASCENDING / DESCENDINGオプションを指定していないため、デフォルトで昇順に並び替えされています。
昇順ソートを明示的に指定した、
 SORT ITBA1 ASCENDING.
と同じ意味になります。

ASCENDINGオプションはデフォルトなので、指定する必要性はありませんが、ソースコードの可読性向上を目的として明示する場合があります。
(「SORT命令はデフォルトで昇順にする」と知っている人ばかりではありません。)

降順ソートの例

内部テーブル:ITAB1のキー項目がNUMBERの場合、
 SORT ITBA1 DESCENDING.
と記述した場合、NUMBERをキーに降順に並び替えされます。

SORT BY

明示的なソートキーを指定し、内部テーブルを昇順・降順に並び替えるSORT BY命令について解説します。

この命令では、内部テーブル:itabを、明示的に指定した項目:f1をソートキーとして、ソートします。
ソートキーは複数指定することができます。

オプションASCENDING(昇順)または DESCENDING(降順)を使用して、ソート順を明示的に指定することができます。
指定しないと、デフォルトで昇順にソートされます。
 ASCENDING  ⇒ 昇順(デフォルト)
 DESCENDING ⇒ 降順

サンプルコード SORT BY ASCENDING

REPORT ZR2111ABAPSQL_KANDA01.

*構造定義
DATA: BEGIN OF WK_BKPF,
  BELNR  TYPE BKPF-BELNR,          "会計伝票番号
  BLART  TYPE BKPF-BLART,          "伝票タイプ
  MONAT TYPE BKPF-MONAT,          "会計期間
END OF WK_BKPF.

*内部テーブル定義
DATA: IT_BKPF LIKE STANDARD TABLE OF WK_BKPF.

*テーブル:BKPFから、BELNR(会計伝票番号)、BLART(伝票タイプ)、
*MONAT(会計期間)を抽出し、内部テーブルに格納
SELECT BELNR BLART MONAT FROM  BKPF
  INTO TABLE IT_BKPF
    WHERE  BUKRS  = '1000'
    AND      BELNR  BETWEEN '0000100014' AND '4900000001'
    AND      GJAHR  = '2020'.

*抽出できたことをチェック
CHECK SY-SUBRC = 0.

*内部テーブルを、MONAT(会計期間)の昇順、
*BLART(伝票タイプ)の昇順でソート
SORT IT_BKPF BY MONAT ASCENDING     "会計期間の昇順
                            BLART ASCENDING.     "伝票タイプの昇順

*実行結果画面への書き出し(ヘッダ部分)
WRITE: /'会計期間',
             '伝票タイプ',
             '伝票番号'.

*実行結果画面への書き出し(データ部分)
LOOP AT IT_BKPF INTO WK_BKPF.
  WRITE: / WK_BKPF-MONAT UNDER '会計期間',
                WK_BKPF-BLART  UNDER '伝票タイプ',
                WK_BKPF-BELNR  UNDER '伝票番号'.
  ENDLOOP.

このサンプルにおけるSORT BY ASCENDING命令部分の説明

最初に会計期間の昇順、次に伝票タイプの昇順で、内部テーブル:IT_BKPFを並び替えなさい、
という意味の命令になります。

データベーステーブル:BKPF(会計伝票ヘッダ)の内容

サンプルコードと同様に、会社コード:1000、伝票番号:100014から4900000001、会計年度:2020のデータを取得します。

デバッグ機能にて、SORT BY ASCENDING命令を実行する前後を比較

項目:MONAT(会計期間)の昇順(優先順位1位)、
項目:BLART(伝票タイプ)の昇順(優先順位2位)
でソートされていることが確認できます。

実行結果

補足事項1

このサンプルプログラムは、SORT命令の説明をするために作成したものです。
ソースコードをなるべく短く、見やすくするために、SELECT命令にてデータベーステーブルを抽出する際の条件を、固定値で記入しています。
しかし、本来、伝票番号などの項目はプログラムの実行時に選択画面にて、パラメータ入力するのが一般的です。
ご興味のある方は、7.1 「補足事項1」にパラメータ入力した場合の例を作成しましたので、ご参照ください。

サンプルコード SORT BY DESCENDING

REPORT ZR2111ABAPSQL_KANDA02.

*構造定義
DATA: BEGIN OF WK_BKPF,
  BELNR  TYPE BKPF-BELNR,          "会計伝票番号
  BLART  TYPE BKPF-BLART,          "伝票タイプ
  MONAT TYPE BKPF-MONAT,          "会計期間
END OF WK_BKPF.

*内部テーブル定義
DATA: IT_BKPF LIKE STANDARD TABLE OF WK_BKPF.

*テーブル:BKPFから、BELNR(会計伝票番号)、BLART(伝票タイプ)、
*MONAT(会計期間)を抽出し、内部テーブルに格納
SELECT BELNR BLART MONAT FROM  BKPF
  INTO TABLE IT_BKPF
    WHERE  BUKRS  = '1000'
    AND      BELNR  BETWEEN '0000100014' AND '4900000001'
    AND      GJAHR  = '2020'.

*抽出できたことをチェック
CHECK SY-SUBRC = 0.

*内部テーブルを、MONAT(会計期間)の降順、
*BLART(伝票タイプ)の降順でソート
SORT IT_BKPF BY MONAT DESCENDING     "会計期間の降順
                            BLART DESCENDING.     "伝票タイプの降順

*実行結果画面への書き出し(ヘッダ部分)
WRITE: /'会計期間',
             '伝票タイプ',
             '伝票番号'.

*実行結果画面への書き出し(データ部分)
LOOP AT IT_BKPF INTO WK_BKPF.
  WRITE: / WK_BKPF-MONAT UNDER '会計期間',
                WK_BKPF-BLART  UNDER '伝票タイプ',
                WK_BKPF-BELNR  UNDER '伝票番号'.
  ENDLOOP.

前述のSORT BY ASCENDING命令は、昇順ソートであったのに対し、
ここで説明するSORT BY DESCENDING命令は、降順ソートです。
2つのプログラムの記載の違いは、「ASCENDING」と「DESCENDING」のみです。

このサンプルにおけるSORT BY DESCENDING命令部分の説明

最初に会計期間の降順、次に伝票タイプの降順で、内部テーブル:IT_BKPFを並び替えなさい、
という意味の命令になります。

データベーステーブル:BKPF(会計伝票ヘッダ)の内容

サンプルコードと同様に、会社コード:1000、伝票番号:100014から4900000001、会計年度:2020のデータを取得します。

デバッグ機能にて、SORT BY DESCENDING命令を実行する前後を比較

項目:MONAT(会計期間)の降順(優先順位1位)、
項目:BLART(伝票タイプ)の降順(優先順位2位)
でソートされていることが確認できます。

実行結果

DESCRIBE

ABAPにおける内部テーブルの属性を読み込む命令「DESCRIBE TABLE」について解説します。
DESCRIBE TABLE命令は、指定した内部テーブルの属性を読み取る命令です。
読み取りたい内部テーブルの属性に応じてオプションがあり、オプションなしではDESCRIBE TABLE命令を利用することはできません。
必ず、いずれかのオプションを指定する必要があります。
DESCRIBE TABLE命令の2つのオプション
 ・LINESオプション:内部テーブルの行数を取得
 ・KINDオプション:内部テーブルのテーブルタイプを取得

DESCRIBE LINES

ABAPにおける内部テーブルの属性を読み込む命令「DESCRIBE TABLE」で、LINESオプションを利用すると、内部テーブルの行数を判別することができます。
判別した行数については、LINESオプションの後に指定した変数に格納されます。

LINESオプションの後に指定する変数には、整数しか入りませんのでデータ型は「i(整数)」でなければなりません。

DESCRIBE LINESの例

DESCRIBE TABLE ITAB1 LINES Z_i.
と記述しますと、内部テーブル「ITAB1」の内容が以下の場合、変数「Z_i」には「9」が格納されます。

DESCRIBE KIND

KINDオプションは、指定した内部テーブルのテーブルタイプを判別することができます。
KINDオプションの後に指定した変数には、テーブルタイプに応じて以下のいずれかの文字が格納されます。

 ・標準テーブルの場合「T」
 ・ソートテーブルの場合「S」
 ・ハッシュテーブルの場合「H」

サンプルコード DESCRIBE

REPORT ZR2111ABAPSQL_KANDA03.

*変数定義
DATA: WK_LINES   TYPE I.                  "行数
DATA: WK_KIND(1) TYPE C.                 "テーブルタイプ

*構造定義
DATA: BEGIN OF WK_BNKA,
  BANKL  TYPE BNKA-BANKL,          "銀行コード
END OF WK_BNKA.

*内部テーブルを標準テーブルとして定義
DATA: IT_BNKA LIKE STANDARD TABLE OF WK_BNKA.

*テーブル:BNKAから、BANKL(銀行コード)を抽出し、内部テーブルに格納
SELECT BANKL FROM BNKA
  INTO TABLE IT_BNKA
    WHERE  BANKS  = 'JP'.                  "銀行国コード

*抽出できたことをチェック
CHECK SY-SUBRC = 0.

*内部テーブルの行数を取得し、書き出す
DESCRIBE TABLE IT_BNKA LINES WK_LINES.
WRITE: /'内部テーブルの行数',
             WK_LINES.

*内部テーブルのテーブルタイプを取得し、書き出す
DESCRIBE TABLE IT_BNKA KIND WK_KIND.
WRITE: /'内部テーブルのテーブルタイプ',
             WK_KIND.

SKIP.
*内部テーブルの内容の書き出し
WRITE: /'銀行コード'.
LOOP AT IT_BNKA INTO WK_BNKA.
  WRITE: / WK_BNKA-BANKL UNDER '銀行コード'.
  ENDLOOP.

データベーステーブル:BNKA(銀行マスタ)の内容

サンプルコードと同様に、銀行国コード:JPのデータを取得します。
17件あります。

デバッグ画面にて、確認

内部テーブル:IT_BNKAは17行あります。
よって、DESCRIBE TABLE LINES命令により、内部テーブルの行数を取得すると、
変数:WK_LINESには17が入ります。

また、内部テーブル:IT_BNKAのテーブルは標準テーブルとして定義されていますので、
DESCRIBE TABLE KIND命令により、内部テーブルのテーブルタイプを取得すると、
変数:WK_KINDにはTが入ります。

実行結果


NEXT>> 17.3 SELECT (For All Entries、 JOIN)