内部テーブルの種類

14.2 内部テーブルの種類

2. 内部テーブルの種類

内部テーブルには、以下の3種類があります。

  • 標準テーブル
  • ソートテーブル
  • レンジテーブル

標準テーブル

標準テーブルは、もっとも基本の内部テーブルです。
追加した順(挿入順)のままデータが並ぶため、一覧表示・順番を保ったまま処理したい場面でよく使います。
順序やキーに関係なく、抽出したデータがそのままの形で格納されています。
また単に、「TYPE TABLE OF」と記述した時は、標準テーブルの宣言とみなされます。
※ただし、可読性から標準テーブルは、略さず「TYPE STANDARD TABLE OF」と宣言することが通例となっています。
(案件によって違います。
)

内部テーブル:標準テーブル

※DBテーブルはデータ型ではないが、SAPシステム上ではDBテーブルの構造を参照するようにSAPシステムの仕様として構築されており、DBテーブルを型として指定すると内部テーブルを作成します。

※アクセス時間は、標準テーブル内のデータの数に比例します。

「サンプルコード」①

REPORT ZFUJII_SAMPLE141_NEW.

" 1行の型(行タイプ)はDDICテーブル/構造を参照するのが実務では一般的
TYPES TY_CUSTOMER_TAB TYPE STANDARD TABLE OF ZFUJII_DB01 WITH EMPTY KEY.

START-OF-SELECTION.

" DBから複数行を取得
  SELECT *
    FROM ZFUJII_DB01
    INTO TABLE @DATA(LT_CUSTOMERS).

  " 一覧表示(簡易)
  LOOP AT LT_CUSTOMERS INTO DATA(LS_CUSTOMER).
    WRITE: / LS_CUSTOMER-KUNNR, LS_CUSTOMER-NAME1, LS_CUSTOMER-NAME2.
  ENDLOOP.

END-OF-SELECTION.

実行結果

ソートテーブル

ソートテーブルは、指定したキー順で並ぶ状態を内部的に維持する内部テーブルです。
格納されているデータを、あるキーによって並び替えることができます。
データを格納する際に、指定したキーでソートをかけてから格納するため、標準テーブルと比べて時間がかかってしまいます。
その反面、ソートテーブル内のデータを条件に指定して読み込む場合は、処理効率は良くなります。

内部テーブル:ソートテーブル

キーを元に宣言しているため、ソートテーブル宣言時には、キーの設定をする必要があります。

「サンプルコード」①

REPORT Z_SAMPLE142_NEW.

*内部テーブル定義
*得意先名称(NAME1)でソート(NON-UNIQUE)
DATA GT_ZFUJII_DB01 TYPE SORTED TABLE OF ZFUJII_DB01 WITH NON-UNIQUE KEY NAME1.

START-OF-SELECTION.

  "※SELECTで全行を取得すると重いので、教材用途なら件数制限を推奨(必要なら外してOK)
  SELECT *
    FROM ZFUJII_DB01
    INTO TABLE @GT_ZFUJII_DB01.

  LOOP AT GT_ZFUJII_DB01 INTO DATA(GS_ZFUJII_DB01).
    WRITE: / GS_ZFUJII_DB01-MANDT,
           GS_ZFUJII_DB01-KUNNR,
           GS_ZFUJII_DB01-NAME1,
           GS_ZFUJII_DB01-NAME2.
  ENDLOOP.

END-OF-SELECTION.

実行結果

レンジテーブル

レンジテーブルとは、内部テーブルの一種ですが、前述のテーブルとは格納方法が異なります。
レンジテーブルは、標準/ソートのように「データを貯める」のではなく、WHERE条件(範囲条件)を行として持つために使います。
(WHERE <フィールド>IN <レンジテーブル>) つまり、テーブルの中にある情報は抽出条件のようなものです。

レンジテーブルの1行には、次の4項目があります。

●SIGN:含める(I) / 除外する(E)
●OPTION:条件(EQ=等しい、BT=範囲、GE=以上…)
●LOW:下限/値
●HIGH:上限(OPTION=BTのとき使用)

内部テーブル:レンジテーブル

その他のテーブル宣言と同様に、定義したいテーブルの種類を含めて宣言をします。
レンジテーブルを宣言する時は、データ型を参照せずに項目名を参照します。
それにより、その項目の範囲を選択し、レンジテーブルに格納することができます。
レンジテーブルにおける構文はとなります。

「サンプルコード」①

REPORT ZFUJII_SAMPLE143.

*&---------------------------------------------------------------------*
* レンジテーブル型定義
*&---------------------------------------------------------------------*
TYPES TYP_SAL TYPE RANGE OF ZFUJII_DB02-ZAMT_SAL.

*&---------------------------------------------------------------------*
* レンジテーブル定義
*&---------------------------------------------------------------------*
DATA R_SAL TYPE TYP_SAL.

*&---------------------------------------------------------------------*
* レンジテーブルの構造定義
*&---------------------------------------------------------------------*
DATA RH_SAL LIKE LINE OF R_SAL.

*&---------------------------------------------------------------------*
* 内部テーブル定義
*&---------------------------------------------------------------------*
DATA IT_ZFUJII02_TAB TYPE ZFUJII02_TAB. "データ抽出用
*&---------------------------------------------------------------------*
* 構造定義
*&---------------------------------------------------------------------*
DATA ST_ZFUJII02 TYPE ZFUJII02. "データ抽出用

