内部テーブル編集(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が入ります。