繰り返し処理

20.1 繰り返し処理

1. 繰り返し処理

繰り返し処理(ループ処理)は、同じ処理を複数回実行したいときに使用します。
ABAPでは、内部テーブルを順番に処理する LOOP命令 が代表的ですが、回数や条件で繰り返す DO命令、条件が成立している間だけ繰り返す WHILE命令 もよく使用します。

  • DOループ命令
  • WHILEループ命令
  • LOOP命令
  • 強制終了命令

DOループ命令

DOループ命令は、強制終了命令が発行されるまでDO~ENDDO内の処理を繰り返し行います。
強制終了命令を発行しない場合は、無限ループ状態となりますので注意が必要です。
そのため、回数が決まっている場合は DO n TIMES を優先し、回数が決められない場合でも 必ず終了条件 を入れるようにします。

  • 回数を指定しないループ
  • 回数を指定するループ

回数を指定しないループ

上記でも説明しましたが、強制終了命令を発行しない場合は、無限ループ状態となりますので注意が必要です。

サンプルコード:回数を指定しないループ
REPORT Z_SAMPLE201_DO.

DATA LV_COUNT TYPE I VALUE 0.

DO.
  LV_COUNT += 1.
  WRITE: / |DOの{ LV_COUNT }回目|.

  "終了条件(ないと無限ループになる)
  IF LV_COUNT = 3.
    EXIT.
  ENDIF.
ENDDO.

WRITE: / '処理完了'.

結果

回数を指定するループ

回数を指定するDOループは、次の通りです。指定した回数(n)分だけDO~ENDDO内の処理を繰り返し行います。

サンプルコード:回数を指定するループ
REPORT Z_SAMPLE201_DOCOUNT.

DATA LV_COUNT TYPE I VALUE 0.

START-OF-SELECTION.

  DO 3 TIMES.
    WRITE: / |SY-INDEX={ SY-INDEX }|.
  ENDDO.

  WRITE: / '処理完了'.
結果

WHILEループ命令

WHILEループ命令は、条件が真の間、WHILE~ENDWHILE内の処理を繰り返し行います。 なお、強制終了命令を使用した場合は、条件に関わらずループパスが終了します。
WHILEループ命令の構文は、以下となります。

条件式には「SY-INDEX > 10」のような限定的に成り立つ条件を指定しないと、無限ループに陥ります。

サンプルコード
REPORT Z_SAMPLE201_WHILE.

START-OF-SELECTION.

  DATA LV_COUNT TYPE I VALUE 0.

  WHILE LV_COUNT < 3.
    LV_COUNT += 1.
    WRITE: / |WHILEの{ LV_COUNT }回目|.
  ENDWHILE.

  WRITE: / '処理完了'.
結果

LOOP命令

LOOP命令は、「同じ処理の繰り返し」を行い、 内部テーブルから「特定のデータを抽出して処理を行う場合」に利用されます。

LOOP命令①

LOOP命令の構文は、以下となります。

<ポイント>
① LOOP処理を行う内部テーブルを指定すること
② LOOP処理で対象となるレコードを格納する構造を指定すること

LOOP命令②

LOOPでは、内部テーブルを1行1行処理をしていきます。
このとき、留意する必要があるのが、LOOP ATでは指定した内部テーブルを直接処理するのではなく、一時的に別の構造に対象の行を格納して処理を進める、という点です。
以下のようなイメージです。

内部テーブルの1行1行を、別の構造に格納して処理を進めるイメージです。
したがって、LOOP~ENDLOOPには、①対象の内部テーブルと②作業エリア(構造)の指定が 必要となるのです。


サンプルコード:LOOP命令(条件指定なし)
REPORT Z_SAMPLE201_LOOPAT.

TYPES: BEGIN OF TY_ITEM,
         ITEM_NAME TYPE STRING,
         ITEM_CODE TYPE N LENGTH 4,
         PRICE     TYPE I,
       END OF TY_ITEM.

START-OF-SELECTION.

  DATA LT_ITEM TYPE STANDARD TABLE OF TY_ITEM WITH EMPTY KEY.

  APPEND VALUE #( ITEM_NAME = 'りんご' ITEM_CODE = '0001' PRICE = 100 ) TO LT_ITEM.
  APPEND VALUE #( ITEM_NAME = 'みかん' ITEM_CODE = '0002' PRICE = 30  ) TO LT_ITEM.
  APPEND VALUE #( ITEM_NAME = 'いちご' ITEM_CODE = '0003' PRICE = 80  ) TO LT_ITEM.

  WRITE: / '商品名', 15 '商品コード', 30 '値段'.
  ULINE.

  LOOP AT LT_ITEM INTO DATA(LS_ITEM).
    WRITE: / LS_ITEM-ITEM_NAME, 15 LS_ITEM-ITEM_CODE, 30 LS_ITEM-PRICE.
  ENDLOOP.
