構造とテーブル

構造とテーブルについて

プログラム中で様々な値を格納するデータオブジェクト。
データオブジェクトには1つで複数の値を格納できる以下のものがある。
 ・構造→1行のみで構成

 ・テーブル→複数行で構成

 構造やテーブルの項目のことをコンポーネントと呼ぶ。

構造

 1行のみで構成されている構造。次のような種類が存在する。
 ・フラット構造
  スタンダードな構造。アドオンプログラムで使うのは大体これ。
 ・ネストされた構造
  構造のコンポーネントのうち、最低どれか1つがほかの構造を参照している構造。
 ・ディープ構造
  構造のコンポーネントのうち、最低どれか1つがほかのテーブルを参照している構造。
 次のような方法で使うことが可能だ。
 ・構造を作成する。

 TYPES: BEGIN OF 構造名,
  コンポーネント名 TYPE 構造,
  コンポーネント名 TYPE 構造,
  コンポーネント名 TYPE 構造,
:
 END OF 構造名.

 ・構造を割り当てたデータオブジェクトを作成する。

 DATA データオブジェクト名 TYPE 構造名.

 また、次のような方法で構造を割り当てたデータオブジェクトを1度に作ることも可能だ。

 DATA: BEGIN OF 構造を割り当てるデータオブジェクト名,
  コンポーネント名 TYPE 構造,
  コンポーネント名 TYPE 構造,
  コンポーネント名 TYPE 構造,
:
 END OF 構造を割り当てるデータオブジェクト名.

 DBテーブルと全く同じ形でいい場合は次のような方法も使用できる。

 DATA データオブジェクト名 TYPE DBテーブル.

グローバル構造

 プログラム内で作り、そのプログラム内でのみ使用できる構造を
 「ローカル構造」と呼ぶ。
 ABAPデータディクショナリ(SE11)で作り、様々なプログラムで使用できる構造を
 「グローバル構造」と呼ぶ。
 作り方は次の通り。


 SE11>データ型に構造の名前を入力>作成ボタンを押す
 出てきたポップアップでラジオボタン「構造」を押す
 次の画面でコンポーネントやその型などを設定
 通貨や数量のコンポーネントが存在する場合は「通貨/数量」タブで
 参照する項目を設定する必要がある。
 同じテーブルの別コンポーネントも別テーブルのコンポーネントも
 参照することが可能だ。

構造の宣言

 ここまでをまとめると、構造を作る方法は次の4つということになる。
  ①TYPESを使う
  ②DBテーブルを参照する
  ③BEGIN OF-END OFを使用して直接宣言する。
  ④グローバル構造を作る。

内部テーブル

 複数行格納することが可能な唯一のデータオブジェクト。
 内部テーブルの操作はほかのデータオブジェクトとは少し異なるので注意しよう。

内部テーブルの作り方

  内部テーブルは次のように作ることが多い。
  ・まずは構造を作成する。

 TYPES: BEGIN OF 構造名,
  コンポーネント名 TYPE 構造,
  コンポーネント名 TYPE 構造,
  コンポーネント名 TYPE 構造,
:
 END OF 構造名.

  ・作った構造を指定して内部テーブルを作る。

 DATA データオブジェクト名 TYPE TABLE OF 構造名.

内部テーブルの操作

 内部テーブルは複数の行が存在するため、それぞれの行にデータを直接操作することは基本的にはしない。
 内部テーブルのデータを使ったり、内部テーブルにデータを入れる場合は内部テーブルと同じ形をした構造型のデータオブジェクトが必要になる。
 このデータオブジェクトはワークエリアと呼ばれる。
 ワークエリアに1行ずつデータを入れていき、ワークエリア上で操作を行う。
 ワークエリアの作り方は普通の構造型のデータオブジェクトと同じだ。

 DATA データオブジェクト名 TYPE 構造名.

内部テーブルの種類

 内部テーブルには次のようなものが存在する。
 ・標準テーブル
  アドオンプログラムで最もよく使う内部テーブル。
  内部テーブルにデータを入れるときにはAPPEND(最終行に追加)とINSERT(任意の行に追加)を使用することが可能だ。
  データへのアクセスはテーブルキーとインデックス両方に対応している。
  通常のREADでは線形検索となり検索の時間はエントリ数に正比例する。
  キー項目は空にすることも可能。
  暗黙的なソートは行われないが、明示的にソートすることは可能だ。
  作り方は次の通り。

  DATA データオブジェクト名 TYPE TABLE OF 構造名.
  もしくは
  DATA データオブジェクト名 TYPE STANDARD TABLE OF 構造名.

 ・ソートテーブル
  標準テーブルと似ているが常にキー項目でソートされるという違いがある。
  ユニークキーと非ユニークキー両方に対応していて、テーブルを作るときに主キーを指定することが必須だ。
  ユニークキーを使用する場合→キーの項目は重複することができない。
  非ユニークキーを使用する場合→キーの項目は重複することができる。使用する場合はデータの不整合が起きないよう注意が必要だ。
