【ABAP】レンジテーブル(RANGE TABLE)

概要

レンジテーブルとは名前の通り範囲を持つテーブルとなります。
もう少し具体化すると例えば、「1月から10月までの範囲」「アルファベットCからG以外の範囲」「数字100と230と500の特定された範囲」などをテーブルで持たせることが出来ます。
レンジテーブルは選択テーブル(SELECT-OPTIONS)と型は同じなのでどういったものかは選択テーブルをイメージしてもらえると理解しやすいと思います。

選択テーブルとレンジテーブルの違いは以下の説明および図の通りとなります。
ロジックだと選択テーブルは「SELECT-OPTIONS」レンジテーブルは「TYPE RANGE OF」と定義の仕方が異なります。

  • 選択テーブルは選択画面から設定された値を自動で選択テーブルに割当てる
  • レンジテーブルは選択画面がなく、入力項目でもないため値はコーディングでレンジテーブルに割当てる

今回はレンジテーブルについて詳しく紹介します。レンジテーブルが分かれば選択テーブルにどの様な値が割り当てられるかイメージできると思いますので類似していると思ってください。
選択テーブルの定義の仕方や動作確認をしたい場合は以下記事を参考にしてください。

命令文

命令文は以下の通りとなります。

DATA レンジテーブル名 TYPE RANGE OF テーブル-項目

レンジテーブルに値を格納する際に必要となる構造(作業領域)については以下の通りとなります。

DATA 構造名(作業領域) LIKE LINE OF レンジテーブル名

以下でもレンジテーブルと構造(作業領域)を作成できますが基本は上記で作成することの方が多いです。
プロジェクトの規約に従って作成してください。

TYPES データ型名1 TYPE RANGE OF データ型
TYPES データ型名2 TYPE LINE OF データ型名1
DATA レンジテーブル名TYPE データ型名1
DATA 構造名(作業領域)TYPE データ型名2

特徴

大きな特徴としては以下3つとなります。
1つ目は概要で説明した通り構造は同じだが値を取得する方法が選択画面からかコーディングからかで異なっています。選択テーブルについてはコーディングで更に値を追加や削除する事も可能です。
2つ目については以下「4つの項目から構成された構造」で別途解説します。
3つ目については変数だと1つの項目に1つの値しか格納できないが、レンジテーブルは1つの項目に複数の値(範囲)を格納する事ができるため検索条件として用いりやすいです。

  • 選択テーブルとレンジテーブルのテーブル構造は同じ
  • 構造は4つの項目(SIGN、OPTION、LOW、HIGH)から成り立つ
  • SELECT文やLOOP文などのWHERE句で用いられることが多い

4つの項目から構成された構造

選択テーブルとレンジテーブルの構造は同一で特徴的な構成となっています。
4つの項目から成立ちSIGN、OPTION、LOW、HIGHと決められた構造となっています。
それぞれどの様な役割となっているのか説明致します。

SIGN

行ごとに指定したOPTION, LOW, HIGHの値を含めるか含めないかを決定する項目となります。
値は2種類と以下の通り決まっており含める場合は’I’、含めない場合は’E’のどちらかとなります。
基本的に’I’を指定する事が多く、その理由としてパフォーマンスの影響を考慮するためです。

  • ‘I'(Include):含める
  • ‘E'(Exclude):含めない

OPTION

演算子を指定する項目となります。基本的に論理式で使用する演算子と同じですが’CP’と’NP’については演算子で使える機能の一部が存在しません。
使える演算子について以下紹介します。

演算子意味
EQ=EQUALLOWと同じ値
NE<>NOT EQUALLOWと異なる値
GE>=GREATOR THAN EQUALLOW以上の値
GT>GREATER THANLOWより大きい値
LE<=LESS THAN EQUALLOW以下の値
LT<LESS THANLOWより小さい値
BTBETWEEN LOW AND HIGHBETWEENLOWからHIGHと同じ値
NBNOT BETWEEN
LOW AND HIGH
NOT BETWEENLOWからHIGHと異なる値
CPCHECK PATTERNLOWと同じ値(ワイルドカードを含む)
ワイルドカードが使用されている場合に限り使用する事が可能
NPNOT CHECK PATTERNLOWと異なる値(ワイルドカードを含む)
ワイルドカードが使用されている場合に限り使用する事が可能

※ワイルドカードについて
入力項目では’*’,’+’を使用する事で任意の値とみなす事ができます。
コーディングでは’%’,’_’を使用する事で任意の値とみなす事ができます。
以下例となります。

’*’,’%’:任意の文字列として扱う(単語検索の例:’A*’ ,’A%’ →’AGE’,’AZURE’など)
‘+’,’_’:任意の1文字として扱う(単語検索の例:’AS+’,’AS_’ →’ASH’,’ASK’)

LOW

宣言したデータ型の影響を受ける項目となります。
基本的に値が格納される項目でもあり、OPTIONの説明からも分かる様にBTとNB以外は基本LOWのみを扱います。
HIGHが入力されている場合は範囲の下限値として使用されます。