*&---------------------------------------------------------------------*
* 主処理
*&---------------------------------------------------------------------*
START-OF-SELECTION.
*初期化
CLEAR: R_SAL, RH_SAL, IT_ZFUJII02_TAB, ST_ZFUJII02.
*値の代入
RH_SAL-SIGN = 'I'. "指定した範囲を含む
RH_SAL-OPTION = 'GE'. "LOWで指定する値以上
RH_SAL-LOW = 1000000.

*レンジテーブルへデータを格納
APPEND RH_SAL TO R_SAL.

*データ抽出
*売上金額が100万以上のデータを抽出
SELECT * FROM ZFUJII_DB02 INTO TABLE IT_ZFUJII02_TAB
  WHERE ZAMT_SAL IN R_SAL.
*出力処理
LOOP AT IT_ZFUJII02_TAB INTO ST_ZFUJII02.
    WRITE ST_ZFUJII02-MANDT.               "クライアント
    WRITE ST_ZFUJII02-GRAC_YYYYMM.     "年月
    WRITE ST_ZFUJII02-ZAMT_SAL.             "売上金額
    WRITE ST_ZFUJII02-CURRENCY.            "通貨
    WRITE /.
  ENDLOOP.

END-OF-SELECTION.

実行結果

補足:LIKE LINE OFオプションについて

サンプルで使用しているLIKE LINE OFというキーワードは、レンジテーブルで構造を宣言する場合に しばしば用いられます。 LIKE LINE OFを使用することで、レンジテーブルと同じ形の構造を宣言することができます。
今回のサンプルの場合、

DATA R_SAL TYPE TYP_SAL.

DATA RH_SAL LIKE LINE OF R_SAL.

上記で構築されています。

また、DATA命令だけでなく、TYPES命令でもLIKE LINE OFを使用することができます。

内部テーブル:レンジテーブル(新構文)

レンジテーブルでも、インライン宣言が可能です。VALUE命令を使うことで構造の宣言が不要になります。
インライン宣言を用いた構文は以下の通りです。

また、共通の値をセットする場合は、以下の通りに記述することも可能です。

詳しくは、サンプルコード③を確認してみましょう。

「サンプルコード」①

REPORT Z_SAMPLE143.
*&---------------------------------------------------------------------*
* レンジテーブル定義(売上金額用)
*&---------------------------------------------------------------------*
TYPES TY_R_AMT TYPE RANGE OF ZFUJII_DB02-ZAMT_SAL.
*&---------------------------------------------------------------------*
* データ定義
*&---------------------------------------------------------------------*
DATA:
  GR_AMT  TYPE TY_R_AMT,                 "売上金額レンジテーブル
  GS_AMT  LIKE LINE OF GR_AMT,           "レンジ1行分(SIGN/OPTION/LOW/HIGH)
  GT_DB02 TYPE STANDARD TABLE OF ZFUJII_DB02, "抽出結果
  GS_DB02 TYPE ZFUJII_DB02.              "抽出結果(1行)
*&---------------------------------------------------------------------*
* 主処理
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  " レンジ条件:100万以上(GE)
  " SIGN   : I = 含める(Include)
  " OPTION : GE = 以上(Greater or Equal)
  " LOW    : 下限値
  GS_AMT-SIGN   = 'I'.
  GS_AMT-OPTION = 'GE'.
  GS_AMT-LOW    = 1000000.
  APPEND GS_AMT TO GR_AMT.

  "データ抽出:売上金額が100万以上
  SELECT *
    FROM ZFUJII_DB02
    INTO TABLE GT_DB02
    WHERE ZAMT_SAL IN GR_AMT.

  "出力
  LOOP AT GT_DB02 INTO GS_DB02.
    WRITE: / GS_DB02-MANDT,       "クライアント
             GS_DB02-ZYEARMONTH,  "年月
             GS_DB02-ZAMT_SAL,    "売上金額
             GS_DB02-CURRENCY.    "通貨
  ENDLOOP.
	

実行結果

「サンプルコード」③

REPORT Z_SAMPLE143_NEW.

*&---------------------------------------------------------------------*
* レンジテーブル定義
*&---------------------------------------------------------------------*
DATA GR_AMT TYPE RANGE OF ZFUJII_DB02-ZAMT_SAL.

*&---------------------------------------------------------------------*
* 内部テーブル定義
*&---------------------------------------------------------------------*
DATA IT_ZFUJII02_TAB TYPE STANDARD TABLE OF ZFUJII02_TAB. "データ抽出用

*&---------------------------------------------------------------------*
* 主処理
*&---------------------------------------------------------------------*
START-OF-SELECTION.

*レンジテーブルへデータを格納
  GR_AMT = VALUE #(
    ( SIGN = 'I' OPTION = 'BT' LOW = 500000  HIGH = 1000000 ) 
    ( SIGN = 'E' OPTION = 'EQ' LOW = 550000 )
  ).

*初期化
  CLEAR RH_SAL.

*データ抽出
*売上金額が50万~100万円の間で、55万円を含まないデータを抽出
  SELECT *
    FROM ZFUJII_DB02
    INTO TABLE @DATA(GT_DB02)
    WHERE ZAMT_SAL IN @GR_AMT.

*出力処理
  LOOP AT GT_DB02 INTO DATA(GS_DB02).
    WRITE: / GS_DB02-MANDT,       "クライアント
             GS_DB02-ZYEARMONTH,  "年月
             GS_DB02-ZAMT_SAL,    "売上金額
             GS_DB02-CURRENCY.    "通貨
  ENDLOOP.

実行結果


NEXT>> 第15章 内部テーブルの編集

研修の詳細はこちら