LOOPとは
LOOPは内部テーブルのデータを読み込む方法の1つ。
使い方は以下の通り。
LOOP AT 内部テーブル名 INTO ワークエリア名.
:
ENDLOOP.
文字通り「LOOP」~「ENDLOOP」までを繰り返し読み込むことが可能だ。
基本的には内部テーブルの値を使って何か処理をしたいときに使う。
Ex.内部テーブルのコンポーネントを使って計算する、どこかのコンポーネントに新しく値を追加する、数値型のコンポーネントを合算する(COLLECTも使用)などなど
アドオンプログラムを作る際にとても頻繁に使用するのでしっかり覚えておきたいABAP Keywordの1つだ。
LOOPはほかのABAP Keywordと一緒に使うことが多い。
例えば、以下のようにLOOP中で計算した結果を結果格納用内部テーブルに追加していく、という使い方をすることがある。
Ex.内部テーブルAには今以下のデータが入っている。
全品10円引きのクーポンを使用した際の値引き後の金額を内部テーブルBに入れる、というコーディングをしてみる。

この内部テーブルAを条件指定なしでLOOPすると、上から1件ずつ3件読み込むことが可能となる。
LOOP AT 内部テーブルA INTO ワークエリアA.
イメージは以下の通り。
1回目

2回目

LOOP中に10円引きクーポン分値段をマイナスし上書きするという処理をしてみる。
ABAPでの計算は計算式が逆になり、
答え=計算式という書き方になる。
以下では 1行目のデータの場合190 = 200 – 10 という計算になる。
ワークエリアA-値段 = ワークエリアA-値段 – 10.
イメージは以下の通り。

ワークエリアの値を更新するだけでは内部テーブルのデータは更新できない。
APPENDを使用して内部テーブルBに計算後の値を入れよう。
APPEND ワークエリアA TO 内部テーブルB.
イメージは以下の通り。

ENDLOOPと書くことでLOOPが終了する。
ここまで読み込まれるとLOOPの最初の行に戻り、次の行を読み込み始める。
ENDLOOP.
3行のLOOPが終わると内部テーブルBは以下のような中身になる。

条件での絞り込み
LOOPでは読み込むデータを条件によって絞り込むことが可能だ。
条件はWHERE句と呼ばれるものを使用する。
使い方は以下の通り。
LOOP AT 内部テーブル名 INTO ワークエリア名 WHERE 条件にするコンポーネント名 = 条件.
ENDLOOP.
イメージは以下の通り。
以下の内部テーブルCで次のようにLOOPを使用すると、赤い部分のみを読み込むことが可能だ。
LOOP AT 内部テーブルC INTO ワークエリアC WHERE 商品名 = ポテト.

また、複数条件を付けることも可能で、その場合は以下のようになる。
LOOP AT 内部テーブルC INTO ワークエリアC WHERE 商品名 = ポテト AND サイズ = M.

フィールドシンボルについて
LOOPでは「INTO ワークエリア」の代わりに「フィールドシンボル」も割り当てることが可能だ。
使い方は次の通り。
* フィールドシンボルを作成
FIELD-SYMBOLS <フィールドシンボル名> LIKE LINE OF 内部テーブル名.
* フィールドシンボルを割り当てる
LOOP AT 内部テーブル名 ASSIGNING <フィールドシンボル名>.
:
ENDLOOP.
フィールドシンボルを割り当てるとワークエリアを使用した場合とは次のような違いがある。
ワークエリアを使用→ワークエリアの値を変更してもLOOP元テーブルに変化なし
フィールドシンボルを使用→フィールドシンボルで変更した部分はそのタイミングで元テーブルも変化する
図にすると以下のようなイメージ。
内部テーブルAをフィールドシンボルに割り当ててLOOPする。

フィールドシンボルの値を変更すると同時に元のテーブルの値も変更される。

Break Statementについて
LOOPにはBreak Statementというものがある。
LOOPの1回目のデータや最後のデータ、特定のコンポーネントの値が変わったときなどに1回だけ通るロジックを書くことが可能だ。
以下のような種類が存在する。
・AT FIRST
・AT LAST
・AT NEW
・AT END OF
どれも共通してLOOP~ENDLOOP.のなかでAT XX ~ ENDAT.と書くことで使用できる。
できることや使い方はそれぞれ以下の通りだ。
・AT FIRST
LOOPの最初の1回目だけ通ることができる。
以下のような内部テーブルだった場合で条件を指定せずに実行していれば1つ目のデータである商品名=ハンバーガー、値段=200のレコードのときのみ通ることが可能だ。

・AT LAST
LOOPの最後の1行だけ通ることができる。
下記のような内部テーブルの場合、条件を指定していなければ商品名=コーラ、値段=100のレコードのときのみ通ることが可能だ。

・AT NEW コンポーネント名
LOOP内で指定したコンポーネントが変わった後に通ることができる。
以下のような内部テーブルでAT NEW 商品名とした場合、まずは1つ目のデータである商品名=ポテト、サイズ=S、値段=200のレコードのときに通る。
その後、商品名が変わった最初のレコードの商品名=コーラ、サイズ=S、値段=100のときにも通る。

・AT END OF コンポーネント名
LOOP内で指定したコンポーネントが変わる前に通ることができる。
以下のような内部テーブルでAT END OF 商品名とした場合、商品名=ポテトが変わる前のレコードなので商品名=ポテト、サイズ=L、値段=300のレコードのときに通る。
その後、商品名が変わってから最後のレコード商品名=コーラ、サイズ=L、値段=200のときにも通る。

・SUMについて
AT XX ~ ENDAT.の中で「SUM」というキーワードを使うと、数値型の項目をすべて合算することが可能だ。
しかし、すべての項目を合算してしまうので使用しない項目も合算してしまったり、どの項目を合算しているのかぱっと見でわからないというような点があるので「COLLECT」を使用したり「IF」などで条件分岐して合算する方がおすすめ。
コメント