通常のREADではバイナリ検索となり検索の時間はエントリ数に正比例するが線形検索よりも高速。
  暗黙的なソートが行われるため、明示的にソートすることは不可能となる。
  作り方は次の通り。

DATA データオブジェクト名 TYPE SORTED TABLE OF 構造名 WITH UNIQUE KEY キーにするコンポーネント名.
  もしくは
DATA データオブジェクト名 TYPE SORTED TABLE OF 構造名 WITH NON-UNIQUE KEY キーにするコンポーネント名.

  キーにするコンポーネントを複数にしたい場合はスペースで区切って複数のコンポーネントを指定しよう。

DATA データオブジェクト名 TYPE SORTED TABLE OF 構造名 WITH UNIQUE KEY キーにするコンポーネント名① キーにするコンポーネント名②.

 ・ハッシュテーブル
  標準テーブル、ソートテーブルと違い行インデックスがない内部テーブル。インデックスがないのでキーによってのみテーブルの操作が可能だ。
  ハッシュテーブルはユニークキーにのみ対応していてキーを指定することは必須となる。
  通常のREADではハッシュアルゴリズム検索となり検索の時間はエントリ数に関係なく常に一定。
  暗黙的なソートは行われないが、明示的にソートすることは可能だ。
  作り方は次の通り。

DATA コンポーネント名 TYPE HASHED TABLE OF 構造名 WITH UNIQUE KEY キーにするコンポーネント名.

 ・Any Table
  すべてのテーブルカテゴリをカバーする汎用テーブルカテゴリ。

 ・Index Table
  インデックス操作が可能なテーブルカテゴリ(標準とソート)のみをカバーする汎用テーブルカテゴリ。

  汎用テーブルカテゴリは作ったときにはどんな形になるか決まっていない。使うときに決めることが可能だ。
  作り方は次の通り。

FIELD-SYMBOLS <コンポーネント名> TYPE ANY TABLE. 

テーブルのキー

 プライマリテーブルキーとセカンダリテーブルキーが使用可能。
 キーの指定方法には次のようなものがある。
 ・よく使う方法。WITH UNIQUE KEYもしくはWITH NON-UNIQUE KEYの後ろにコンポーネントを指定することでキーとすることが可能。

DATA データオブジェクト名 TYPE SORTED TABLE OF 構造名 WITH UNIQUE KEY コンポーネント名.

 ・文字型の項目をすべてキーにすることも可能。

DATA データオブジェクト名 TYPE SORTED TABLE OF 構造名 WITH UNIQUE DEFAULT KEY.

 ・テーブルが基本行データ型(CやDやIやXなど)の場合、行全体をキーとすることが可能だ。

DATA データオブジェクト名 TYPE SORTED TABLE OF 構造名 WITH UNIQUE KEY TABLE_LINE.

 ・セカンダリテーブルキーは次のように作ることが可能だ。LOOPなどでキーを指定するときにセカンダリキー名を指定することでセカンダリキーを使用することが可能となる。

DATA データオブジェクト名 TYPE SORTED TABLE OF 構造名
WITH UNIQUE KEY コンポーネント名
WITH NON-UNIQUE SORTED KEY セカンダリキー名
COMPONENTS コンポーネント名.

 セカンダリテーブルキーは次のような使い方はしない方がいい。
 ・50行未満の内部テーブル
 ・頻繁に更新されるコンポーネントを指定する

内部テーブルの操作

 内部テーブルにデータを追加、削除、読み込みなどする場合は次のようなABAP Keywordを使用できる。
 ・データの追加
  APPEND 1番下の行に追加
  INSERT  任意の行に追加(指定しない場合は一番下に追加)
   SORTED TABLEではINSERTがおすすめ。
   ※SORETED TABLEにAPPENDする場合、ソート順が正しくない場合ショートダンプしてしまう。
 ・データの集計
  COLLECT
 ・データの削除
  DELETE
  CLEAR
 ・データの読み込み
  READ 条件に合う1件だけ
  LOOP 条件に合うすべて
 ・データの変更
  MODIFY

