【COBOL学習|実務向け】報告書作成の高度な技:SUM … UPON 句で集計を自在に操る

1. 導入: なぜSUM…UPON句が重要なのか?

報告書を作成する際、集計処理は欠かせません。しかし、一つの報告書の中に複数の明細パターンが存在し、それらを個別に、あるいは特定の条件で集計したいという場面は少なくありません。例えば、売上報告書で「通常商品」と「キャンペーン商品」の売上を別々に集計したい場合や、在庫報告書で「正規在庫」と「一時保管在庫」を区別して集計したい場合などです。

このような複雑な集計要件を、従来の単一のSUM句で実現しようとすると、条件分岐を多用したり、一時的な作業領域を大量に確保したりと、プログラムが複雑化し、可読性や保守性が低下する原因となります。

ここで活躍するのが、COBOLの `SUM … UPON` 句です。この句を使うことで、特定の条件を満たすレコードのみを集計対象とすることができ、報告書作成機能における集計処理を、よりスマートかつ効率的に記述することが可能になります。

2. 基礎知識: SUM … UPON 句とは?

`SUM … UPON` 句は、`SUM` 句の拡張機能の一つで、「特定の条件を満たすレコードのみを集計対象とする」ための構文です。

  • SUM句: COBOLの基本的な集計命令です。通常、`SUM` 句は、対象となるレコード(通常はDETAIL段落で生成されるレコード)をすべて読み込み、指定された金額フィールドを合計します。
  • UPON句: `SUM` 句と組み合わせて使用され、集計対象となるレコードを限定する条件を指定します。`UPON` の後に指定する名前は、通常、特定の条件で生成されるレコードを識別するための名前(例えば、レコードタイプを示す項目など)です。

この `UPON` 句に指定する「条件」は、報告書の構造やデータの内容によって様々ですが、一般的には、報告書を生成する際に特定の条件で区分けされたレコードの「識別名」や「レコードタイプ」を指定します。

3. 実装/解決策: SUM … UPON 句の使い方

`SUM … UPON` 句の基本的な構文は以下の通りです。

SUM 金額フィールド名 UPON 集計条件指定名.

ここで、「集計条件指定名」には、通常、報告書生成時に特定の条件で発生するレコードを識別するために使用される項目名や、`RECORD` キーワードで定義されたレコードタイプ名などを指定します。

具体的には、報告書作成の `PRINTING` または `REPORTING` 段落などで、特定の条件分岐(例: `IF` 文や `EVALUATE` 文)によって異なるレコードタイプを生成する際に、それぞれのレコードタイプに名前を付けておき、その名前を `UPON` 句で指定します。

例えば、売上報告書で「通常商品」と「値引き商品」の売上を別々に集計したい場合、以下のようなイメージで実装します。

1. レコードタイプを識別する項目を定義する。
2. DETAIL段落などで、条件に応じてレコードタイプを識別する項目に値を設定する。
3. `SUM` 句で、各レコードタイプに対応する集計フィールドを定義し、`UPON` 句で集計対象を限定する。

4. サンプルプログラム

ここでは、商品売上報告書を想定し、「通常商品」と「キャンペーン商品」の売上を別々に集計するサンプルプログラムを示します。

IDENTIFICATION DIVISION.
PROGRAM-ID. SUMUPON-SAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TOTAL-AMT PIC 9(9) VALUE 0. > 通常商品の合計金額
01 WS-CAMPAIGN-AMT PIC 9(9) VALUE 0. > キャンペーン商品の合計金額

01 WS-RECORD-TYPE PIC X(1). > レコードタイプ識別用
88 IS-NORMAL-ITEM VALUE ‘N’. > 通常商品
88 IS-CAMPAIGN-ITEM VALUE ‘C’. > キャンペーン商品

01 WS-ITEM-AMT PIC 9(7) VALUE 0. > 商品単価

PROCEDURE DIVISION.
MAIN-PROCEDURE.
PERFORM PROCESS-RECORDS.
PERFORM DISPLAY-TOTALS.
STOP RUN.

PROCESS-RECORDS.
> ここではサンプルとして固定データを使用しますが、
> 実際にはファイル読み込みなどを行います。
MOVE 1000 TO WS-ITEM-AMT.
MOVE ‘N’ TO WS-RECORD-TYPE. > 通常商品
PERFORM ADD-TO-TOTALS.

MOVE 2500 TO WS-ITEM-AMT.
MOVE ‘C’ TO WS-RECORD-TYPE. > キャンペーン商品
PERFORM ADD-TO-TOTALS.

