トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS

ABAP/LOOP の変更点

Top/ABAP/LOOP

[[内部テーブル>ABAP/内部テーブル]]をぐるぐる回す命令。
アドオンで使わないプログラムはないんじゃないか?というくらいメジャーな命令。

----
#contents
----


* 概要 [#h709f720]
LOOP~ENDLOOP形式で記述し、大抵は集計したり分岐してOutputやその元ネタを作るために利用する。

** LOOP AT iTAB INTO WorkArea [#d82c89d3]
*** 用法 [#d870e6ce]
一般的にはこちら。
このLOOPで何らかの別iTABを作るならばこちらが相当だが、元ネタの編集・更新ならば下記のAssigning句を使うべき。

*** サンプル [#i817cab8]
 LOOP AT L_IT_MARC INTO L_WA_MARC.
   CORRECT L_WA_MARC TO L_IT_STOCK.
 ENDLOOP.

** LOOP AT iTAB Assigning <FieldSymbols> [#obc92f78]
*** 用法 [#d5815b1e]
iTABの内容を更新する場合はこちら。

[[ASSIGN>ABAP/ASSIGN]]の方がパフォーマンスが高いという理由でこちらを使う人もいるが、INTO WorkAreaと違い、こちらは命令の仕様で''こちらはiTABを更新しうる''。
そのため、更新の意図がないのならば、こちらを使うべきでない。

*** サンプル [#w89d82d3]
 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 [#f4f291cc]
*** 用法 [#r5a5b2c0]
特定の条件を満たすレコードでのみLOOPしたい場合に使用する。
例えば、特定の性質を持つ[[得意先マスタ]]が指定された伝票など。

この命令を使用した場合の注意点は、[[AT>ABAP/AT]]句が正しく効かないこと。

*** サンプル [#r58cc4fd]
 LOOP AT L_IT_KNA1 INTO L_WA_KNA1 WHERE LAND1 = 'JP'.
   .....
 ENDIF.

** テーブルコントロールのLoop [#f7977c3b]
[[テーブルコントロール>ABAP/テーブルコントロール]]のLOOPについて、

 DATA :
   IT_9000           TYPE STANDARD TABLE OF TYPE_SCREEN_9000.

[[テーブルコントロール>ABAP/テーブルコントロール]]の受け皿的な[[内部テーブル>ABAP/内部テーブル]]を宣言して、

 CONTROLS:
   TABLECONTROL_9000 TYPE TABLEVIEW USING SCREEN 9000.

[[テーブルコントロール>ABAP/テーブルコントロール]]自体を宣言して、[[PBO>ABAP/PBO]]や[[PAI>ABAP/PAI]]の処理に用いる。


 PROCESS BEFORE OUTPUT.
 
   LOOP AT IT_9000 INTO WA_9000 WITH CONTROL TABLECONTROL_9000 CURSOR TABLECONTROL_9000-CURRENT_LINE.
     ...
   ENDLOOP.

[[PBO>ABAP/PBO]]にはこんな感じで書いて、

 PROCESS AFTER INPUT.
 
   LOOP AT IT_9000 INTO WA_9000.
 
     CHAIN.
       FIELD : WA_9000-SELECTION,    "選択行
                  WA_9000-QTY.          "数量
 
 *    何らかの処理
       MODULE xxx
     ENDCHAIN.
 
   ENDLOOP.

[[PAI>ABAP/PAI]]にはこんな感じで書く。

* その他 [#n70fe8b9]
** Loop中のiTabへの操作 [#r277d28c]
LOOP中の内部テーブル自体に対しての登録や削除について、INDEXなどのシステム変数にも影響を及ぼすため、極力行わないのが望ましい。そうしなければならない理由も特にないし。

変更については実施しても概ね問題ない所見だが、いうまでもなく[[AT>ABAP/AT]]のキーを変更したりWHERE句の条件かわを変更したりワケワカラン組み方はしないこと。

** Loop中のLoopについて [#f3b83efd]
例えばヘッダデータのLoopの中で明細データをLoopする、基本データのLoopの中で組織依存データをLoopする等、Loopの中のLoopはってのよくある話。

「Loopの中のLoopはわかりづらいからダメだ」という人が偶にいるけど、素直に「俺の脳ミソがついていかないからやめてくれ」といっていれば可愛げもあるのに。

それは置いといて、確かに書きっぷりによってはわかりづらくなってしまうのも事実。
じゃあどうやって書けばよいかというと、単にLoopの中のLoopを長いロジックで書かない/飛ばした先のサブルーチンでLoopしないければよいだけの話。

あと、基本的なことだが、不用意に[[グローバル変数>アドオン/グローバル変数]]を使うことで著しく可読性や保守性が低下してしまうことにも留意すること。

*** 良い例 [#ga58c474]
 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.

*** 悪い例 [#eaa351c5]
 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.


~
~
CENTER:【スポンサードリンク】
#htmlinsert(amazon_book_sap_system_implement)
~
~
----
#pcomment(reply)