内部テーブルへのデータの追加

 ・APPEND 一番最後の行にデータを追加する。
      基本的に標準テーブルで使用しよう。
      (SORTED TABLEは非推奨、HASHED TABLEは非対応なので注意。)
 ・INSERT 行を指定してデータを追加することが可能。 指定しなかった場合、APPENDと同じく最後の行にデータを追加する。

 それぞれの使い方は次の通り。
①コンポーネントが会社コード、伝票番号のTY_BSEGという構造をつくる。

*--- データ型定義
TYPES : BEGIN OF TY_BSEG,
BUKRS TYPE BSEG-BUKRS, "会社コード
BELNR TYPE BSEG-BUKRS, "伝票番号
END OF TY_BSEG.

②作った構造を使って内部テーブルとワークエリアを作成

*--- データオブジェクト宣言
DATA : WA_BSEG TYPE TY_BSEG, "ワークエリア
IT_BSEG TYPE TABLE OF TY_BSEG. "内部テーブル

③APPENDでデータ追加

WA_BSEG-BUKRS = 'AAAA'. "会社コード
WA_BSEG-BELNR = '100000000002'. "伝票番号
***ワークエリアのデータを内部テーブルに追加
APPEND WA_BSEG TO IT_BSEG.

※SORTED TABLEにAPPENDでデータを追加する際はソート順に注意

③INSERTでデータ追加

WA_BSEG-BUKRS = 'AAAA'. "会社コード
WA_BSEG-BELNR = '100000000001'. "伝票番号
**INSERTで内部テーブルに追加 
***INDEX 1で内部テーブルの1行目に追加という意味
INSERT WA_BSEG INTO IT_BSEG INDEX 1.

DBテーブルへのデータの追加

 DBテーブルへデータを追加する場合もINSERTを使用する。
 
 ・単一行の追加
  INSERT INTO DBテーブル名 VALUES 構造名.
  INSERT DBテーブル名 FROM 構造名.

 ・複数行の追加
  INSERT DBテーブル名 FROM TABLE 内部テーブル名.
  INSERT DBテーブル名 FROM TABLE 内部テーブル名 ACCEPTING DUPLICATE KEYS.

 INSERTはキー重複のデータがある場合ショートダンプしてしまうが、
 オプション「ACCEPTING DUPLICATE KEYS」を指定することでショートダンプではなくエラーメッセージとすることが可能となる。

DBテーブルの更新

UPDATEを使用することで可能。
更新する対象は更新する値が入っている構造や内部テーブルのキーと一致するデータ。
・単一行の更新
 UPDATE DBテーブル名 FROM 構造名.
・複数行の更新
 UPDATE DBテーブル名 FROM TABLE 内部テーブル名.

データの集計

 COLLECT データを追加するという点はAPPEND,INSERTと同じ。異なる部分はデータを追加する前に追加先の内部テーブルを見に行き、追加するデータと数値以外の項目が同じデータが存在するか確認し、存在する場合はレコード自体は追加せず、数値項目を合算する、という動きをする点だ。
 使い方は以下の通り。
①コンポーネントが会社コード、伝票番号、国内通貨額のTY_BSEGという構造をつくる。

*--- データ型定義
TYPES : BEGIN OF TY_BSEG,
BUKRS TYPE BSEG-BUKRS, "会社コード
BELNR TYPE BSEG-BUKRS, "伝票番号
DMBTR TYPE BSEG-DMBTR, "国内通貨額
END OF TY_BSEG.

②作った構造を使って内部テーブルとワークエリアを作成

*--- データオブジェクト宣言
DATA : WA_BSEG TYPE TY_BSEG, "ワークエリア
IT_BSEG TYPE TABLE OF TY_BSEG. "内部テーブル

③COLLECTでデータ追加

WA_BSEG-BUKRS = 'AAAA'. "会社コード
WA_BSEG-BELNR = '100000000003'. "伝票番号
WA_BSEG-DMBTR = 500, "国内通貨額
***ワークエリアのデータを内部テーブルに追加
***レコード自体が追加される
COLLECT WA_BSEG TO IT_BSEG.

④COLLECTでさらにデータ追加

WA_BSEG-BUKRS = 'AAAA'. "会社コード
WA_BSEG-BELNR = '100000000003'. "伝票番号
WA_BSEG-DMBTR = 1000, "国内通貨額
***ワークエリアのデータを内部テーブルに追加
***レコードは追加されず、国内通貨額が500から1500になる。
COLLECT WA_BSEG TO IT_BSEG.

 以下の画像はCOLLECTのイメージ。

COLLECTのイメージ

内部テーブルのデータの削除

 DELETE 内部テーブルのデータを指定した条件で削除することが可能。
 CLEAR 内部テーブルのすべてのデータを削除する。
 使い方は以下の通り。
 ・削除する行を指定

