!--a11y-->

ループでは、命令ブロックが続けて数回実行されます。ABAP には以下の 4 つのループがあります。
キ DO 命令を使った無条件ループ
キ WHILE 命令を使った条件ループ
キ LOOP 命令を使った内部テーブルと抽出データセットによるループ
キ SELECT 命令を使ったデータベーステーブルからデータセットへのループ
このセクションでは、DO ループと WHILE ループについて説明します。SELECT は Open SQL 命令です。説明は、Open SQL セクションを参照してください。LOOP 命令の説明は、内部テーブルおよび抽出データセットセクションを参照してください。
命令ブロックを無条件で数回繰り返すには、次の制御構造を使います。
DO [<n>
TIMES] [VARYING <f> FROM <f1> NEXT
<f2>].
<
命令ブロック>
ENDDO.
オプションを指定していない場合は、EXIT または STOP などの強制終了命令 ( 下記参照) に到達するまで、命令ブロックが繰り返されます。システム項目 SY-INDEX には、現在のループパスを含むループパスの回数が含まれています。
ループパスの回数を <n> に限定するには、TIMES オプションを使用します。<n> には、リテラルまたは変数を指定します。<n> が 0 または負の値の場合、ループは処理されません。TIMES オプションを使わない場合は、ループが 1 つ以上の EXIT または STOP 命令を含むことを確認して、無限ループになるのを防いでください。
VARYING オプションを使用すると、各ループパスで、新しい値を変数 <f> に割り当てることができます。VARYING オプションは、DO 命令で 1 回以上使用することができます。<f1> と <f2> は、項目シーケンスの最初の 2 項目で、メモリ内の距離、データ型、長さが同じです。1 番目のループパスでは、<f> は <f1> の値をとり、2 番目のループパスでは <f2> の値をとります。処理はこのように続行されます。DO ループ内で項目 <f> の値を変更すると、現在の項目 <fi> の値も変更されます。シーケンスの項目よりループパスの数を少なく設定してください。ループパスの方が多いと、実行時エラーが発生します。
DO ループをネストして、他のループフォームに組み込むことも可能です。

DO ループの簡単な例
DO.
WRITE SY-INDEX.
IF SY-INDEX = 3.
EXIT.
ENDIF.
ENDDO.
出力は次のようになります。
1 2 3
ループは 3 回実行されます。この例では、ループは 3 回実行された後、EXIT 命令により終了します。

TIMES オプションを指定された 2 つのネストしたループの例
DO 2
TIMES.
WRITE SY-INDEX.
SKIP.
DO 3 TIMES.
WRITE SY-INDEX.
ENDDO.
SKIP.
ENDDO.
出力は次のようになります。
1
1 2 3
2
1 2 3
外部ループは 2 回実行されます。外部ループが 1 回実行される度に、内部ループは 3 回実行されます。システム項目 SY-INDEX には、各ループのループパス回数が含まれています。

DO ループの VARYING オプションの例
DATA: BEGIN OF TEXT,
WORD1(4) VALUE 'This',
WORD2(4) VALUE 'is',
WORD3(4) VALUE 'a',
WORD4(4) VALUE 'loop',
END OF TEXT.
DATA: STRING1(4), STRING2(4).
DO 4 TIMES VARYING STRING1 FROM TEXT-WORD1 NEXT
TEXT-WORD2.
WRITE
STRING1.
IF STRING1
= 'is'.
STRING1 =
'was'.
ENDIF.
ENDDO.
SKIP.
DO 2 TIMES VARYING STRING1 FROM TEXT-WORD1 NEXT
TEXT-WORD3
VARYING STRING2 FROM TEXT-WORD2 NEXT TEXT-WORD4.
WRITE:
STRING1, STRING2.
ENDDO.
出力は次のようになります。
This is a loop
This was a loop
構造 TEXT は、メモリ内の 4 つの等距離項目を表しています。最初の DO ループが実行される度に、そのコンポーネントが 1 つずつ STRING1 に割り当てられます。STRING1 が ‘is ’ を含む場合は、その内容は ‘was ’ に変更されます。TEXT-WORD2 も ‘was ’ に変更されます。2 つ目の DO ループが実行される度に、TEXT のコンポーネントが STRING1 から STRING2 に渡されます。
命令ブロックをある条件が真の間繰り返すには、次の制御構造を使います。
WHILE <
条件> [VARY <f> FROM
<f1> NEXT <f2>].
<
命令ブロック>
ENDWHILE.
< 条件> には、論理式を指定してください。WHILE と ENDWHILE の間の命令ブロックは、条件が真の間または EXIT や STOP などの強制終了命令に到達するまで繰り返されます。システム項目 SY-INDEX には、現在のループパスを含むループパスの回数が含まれています。WHILE 命令の VARY オプションの動作は、DO 命令の VARYING オプションの動作と同じです ( 上を参照) 。
無限ループを避けるために、WHILE 命令の条件が偽となる場合があること、または EXIT や STOP などの強制終了命令が命令ブロック内にあることを確認してください。
WHILE ループを任意の深さにネストして、他のループフォームに組み込むことも可能です。

