グループ化とループ処理

GROUP および LOOP コマンドは、一連のコマンドを繰り返し実行するための 2 つの方法を提供します。GROUP は各レコードに対して 1 つ以上のコマンドを 1 回繰り返します。LOOP は単一レコードに対して一連のコマンドを複数回繰り返して実行し、GROUP ブロック内でのみ使用できます。

GROUP の簡単な例

請求書データのテーブル Ap_Trans があります。このデータを使用して、請求金額の合計を計算する必要があります。

Vendor_Number Vendor_Name Invoice_Number 日付 金額
11663 More Power Industries 5981807 2000-11-17 618.30
13808 NOVATECH Wholesale 2275301 2000-11-17 6705.12
12433 Koro International 6585673 2000-11-17 7955.46

この金額を計算するには、GROUP コマンドを使用します。GROUP の各繰り返し内で次のことを実行します。

  1. 現在のレコードの時点で合計を計算します。
  2. 請求書番号、金額、日付、合計を結果テーブルに抽出します。
OPEN AP_Trans

COMMENT 累計の初期値をゼロに設定 END
ASSIGN v_running_total = 0.00

COMMENT テーブルの各レコードを繰り返し、累計を計算して抽出 END
GROUP
  ASSIGN v_running_total = v_running_total + Amount
  EXTRACT Invoice_Number, Amount, Date, v_running_total AS "Running total" TO results1
END

スクリプトが実行されると、GROUP ブロック内のコマンドはテーブルの各レコードに対して上から下に処理され、合計が計算され、抽出されます。実行される GROUP コマンドを見ると、次のような仕組みになっています。

GROUP の最初の繰り返し:合計 = 0.00 + 618.30

GROUP は最初のレコードの請求金額を 0.00 の初期合計に追加し、フィールドを結果テーブルに抽出します。

Vendor_Number Vendor_Name Invoice_Number 日付 金額
11663 More Power Industries 5981807 2000-11-17 618.30
13808 NOVATECH Wholesale 2275301 2000-11-17 6705.12
12433 Koro International 6585673 2000-11-17 7955.46

GROUP の 2 番目の繰り返し:合計 = 618.30 + 6705.12

GROUP は 2 番目のレコードの請求金額を新しい合計の 618.30 に追加し、フィールドを結果テーブルに抽出します。

Vendor_Number Vendor_Name Invoice_Number 日付 金額
11663 More Power Industries 5981807 2000-11-17 618.30
13808 NOVATECH Wholesale 2275301 2000-11-17 6705.12
12433 Koro International 6585673 2000-11-17 7955.46

GROUP の 3 番目の繰り返し:合計 = 7323.42 + 7955.46

GROUP は 3 番目のレコードの請求金額を新しい合計 7323.42 に追加し、フィールドを毛かテーブルに抽出します。

Vendor_Number Vendor_Name Invoice_Number 日付 金額
11663 More Power Industries 5981807 2000-11-17 618.30
13808 NOVATECH Wholesale 2275301 2000-11-17 6705.12
12433 Koro International 6585673 2000-11-17 7955.46

最終結果テーブル

GROUP がテーブルの最終レコードを処理した後、次の結果テーブルが作成されます。

Invoice_Number 金額 日付 Running_total
5981807 618.30 2000-11-17 618.30
2275301 6705.12 2000-11-17 7323.42
6585673 7955.46 2000-11-17 15278.88

GROUP IF を使用したさまざまな場合の処理

上記と同じ Ap_Trans テーブルを使用して、3 種類の請求書の累計を計算する必要があります。

  • 高額(1000.00 以上)
  • 標準額(100.00 ~ 1000.00)
  • 低額(100.00 未満)

GROUP コマンドは異なる場合を処理するために IF/ELSE 構造を提供します。テストする条件式を提供し、レコードが真と評価される場合は、ブロック内のコマンドが実行されます。

場合のテスト方法