HIGH

宣言したデータ型の影響を受ける項目となります。
OPTIONの説明からも分かる様にBTとNBの時くらいしか使用されません。
使われ方としては範囲の上限値として使用されます。

コーディング

選択画面から入力し実行した場合は選択画面の入力値(選択テーブル)を条件にテーブル「T001」を検索します。(図左側)
選択画面から入力せず実行した場合はコーディングでレンジテーブルに値を格納し、そのレンジテーブルを条件にテーブル「T001」を検索します。(図右側)
その結果として「会社コード」「テキスト」「国コード」を出力します。

TYPES:
  BEGIN OF TA_T001,
    BUKRS TYPE BUKRS,
    BUTXT TYPE BUTXT,
    LAND1 TYPE LAND1,
  END OF TA_T001.

DATA:
  W_BUKRS  TYPE T001-BUKRS,
  R_BUKRS  TYPE RANGE OF T001-BUKRS,
  WA_BUKRS LIKE LINE OF R_BUKRS,
  IT_T001 TYPE STANDARD TABLE OF TA_T001,
  WA_T001 TYPE TA_T001.

*TYPESでレンジテーブルを定義した例
*TYPES:
*  TAR_BUKRS  TYPE RANGE OF T001-BUKRS,
*  TAWA_BUKRS TYPE LINE OF TAR_BUKRS.
*DATA:
*  R_BUKRS  TYPE TAR_BUKRS,
*  WA_BUKRS TYPE TAWA_BUKRS.

SELECT-OPTIONS:
  S_BUKRS FOR W_BUKRS.

* レンジテーブルに値を代入
  WA_BUKRS-SIGN   = 'I'.
  WA_BUKRS-OPTION = 'EQ'.
  WA_BUKRS-LOW    = '0001'.
  WA_BUKRS-HIGH   = ''.
   APPEND WA_BUKRS TO R_BUKRS.

  WA_BUKRS-SIGN   = 'I'.
  WA_BUKRS-OPTION = 'EQ'.
  WA_BUKRS-LOW    = '0005'.
  WA_BUKRS-HIGH   = ''.
   APPEND WA_BUKRS TO R_BUKRS.

*選択テーブルがブランクの場合
IF S_BUKRS IS INITIAL.
* レンジテーブルを条件にテーブル「T001」から値を取得
  SELECT BUKRS
         BUTXT
         LAND1
    FROM T001
    INTO TABLE IT_T001
   WHERE BUKRS IN R_BUKRS.

    WRITE: / '*レンジテーブルのデータ出力*',
           / 'SIGN','OPTION','LOW ','HIGH'.
    LOOP AT R_BUKRS INTO WA_BUKRS.
      WRITE: /  WA_BUKRS-SIGN,
              6 WA_BUKRS-OPTION,
             13 WA_BUKRS-LOW,
             18 WA_BUKRS-HIGH.
    ENDLOOP.

*選択テーブルがブランク以外の場合
ELSE.
* 選択テーブルを条件にテーブル「T001」から値を取得
  SELECT BUKRS
         BUTXT
         LAND1
    FROM T001
    INTO TABLE IT_T001
   WHERE BUKRS IN S_BUKRS.

    WRITE: / '*選択テーブルのデータ出力*',
           / 'SIGN','OPTION','LOW ','HIGH'.
    LOOP AT S_BUKRS INTO WA_BUKRS.
      WRITE: /  WA_BUKRS-SIGN,
              6 WA_BUKRS-OPTION,
             13 WA_BUKRS-LOW,
             18 WA_BUKRS-HIGH.
    ENDLOOP.

ENDIF.

*取得データが存在しない場合
IF IT_T001 IS INITIAL.
  WRITE: 'データが存在しません。'.
*取得データが存在する場合
ELSE.
* 取得データを出力する
  WRITE: / '*取得データ出力*'.
  LOOP AT IT_T001 INTO WA_T001.
    WRITE: / WA_T001-BUKRS, "会社コード
             WA_T001-BUTXT, "テキスト
             WA_T001-LAND1. "国コード
  ENDLOOP.
ENDIF.

注意事項

選択テーブルとレンジテーブルによる複数条件指定は便利ではあるがどのくらい条件が指定されるのかある程度把握していないとパフォーマンスの劣化やショートダンプ(処理落ち)する可能性があるため注意となります。

理由としてはコーディング上WHERE句と選択テーブルまたはレンジテーブルを組み合わせれば複数条件の検索が容易にできます。
しかし、コーディング上は短文となっているが実際に処理される際には選択テーブルまたはレンジテーブルの中身は分解されて検索をしております。

例えばランダムに指定された数字を1000個ほど選択テーブルまたはレンジテーブルに格納している場合、実際には1000個の条件をORで分解して検索をしています。
分解しているため実際に処理される際は長文になります。
そのため指定する条件が多い場合はパフォーマンスの劣化やショートダンプ(処理落ち)する可能性がある事を意識しましょう。