DELETE 内部テーブル名 INDEX 削除する行のINDEX番号.

 ・削除する条件を指定

DELETE 内部テーブル WHERE 条件.

 ・すべて削除

CLEAR 内部テーブル.

DBテーブルのデータの削除

DBテーブルのデータの削除もDELETEで行うことが可能。
アドオンプログラムで登録したデータの取り消し機能などで使われることが多い。
※DBテーブルの操作をすることができるので慎重に扱おう。

条件に当てはまるすべてのレコードをDBテーブルから削除
 DELETE FROM DBテーブル名 WHERE 条件.

指定した構造や内部テーブルの値とキーが一致するデータを削除
 単一行の削除
 DELETE DBテーブル名 FROM 構造.
 複数行の削除
 DELETE DBテーブル名 FROM TABLE 内部テーブル.

データの読み込み

  内部テーブルのデータをワークエリアにコピーすることをデータの読み込みと表現しています。
 ・READ 条件に合う1件を読み込む。
    条件にはテーブルのコンポーネントやテーブルのキー(プライマリ、セカンダリどちらも)を使うことも可能だ。
    インデックスを指定することも可能だが、使えるのは標準とSORTED TABLEのみなので注意。
  ※READではEQ(Equal)のように1つに絞り込むような条件しか使えないので注意
   (NE(Not Equal)などは使用できない。)


 ・LOOP 条件に合うすべてを読み込む。(1件ずつ読み込み、すべて読み込み終わるまで繰り返す。)
    LOOPの後にENDLOOPと書いたところまでをすべて読み込み終わるまで繰り返す。
    条件を指定しない場合、すべてのレコードを読み込む。
    条件の指定方法はWHERE句を使用してコンポーネントとその値を指定したり、セカンダリキーを使用したりすることが可能だ。

   それぞれの使い方は以下の通り。
  
   ・任意のコンポーネントを条件に使用する場合

READ TABLE 内部テーブル名 INTO ワークエリア名 WITH KEY コンポーネント名 = 条件.

   ・テーブルのキーを条件に使用する場合
    キーになってるコンポーネントはすべて指定しよう。

READ TABLE 内部テーブル名 INTO ワークエリア名 WITH TABLE KEY キーになってるコンポーネント名 = 条件. 

   ・セカンダリキーを使用する場合

READ TABLE 内部テーブル名 INTO ワークエリア名 USING KEY セカンダリキー名.

   ・インデックスを使用する場合

READ TABLE 内部テーブル名 INTO ワークエリア名 INDEX インデックス番号.

   ・全件LOOPする場合

LOOP AT 内部テーブル名 INTO ワークエリア名.
ENDLOOP.

   ・任意のコンポーネントを条件に使用する場合

LOOP AT 内部テーブル名 INTO ワークエリア名 WHERE コンポーネント名 = 条件.
ENDLOOP.

   ・セカンダリキーを使用する場合

LOOP AT 内部テーブル名 INTO ワークエリア名 USING KEY セカンダリキー名 WHERE キーになっているコンポーネント名 = 条件.
ENDLOOP.

   ・インデックスを使用する場合

   ・任意のコンポーネントを条件に使用する場合

LOOP AT 内部テーブル名 INTO ワークエリア名 FROM 1 to 5ENDLOOP.

内部テーブルのデータの変更

  MODIFY:キーになっている項目以外を変更することが可能。
  キー以外の項目を1行まるまる変更したり、コンポーネント1つだけを変更したりすることが可能だ。
  使い方は次の通り。
  ・任意のコンポーネントを条件に指定する場合

MODIFY 内部テーブル名 FROM ワークエリア名 WHERE コンポーネント名 = 条件.

  ・キーを条件に使用する場合

MODIFY 内部テーブル名 FROM ワークエリア名 .

  ・更新するコンポーネントを指定する場合(任意のコンポーネントを条件に使用)

MODIFY 内部テーブル名 FROM ワークエリア名 TRANSPORTING 更新するコンポーネント名 WHERE コンポーネント名 = 条件.

  ・更新するコンポーネントを指定する場合(キー使用)

MODIFY 内部テーブル名 FROM ワークエリア名 TRANSPORTING 更新するコンポーネント名.

DBテーブルのデータ変更

DBテーブルのデータを変更するときのもMODIFYを使用することができる。
※DBテーブルの操作をすることができるので慎重に扱おう。

 単一行変更
 MODIFY DBテーブル名 FROM 構造名.
 複数行変更
 MODIFY DBテーブル名 FROM TABLE 内部テーブル名.

コメント

タイトルとURLをコピーしました