場合は上から下にテストされ、レコードは 1 つの IF/ELSE ブロックでのみ処理できます。レコードの真に評価される最初の場合は、レコードを処理するものです。

  1. GROUP が最初のレコードを処理すると、最初の IF 条件に対してテストします(Amount >= 1000)。真と評価される場合、この場合のコードが実行され、他の場合はテストされません。
  2. 最初の場合が偽と評価されると、次の ELSE IF 条件 (Amount >= 100) がテストされます。同時に真と評価される場合、この場合のコードが実行され、他の場合はテストされません。
  3. いずれの IF または ELSE IF 場合が真と評価される場合、ELSE ブロックのデフォルトの場合がレコードを処理します。

メモ

レコードが複数の場合で真と評価される場合、レコードはテストする最初の IF/ELSE ブロックでのみ処理されます。レコードは GROUP コマンド内の複数の IF/ELSE ブロックでは処理されません。

OPEN AP_Trans

COMMENT 累計の初期値を設定 END
ASSIGN v_running_total_hi = 0.00
ASSIGN v_running_total_med = 0.00
ASSIGN v_running_total_low = 0.00

COMMENT GROUP IF を使用して、請求金額に応じて別の ASSIGN および EXTRACT コマンドを実行 END
GROUP IF Amount >= 1000
  ASSIGN v_running_total_hi = v_running_total_hi + Amount
  EXTRACT Invoice_Number, Amount, Date, v_running_total_hi AS "Running total" TO results_hi
ELSE IF Amount >= 100
  ASSIGN v_running_total_med = v_running_total_med + Amount
  EXTRACT Invoice_Number, Amount, Date, v_running_total_med AS "Running total" TO results_med
ELSE
  ASSIGN v_running_total_low = v_running_total_low + Amount
  EXTRACT Invoice_Number, Amount, Date, v_running_total_low AS "Running total" TO results_low
END

スクリプトの実行時には、GROUP コマンドは各レコードの請求金額をテストします。金額によっては、レコードは 3 つの合計(低、中、高)のいずれかを更新するために使用され、3 つの結果テーブルが生成されます。

GROUP 内の LOOP

GROUP を使用してテーブルのレコードを処理するときには、LOOP コマンドを使用して、単一のレコードに対して一連のコマンドを複数回実行できます。LOOP は GROUP 内の繰り返し内で発生する 2 番目の繰り返しであり、指定するテスト条件が偽と評価されるまで実行されます。

LOOP を使用してフィールドを分割する

請求データを含む次のテーブルがあり、部署単位で請求金額の特定の情報を分離する必要があります。1 つの請求書は複数の部署に関連付けることができ、部署コードがカンマ区切りでテーブルに保存されます。

Vendor_Number Invoice_Number 日付 金額 Dept_Code
11663 5981807 2000-11-17 618.30 CCD,RDR
13808 2275301 2000-11-17 6705.12 CCD
12433 6585673 2000-11-17 7955.46 CCD,LMO,RDR

請求金額を部署ごとに抽出するには

  1. GROUP コマンドを使用して、テーブルの各レコードを処理します。
  2. 各レコードに関連付けられた部署 (n) 数を計算します。
  3. LOOP コマンドを使用して、レコードに関連付けられた各部署のデータを抽出する操作を n 回繰り返します。

メモ

LOOP 内では v_counter 変数を増やす必要があります。そうしない場合、WHILE テストは常に真と評価され、スクリプトは無限ループに入ります。スクリプトに SET LOOP コマンドを含め、無限ループを防止できます。詳細については、SET LOOP コマンドを参照してください。

COMMENT
GROUP を使用すると、各部署コード フィールドのコメントをカウントし、レコードに関連付けられている部署数を特定します
LOOP でフィールドの各コードをレコードごとに「ループ」します。ループを繰り返すたびに、単一のコードのレコードが result1 テーブルに抽出されます
END