DATA: LENGTH TYPE I
VALUE 0,
STRL
TYPE I VALUE 0,
STRING(30) TYPE C VALUE 'Test
String'.
STRL = STRLEN( STRING ).
WHILE STRING NE SPACE.
WRITE
STRING(1).
LENGTH =
SY-INDEX.
SHIFT
STRING.
ENDWHILE.
WRITE: /
'STRLEN: ',
STRL.
WRITE: / 'Length of string:',
LENGTH.
出力は、次のように表示されます。
T e s t S t r
i n g
STRLEN: 11
Length of
String: 11
WHILE ループは、文字列の長さを決めるために使われています。空白だけになるまで、ループ実行ごとに文字列を左に 1 つシフトして長さを決定します。この例を選んだのは、WHILE 命令の例を示すためです。もちろん、STRLEN 機能を使うと、文字列の長さをより簡単かつ効率的に調べることができます。
ABAP には、ループを予定より早く終了させる強制終了命令があります。強制命令には、ループだけに適用される命令とループの処理ブロック全体に適用される命令の 2 種類があります。STOP と REJECT 命令は、処理ブロック全体に適用されます。詳しい説明は、イベントブロックの終了を参照してください。
ループだけに適用される強制終了命令には、CONTINUE 、CHECK 、EXIT があります。CONTINUE 命令は 1 つのループに 1 回しか使用できません。CHECK と EXIT は、コンテキスト依存型です。ループ内では、そのループの実行にのみ適用されます。ループの外では、その処理ブロック全体 ( サブルーチン、ダイアログモジュール、イベントブロックなど) を強制終了します。
CONTINUE 、CHECK 、EXIT は、ABAP の 4 種類のループ (DO 、WHILE 、LOOP 、SELECT) すべてで使うことができます。
1 つのループパスを即座に無条件で終了する場合は、ループ内の命令ブロックに CONTINUE 命令を記述します。
この命令が実行されると、その命令ブロック内に残った命令は無視され、次のループパスが開始されます。

DO 4 TIMES.
IF SY-INDEX = 2.
CONTINUE.
ENDIF.
WRITE SY-INDEX.
ENDDO.
出力は次のようになります。
1 3 4
2 つ目のループは、WRITE 命令を処理せずに終了します。
1 つのループパスを条件付きで終了する場合は、ループ内の命令ブロックに CHECK < 条件> 命令を記述します。
条件が真でなければ、命令ブロック内の CHECK 命令の後の命令は無視され、次のループパスが開始されます。< 条件> には、論理式を指定してください。

DO 4 TIMES.
CHECK
SY-INDEX BETWEEN 2 and 3.
WRITE SY-INDEX.
ENDDO.
出力は次のようになります。
2 3
1 つ目と 4 つ目のループパスは、SY-INDEX が 2 と 3 の間ではないので、WRITE 命令を実行せずに終了されます。
ループ全体を即座に無条件で終了する場合は、ループ内の命令ブロックに EXIT 命令を記述します。
この命令が実行されると、ループは終了され、ループ構造の終了命令 (ENDDO 、ENDWHILE 、ENDLOOP 、ENDSELECT) の後で、処理が再開されます。ネストしたループでは、現在のループだけが終了します。

DO 4 TIMES.
IF SY-INDEX = 3.
EXIT.
ENDIF.
WRITE SY-INDEX.
ENDDO.
出力は次のようになります。
1 2
3 つ目のループパスでは、WRITE 命令を処理する前にループが終了します。