【COBOL学習|豆知識】報告書作成の要!DETAIL集団とGENERATE命令の正しい同期術

導入:なぜGENERATE命令のタイミングが重要なのか

COBOLのReport Writer機能(RPT)を利用する際、最も混乱を招きやすいのが「いつ明細(DETAIL)行が物理的に印字されるか」という点です。プログラムの論理的な処理順序と、帳票上の行配置が連動しないと、意図しない改ページが発生したり、不要な空行が混入したりするトラブルに繋がります。今回は、GENERATE命令が裏側で行っている処理の仕組みと、制御の勘所を解説します。

基礎知識:Report Writerの「自動制御」を理解する

Report Writerにおいて、DETAIL集団は「明細行」を定義するものです。しかし、ただ定義しただけでは何も出力されません。手続き部で GENERATE 命令を実行することで初めて、Report Writer機能が起動します。

重要なのは、GENERATE命令が呼ばれた瞬間に「以下の判定」が連鎖的に行われる点です。
1. 改ページ(PAGE LIMIT)判定:現在の行位置が、定義したページ終了行を超えていないか。
2. 改ページ処理:超えている場合、自動的に「REPORT FOOTING」と「PAGE FOOTING」を出力し、改ページして「PAGE HEADING」を出力する。
3. 明細行の印字:上記判定をクリアした後、定義されたDETAIL集団をバッファに書き出す。

つまり、GENERATE命令は単なる印字命令ではなく、「帳票レイアウト管理」を伴う高度な制御命令なのです。

実装:手続き部での制御手順

GENERATEを呼び出す前に、明細行の変数(ソースデータ)に値をセットしておくことが必須です。手続き部では、以下の順序を厳守してください。

1. 明細データ(データ部)への値セット
2. GENERATE命令の実行

サンプルプログラム:明細印字の基本実装

以下は、売上明細を1行ずつ出力する基本的な手続き部の記述例です。

IDENTIFICATION DIVISION.
PROGRAM-ID. DETAIL-PRINT-SAMPLE.

PROCEDURE DIVISION.
> ページヘッダ等の初期化(必要に応じて)

PERFORM UNTIL 売上データ終了
> 1. 明細行にセットするデータを準備
MOVE WS-SALES-DATE TO SALES-DATE-OUT
MOVE WS-SALES-AMT TO SALES-AMT-OUT

> 2. GENERATE命令を実行
> ここで自動的に改ページ判定と行送りが行われる
GENERATE DETAIL-LINE

READ SALES-FILE
END-PERFORM.

STOP RUN.

応用・注意点:現場でハマりやすい罠

現場でよくある失敗は、「GENERATEをループ内で複数回呼んでしまう」ことによる重複印字です。

注意点1:制御切れの判定との兼ね合い
CONTROL句(集計制御)を使用している場合、GENERATE命令によって「制御切れ」が検知されると、自動的に「CONTROL FOOTING」や「CONTROL HEADING」が挿入されます。自分が意図した明細行の前に、突然見出し行が入る可能性があることを常に意識してください。

注意点2:物理的な行位置の制御
もし、特定の処理の前に強制的に改ページさせたい場合は、GENERATEを使うのではなく SUPPRESS PRINTING を活用するか、あるいは明細行の定義で NEXT GROUP IS NEXT PAGE を利用する方が、Report Writerの機能を損なわずに実装可能です。

Report Writerは強力ですが、ブラックボックス的な挙動が多い機能です。まずはGENERATEが「印字+判定」のセットであることを理解し、論理と物理のズレを意識してコーディングしましょう。

コメント

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