GROUP
v_department_count = OCCURS(Dept_Code,',')
v_counter = 0
LOOP WHILE v_counter <= v_department_count
v_dept = SPLIT(Dept_Code, ',', (v_counter + 1))
EXTRACT FIELDS Invoice_Number, Amount, v_dept AS "Department" TO result1
v_counter = v_counter + 1
END
END

スクリプトが実行されると、GROUP ブロック内のコマンドは上から下にテーブルの各レコードに対して処理されます。各レコードでは、LOOP コマンドがカンマ区切りのリストの部署コード単位で 1 回レコードに対して繰り返され、レコードを抽出します。実行される GROUP および LOOP コマンドを見ると、次のような仕組みになっています。

GROUP の 1 番目の繰り返し:LOOP の 2 つの繰り返し

Vendor_Number Invoice_Number 日付 金額 Dept_Code
11663 5981807 2000-11-17 618.30 CCD,RDR
13808 2275301 2000-11-17 6705.12 CCD
12433 6585673 2000-11-17 7955.46 CCD,LMO,RDR

テーブルの 1 番目のレコードでは、v_department_count の値が 1 になるため、LOOP は 2 回繰り返します。

  1. LOOP の最初の繰り返し:
    • v_counter = 0
    • v_depart = CCD

    次のレコードが抽出され、v_counter の値が 1 になるため、LOOP はもう一度繰り返します。

    5981807618.30CCD
  2. LOOP の 2 回目の繰り返し:
    • v_counter = 1
    • v_depart = RDR

    次のレコードが抽出され、v_counter の値が 2 になるため、LOOP は繰り返さず、GROUP は次のレコードに進みます。

    5981807618.30RDR

GROUP の 2 番目の繰り返し:LOOP の 1つの繰り返し

Vendor_Number Invoice_Number 日付 金額 Dept_Code
11663 5981807 2000-11-17 618.30 CCD,RDR
13808 2275301 2000-11-17 6705.12 CCD
12433 6585673 2000-11-17 7955.46 CCD,LMO,RDR

テーブルの 2 番目のレコードでは、v_department_count の値が 0 になるため、LOOP は 1 回繰り返します。

  • v_counter = 0
  • v_depart = CCD

次のレコードが抽出され、v_counter の値が 1 になるため、LOOP は繰り返さず、GROUP は次のレコードに進みます。

2275301 6705.12 CCD

GROUP の 3 番目の繰り返し:LOOP の 3 つの繰り返し

Vendor_Number Invoice_Number 日付 金額 Dept_Code
11663 5981807 2000-11-17 618.30 CCD,RDR
13808 2275301 2000-11-17 6705.12 CCD
12433 6585673 2000-11-17 7955.46 CCD,LMO,RDR

テーブルの 3 番目のレコードでは、v_department_count の値が 2 であるため、LOOP は 3 回繰り返します。

  1. LOOP の最初の繰り返し:
    • v_counter = 0
    • v_depart = CCD

    次のレコードが抽出され、v_counter の値が 1 になるため、LOOP はもう一度繰り返します。

    65856737955.46CCD
  2. LOOP の 2 回目の繰り返し:
    • v_counter = 1
    • v_depart = LMO

    次のレコードが抽出され、v_counter の値が 2 になるため、LOOP はもう一度繰り返します。

    65856737955.46LMO
  3. LOOP の 3 回目の繰り返し:
    • v_counter = 2
    • v_depart = RDR

    次のレコードが抽出され、v_counter の値が 3 になるため、LOOP は繰り返さず、GROUP はテーブルの最後に達します。

    65856737955.46RDR

最終結果テーブル

GROUP がテーブルの各レコードを処理し、LOOP がすべての部署コードを繰り返した後、次の結果テーブルが生成されます。

Invoice_Number 金額 部門
5981807 618.30 CCD
5981807 618.30 RDR
2275301 6705.12 CCD
6585673 7955.46 CCD
6585673 7955.46 LMO
6585673 7955.46 RDR