MOVE 1500 TO WS-ITEM-AMT.
MOVE ‘N’ TO WS-RECORD-TYPE. > 通常商品
PERFORM ADD-TO-TOTALS.

MOVE 3000 TO WS-ITEM-AMT.
MOVE ‘C’ TO WS-RECORD-TYPE. > キャンペーン商品
PERFORM ADD-TO-TOTALS.

ADD-TO-TOTALS.
> DETAIL段落に相当する処理
> ここで、WS-RECORD-TYPE に基づいて集計対象を判断します。
> SUM … UPON 句は、通常、REPORT WRITER の DETAIL 段落などで
> 自動的にレコードを処理する際に利用されますが、
> ここでは概念を理解するために、手動で集計処理を模倣します。

> 実際には REPORT WRITER を使用する場合、以下のような記述になります。
> SUM WS-ITEM-AMT UPON IS-NORMAL-ITEM.
> SUM WS-ITEM-AMT UPON IS-CAMPAIGN-ITEM.

> このサンプルでは、手動で条件分岐させて集計します。
IF IS-NORMAL-ITEM
ADD WS-ITEM-AMT TO WS-TOTAL-AMT
ELSE IF IS-CAMPAIGN-ITEM
ADD WS-ITEM-AMT TO WS-CAMPAIGN-AMT
END-IF.

DISPLAY-TOTALS.
DISPLAY “通常商品の合計金額: ” WS-TOTAL-AMT.
DISPLAY “キャンペーン商品の合計金額: ” WS-CAMPAIGN-AMT.

END PROGRAM SUMUPON-SAMPLE.

【サンプルコードの解説】

  • `WS-RECORD-TYPE` は、レコードの種類を識別するための項目です。`88` レベルで `IS-NORMAL-ITEM` と `IS-CAMPAIGN-ITEM` という条件名(条件変数)を定義しています。
  • `PROCESS-RECORDS` 内では、サンプルデータとして `WS-ITEM-AMT` に金額をセットし、`WS-RECORD-TYPE` に ‘N’ (通常商品) または ‘C’ (キャンペーン商品) を設定しています。
  • `ADD-TO-TOTALS` 段落では、本来 `SUM … UPON` 句が使われる `REPORT WRITER` の `DETAIL` 段落での処理を模倣しています。実際の `REPORT WRITER` では、`SUM WS-ITEM-AMT UPON IS-NORMAL-ITEM.` のように記述することで、`IS-NORMAL-ITEM` が真となるレコードのみ `WS-TOTAL-AMT` に加算されます。
  • このサンプルでは `REPORT WRITER` を直接使用せず、手動で `IF` 文を使って集計していますが、`SUM … UPON` 句の概念を理解するための一例として提示しています。

5. 応用・注意点

  • REPORT WRITERとの連携: `SUM … UPON` 句は、COBOLの `REPORT WRITER` 機能と組み合わせて使用されるのが一般的です。`REPORT WRITER` では、`SUM` 句を `CONTROL FOOTING` や `PAGE FOOTING` などで定義する際に、`UPON` 句で特定の `DETAIL` 段落で生成されたレコードタイプを指定することで、柔軟な集計が可能です。
  • 条件名の活用: `UPON` 句には、直接的な値だけでなく、`88` レベルで定義された条件名(例: `IS-NORMAL-ITEM`)を指定できます。これにより、コードの可読性が向上し、条件の意図が明確になります。
  • 集計フィールドの定義: `SUM` 句で集計するフィールドは、`WORKING-STORAGE SECTION` で定義し、初期値を `0` に設定しておく必要があります。
  • 複数の集計: 一つの報告書で複数の集計条件がある場合、それぞれの集計フィールドに対して `SUM … UPON` 句を記述することで、複数の集計を同時に行うことができます。
  • パフォーマンス: `SUM … UPON` 句は、条件に合致しないレコードの処理をスキップするため、単純な `SUM` 句や複雑な `IF` 文の羅列よりも効率的な場合があります。
  • データ整合性の確認: `UPON` 句に指定する条件が、実際に生成されるレコードタイプと一致しているか、十分にテストして確認することが重要です。意図しないレコードが集計対象となったり、逆に集計から漏れたりする可能性があります。

`SUM … UPON` 句を使いこなすことで、報告書作成機能における集計処理の記述が格段にシンプルになり、保守性も向上します。ぜひ、日々の開発業務で活用してみてください。

コメント

タイトルとURLをコピーしました