ABAP/LOOP
内部テーブルをぐるぐる回す命令。
アドオンで使わないプログラムはないんじゃないか?というくらいメジャーな命令。
概要 †
LOOP~ENDLOOP形式で記述し、大抵は集計したり分岐してOutputやその元ネタを作るために利用する。
LOOP AT iTAB INTO WorkArea †
用法 †
一般的にはこちら。
このLOOPで何らかの別iTABを作るならばこちらが相当だが、元ネタの編集・更新ならば下記のAssigning句を使うべき。
サンプル †
LOOP AT L_IT_MARC INTO L_WA_MARC. CORRECT L_WA_MARC TO L_IT_STOCK. ENDLOOP.
LOOP AT iTAB Assigning <FieldSymbols> †
用法 †
iTABの内容を更新する場合はこちら。
ASSIGNの方がパフォーマンスが高いという理由でこちらを使う人もいるが、INTO WorkAreaと違い、こちらは命令の仕様でこちらはiTABを更新しうる。
そのため、更新の意図がないのならば、こちらを使うべきでない。
サンプル †
LOOP AT L_IT_ALVREPORT ASSIGNING <F_WA_ALVREPORT>. IF ( <F_WA_ALVREPORT>-AMOUNT > 100 ). <F_WA_ALVREPORT>-DIVISION = 'X'. ENDIF. ENDLOOP.
LOOP AT iTAB WHERE xxx †
用法 †
特定の条件を満たすレコードでのみLOOPしたい場合に使用する。
例えば、特定の性質を持つ得意先マスタが指定された伝票など。
この命令を使用した場合の注意点は、AT句が正しく効かないこと。
サンプル †
LOOP AT L_IT_KNA1 INTO L_WA_KNA1 WHERE LAND1 = 'JP'. ..... ENDIF.
テーブルコントロールのLoop †
テーブルコントロールのLOOPについて、
DATA : IT_9000 TYPE STANDARD TABLE OF TYPE_SCREEN_9000.
テーブルコントロールの受け皿的な内部テーブルを宣言して、
CONTROLS: TABLECONTROL_9000 TYPE TABLEVIEW USING SCREEN 9000.
テーブルコントロール自体を宣言して、PBO?やPAI?の処理に用いる。
PROCESS BEFORE OUTPUT. LOOP AT IT_9000 INTO WA_9000 WITH CONTROL TABLECONTROL_9000 CURSOR TABLECONTROL_9000-CURRENT_LINE. ... ENDLOOP.
PBO?にはこんな感じで書いて、
PROCESS AFTER INPUT. LOOP AT IT_9000 INTO WA_9000. CHAIN. FIELD : WA_9000-SELECTION, "選択行 WA_9000-QTY. "数量 * 何らかの処理 MODULE xxx ENDCHAIN. ENDLOOP.
PAI?にはこんな感じで書く。
その他 †
Loop中のiTabへの操作 †
LOOP中の内部テーブル自体に対しての登録や削除について、INDEXなどのシステム変数にも影響を及ぼすため、極力行わないのが望ましい。そうしなければならない理由も特にないし。
変更については実施しても概ね問題ない所見だが、いうまでもなくATのキーを変更したりWHERE句の条件かわを変更したりワケワカラン組み方はしないこと。
Loop中のLoopについて †
例えばヘッダデータのLoopの中で明細データをLoopする、基本データのLoopの中で組織依存データをLoopする等、Loopの中のLoopはってのよくある話。
「Loopの中のLoopはわかりづらいからダメだ」という人が偶にいるけど、素直に「俺の脳ミソがついていかないからやめてくれ」といっていれば可愛げもあるのに。
それは置いといて、確かに書きっぷりによってはわかりづらくなってしまうのも事実。
じゃあどうやって書けばよいかというと、単にLoopの中のLoopを長いロジックで書かない/飛ばした先のサブルーチンでLoopしないければよいだけの話。
あと、基本的なことだが、不用意にグローバル変数を使うことで著しく可読性や保守性が低下してしまうことにも留意すること。
良い例 †
FORM 処理A LOOP AT iTAB_CURRENT_HEADER INTO WA_CURRENT_HEADER. PERFORM 処理1 USING WA_CURRENT_HEADER CHANGING WA_NEW_HEADER. LOOP AT iTAB_CURRENT_ITEM INTO WA_CURRENT_ITEM WHERE DOCNO = WA_CURRENT_HEADER-DOCNO. PERFORM 処理2 USING WA_CURRENT_ITEM CHANGING iTab_NEW_HEADER. ... ENDLOOP. ... ENDLOOP. ENDFORM.
悪い例 †
FORM 処理A LOOP AT iTAB_CURRENT_HEADER INTO WA_CURRENT_HEADER. PERFORM 処理1 USING WA_CURRENT_HEADER CHANGING WA_NEW_HEADER. PERFORM 処理2 USING WA_CURRENT_HEADER-DOCNO iTAB_CURRENT_ITEM CHANGING WA_NEW_ITEM. ENDFORM.
FORM 処理2 LOOP AT iTAB_CURRENT_ITEM INTO WA_CURRENT_ITEM WHERE DOCNO = WA_CURRENT_HEADER-DOCNO. PERFORM 処理1 USING WA_CURRENT_HEADER CHANGING iTAB_NEW_ITEM. ... ENDLOOP. ... ENDLOOP. ENDFORM.
コメントはありません。 Comments/ABAP/LOOP?