結果

補足(SY-TABIXについて)

システム項目の一つで「現在ループしているテーブルの対象行」が格納されます。
LOOP文を使用するとSY-TABIX にテーブルの対象行が格納されると覚えておきましょう。

LOOP命令③

LOOP命令では、WHEREオプションを用いて処理の対象としたいレコードを特定することが可能です。

サンプルコード:LOOP命令(条件指定あり)
REPORT Z_SAMPLE201_LOOPWHERE.

TYPES: BEGIN OF TY_ITEM,
         ITEM_NAME TYPE STRING,
         ITEM_CODE TYPE N LENGTH 4,
         PRICE     TYPE I,
       END OF TY_ITEM.

START-OF-SELECTION.

  DATA LT_ITEM TYPE STANDARD TABLE OF TY_ITEM WITH EMPTY KEY.
  CONSTANTS LC_TARGET TYPE STRING VALUE 'みかん'.

  APPEND VALUE #( ITEM_NAME = 'りんご' ITEM_CODE = '0001' PRICE = 100 ) TO LT_ITEM.
  APPEND VALUE #( ITEM_NAME = 'みかん' ITEM_CODE = '0002' PRICE = 30  ) TO LT_ITEM.
  APPEND VALUE #( ITEM_NAME = 'いちご' ITEM_CODE = '0003' PRICE = 80  ) TO LT_ITEM.

  WRITE: / '商品名', 15 '商品コード', 30 '値段'.
  ULINE.

  LOOP AT LT_ITEM INTO DATA(LS_ITEM) WHERE ITEM_NAME = LC_TARGET..
    WRITE: / LS_ITEM-ITEM_NAME, 15 LS_ITEM-ITEM_CODE, 30 LS_ITEM-PRICE.
  ENDLOOP.
結果

LOOP命令(新構文)

LOOP命令も新構文を用いることができます。構文は、以下となります。

旧構文では、作業用の構造を事前に宣言(定義)する必要がありましたが 新構文では、内部テーブルと同じ構造が自動で作成されます。

サンプルコード:LOOP命令(新構文)
REPORT Z_SAMPLE_S12_309_NEW NO STANDARD PAGE HEADING

*&---------------------------------------------------------------------*
* TYPES宣言
*&---------------------------------------------------------------------*
* 構造データ型
  TYPES:
    BEGIN OF TYP_ST,
      NAME  TYPE C LENGTH 10,
      CODE  TYPE C LENGTH 10,
      VALUE TYPE C LENGTH 10,
    END   OF TYP_ST.

* テーブルデータ型
  TYPES TYP_T TYPE STANDARD TABLE OF TYP_ST.

*&---------------------------------------------------------------------*
* DATA宣言
*&---------------------------------------------------------------------*
*  DATA IT_TEST TYPE TYP_T.
  DATA IT_TEST TYPE STANDARD TABLE OF TYP_ST.

*&---------------------------------------------------------------------*
* CONSTANTS宣言
*&---------------------------------------------------------------------*
  CONSTANTS CNS_FRUIT TYPE C LENGTH 6 VALUE 'みかん'.

*&---------------------------------------------------------------------*
*  LOOP命令(新構文)
*&---------------------------------------------------------------------*
  START-OF-SELECTION.

*   内部テーブルにデータを追加
    APPEND VALUE #( NAME = ‘りんご’         CODE = ‘0001’ VALUE = ‘100’ ) TO IT_TEST.
    APPEND VALUE #( NAME = CNS_FRUIT CODE = ‘0002’ VALUE = ‘30’   ) TO IT_TEST.
    APPEND VALUE #( NAME = ‘イチゴ’         CODE = ‘0003’ VALUE = ‘80’   ) TO IT_TEST.
    APPEND VALUE #( NAME = CNS_FRUIT CODE = ‘0004’ VALUE = ‘31’   ) TO IT_TEST.


*   内部テーブルの結果を出力
    WRITE: |商品名 商品コード 値段|.

*   今回はみかんだけ出力させる
    LOOP AT IT_TEST INTO DATA(ST_TEST) WHERE NAME = CNS_FRUIT.

      WRITE / ST_TEST.

    ENDLOOP.

  END-OF-SELECTION.

強制終了命令

単一ループパスを終了したり、ループ全体を終了したりする場合は、強制終了命令を使用します。

  • CHECK命令
  • CONTINUE命令
  • EXIT命令

CHECK命令

CHECK命令は、条件が成立しない場合に、その時点で現在の処理ブロックから抜けます。
ループ内で使うと、「条件に合わない行はスキップする」という用途になります。(結果として次の行へ進みます)。
※ループ外でのCHECKは意図が伝わりにくく、非推奨とされるため、基本はループ内で使用します。

