1. 導入:なぜ合計値に手を触れてはいけないのか
COBOLのReport Writer機能(REPORT SECTION)を使っていると、改ページごとに合計値をリセットしたくなる場面がありますよね。「手続き部(PROCEDURE DIVISION)でMOVE 0すれば手っ取り早い」と考えるのは、ベテランでも陥りがちな罠です。しかし、これはReport Writerの制御を根底から崩す禁じ手です。なぜなら、Report Writerは独自の内部ロジックで集計のタイミングを管理しており、外部からの介入はその整合性を一瞬で破壊してしまうからです。
2. 基礎知識:Report Writerの集計の仕組み
Report WriterのSUM句は、単なる変数の加算ではありません。出力行が生成される(GENERATE文)たびに、内部的に「どのレベルの集計か」を判定し、自動的に値を加算し、出力後に特定の制御(リセットなど)を自動で行う仕組みです。
私たちが手続き部で勝手に値を書き換えてしまうと、Report Writerはその変更を検知できず、次の集計計算時に「本来あるべき値」と「現在の値」の差異により、誤った集計結果を出力することになります。
3. 実装/解決策:正しいリセット方法
合計値をリセットしたい場合は、手続き部で無理やり数値を代入するのではなく、Report Writerの自動リセット機能を信じてください。SUM句を定義したデータ項目は、定義されたレベル(CONTROL句で指定した項目)が変わった瞬間に、Report Writerが自動的にゼロクリアを行います。
4. サンプルプログラム:正しい合計値の制御
以下は、部門ごとの売上合計を正しく出力するための構成例です。
REPORT SECTION.
RD SAMPLE-REPORT
CONTROLS ARE FINAL DEPARTMENT-CODE.
01 DETAIL-LINE TYPE IS DETAIL.
05 ITEM-VAL PIC 9(5).
01 DEPT-TOTAL-LINE TYPE IS CONTROL FOOTING DEPARTMENT-CODE.
05 DEPT-SUM PIC Z(7)9 SOURCE SUM(ITEM-VAL).
> ここでSUM句を使えば、DEPARTMENT-CODEが変わった瞬間に
> 自動的にゼロクリアされるため、MOVE 0は一切不要です。
PROCEDURE DIVISION.
> 手続き部では、ただGENERATEするだけ
MOVE 100 TO ITEM-VAL.
GENERATE DETAIL-LINE.
> 手続き部で合計カウンタを直接操作するようなコードは記述しないこと!
5. 応用・注意点:現場で生き残るために
もし、「どうしても特殊な条件でリセットしたい」という複雑な要件がある場合は、合計カウンタをSUM句で定義するのではなく、自分で計算用の項目を別途定義し、手続き部で完全に制御するという手段をとるべきです。
「Report WriterのSUM句」を使うのであれば、その制御権は完全にCOBOLのランタイム(RW機能)に委譲するというのがプロの作法です。中途半端に「自動集計」と「手動代入」を混ぜ合わせると、テスト環境では正常に見えても、本番環境で特定の条件が重なった時にだけ合計がズレるという、極めて恐ろしいバグを引き起こします。
「Report Writerに任せるなら徹底的に任せる」。これが、保守性の高い帳票プログラムを作る唯一の道です。

コメント