サンプルコード:CHECK命令
REPORT Z_SAMPLE201_CHECK.

TYPES: BEGIN OF TY_ITEM,
         NAME TYPE STRING,
         CODE TYPE N LENGTH 4,
         VAL  TYPE I,
       END OF TY_ITEM.

START-OF-SELECTION.

  DATA LT_ITEM TYPE STANDARD TABLE OF TY_ITEM WITH EMPTY KEY.

  APPEND VALUE #( NAME = 'りんご' CODE = '0001' VAL = 100 ) TO LT_ITEM.
  APPEND VALUE #( NAME = 'みかん' CODE = '0002' VAL = 30  ) TO LT_ITEM.
  APPEND VALUE #( NAME = 'いちご' CODE = '0003' VAL = 80  ) TO LT_ITEM.

  WRITE: / '(CODE=0002 の行だけ出力)'.

  LOOP AT LT_ITEM INTO DATA(LS_ITEM).
    CHECK LS_ITEM-CODE = '0002'.
    WRITE: / |{ LS_ITEM-NAME } { LS_ITEM-CODE } { LS_ITEM-VAL }|.
  ENDLOOP.	
結果

CONTINUE命令

CONTINUE命令は、現在のループ1回分の処理を打ち切って、次のループへ進む命令です。

※CONTINUE命令は、ループ内でしか使えません。

サンプルコード:CONTINUE命令
REPORT Z_SAMPLE_KANDA_01 NO STANDARD PAGE HEADING.

*&---------------------------------------------------------------------*
* TYPES宣言
*&---------------------------------------------------------------------*
* 構造データ型
  TYPES:
    BEGIN OF TYP_ST,
      NAME  TYPE C LENGTH 10,
      CODE  TYPE C LENGTH 10,
      VALUE TYPE C LENGTH 10,
    END   OF TYP_ST.

* テーブルデータ型
  TYPES TYP_T TYPE STANDARD TABLE OF TYP_ST.
*&---------------------------------------------------------------------*
* DATA宣言
*&---------------------------------------------------------------------*
*  DATA IT_TEST TYPE TYP_T.
  DATA IT_TEST TYPE STANDARD TABLE OF TYP_ST.

*&---------------------------------------------------------------------*
*  CHECK命令
*&---------------------------------------------------------------------*
  START-OF-SELECTION.

*   内部テーブルにデータを追加
    APPEND VALUE #( NAME = ‘りんご’ CODE = ‘0001’ VALUE = ‘100’ ) TO IT_TEST.
    APPEND VALUE #( NAME = ‘みかん’ CODE = ‘0002’ VALUE = ‘30’   ) TO IT_TEST.
    APPEND VALUE #( NAME = ‘イチゴ’ CODE = ‘0003’ VALUE = ‘80’   ) TO IT_TEST.

*  内部テーブルの結果を出力
    LOOP AT IT_TEST INTO DATA(ST_TEST).

*    現在の行が2行目だった場合
      IF SY-TABIX = 2.
*      LOOPの先頭に戻る(3件目の処理に行く)
        CONTINUE.
      ENDIF.

      WRITE / ST_TEST.

    ENDLOOP.

  END-OF-SELECTION. 
結果

EXIT命令

EXIT命令を記述すると、CONTINE命令同様 ループ処理を無条件に終了します。

※EXIT命令は、ループ外にも書けますが、処理の意図が曖昧になりやすいため、「ループを抜ける目的」でループ内に書く運用を基本にします。。 動作としてはRETURNと同じですがRETURNは呼び出し元に戻る命令に対して、EXITは強制終了する命令です。

サンプルコード:EXIT命令
REPORT Z_SAMPLE201_EXIT.

TYPES: BEGIN OF TY_ITEM,
         NAME TYPE STRING,
         CODE TYPE N LENGTH 4,
         VAL  TYPE I,
       END OF TY_ITEM.

START-OF-SELECTION.

  DATA LT_ITEM TYPE STANDARD TABLE OF TY_ITEM WITH EMPTY KEY.

  APPEND VALUE #( NAME = 'りんご' CODE = '0001' VAL = 100 ) TO LT_ITEM.
  APPEND VALUE #( NAME = 'みかん' CODE = '0002' VAL = 30  ) TO LT_ITEM.
  APPEND VALUE #( NAME = 'いちご' CODE = '0003' VAL = 80  ) TO LT_ITEM.

  WRITE: / '(最初の1行だけ出力してループ終了)'.

  LOOP AT LT_ITEM INTO DATA(LS_ITEM).
    WRITE: / |{ LS_ITEM-NAME } { LS_ITEM-CODE } { LS_ITEM-VAL }|.
    EXIT.
  ENDLOOP.
結果

NEXT>> 20.2 日付と時刻の計算(SY)

研修の詳細はこちら