はじめに
COBOLで帳票を作成する際、決まった文字列だけでなく、プログラムの実行中に決定される動的な値を印字したい場面は多々あります。例えば、ユーザー名、処理日付、計算結果などを帳票に反映させたい場合などです。このような動的な値のバインドを実現するのが、REPORT SECTION における SOURCE 句 です。
SOURCE句を理解し活用することで、より柔軟でリッチな報告書作成が可能になります。本記事では、SOURCE句の基本的な使い方から、具体的な実装例、そして現場で役立つ注意点までを、ベテランCOBOL技術者の視点から解説します。
SOURCE句とは?
SOURCE句は、REPORT SECTIONで定義されるprintable item(印字可能な項目)に対して使用されます。その役割は、「印字するデータ値を、データ部の他の場所にあるデータ項目(主にWORKING-STORAGE SECTION)から取得することを指定する」ことにあります。
イメージとしては、「印字直前に自動的にMOVEが行われる」と考えていただくと分かりやすいでしょう。SOURCE句で指定されたデータ項目は、その値が自動的にprintable item に転送され、帳票として出力されます。
これにより、プログラムの実行時に入力された値や計算された値を、そのまま帳票に反映させることが可能になります。
SOURCE句の実装と解説
SOURCE句は、REPORT SECTION内のprintable item の宣言時に、COLUMN 句やLINE 句と組み合わせて使用されます。
基本構文
<position-number> [LINE NUMBER IS <line-number>] [COLUMN NUMBER IS <column-number>]
SOURCE IS <data-item>.
- <position-number>: 項目番号(必須)
- LINE NUMBER IS <line-number>: 印字する行番号(省略可能、省略時は前の項目と同じ行)
- COLUMN NUMBER IS <column-number>: 印字する開始桁(省略可能、省略時は前の項目と同じ桁)
- SOURCE IS <data-item>: 印字したい値を持つデータ項目を指定します。このデータ項目は、通常 WORKING-STORAGE SECTION で定義されます。
具体的な例
例えば、ユーザー名を表示する項目を定義する場合を考えてみましょう。
まず、WORKING-STORAGE SECTION でユーザー名を保持するデータ項目を定義します。
WORKING-STORAGE SECTION. 01 WS-USER-NAME PIC X(20) VALUE 'COBOL太郎'. 01 WS-PROCESS-DATE PIC X(10) VALUE '2023/10/27'.
次に、REPORT SECTION でこれらの値を印字する printable item を定義します。
REPORT SECTION. 01 WS-REPORT-PAGE-HEADING. 05 LINE 1 COL 1 PIC X(20) VALUE '--- 報告書 ---'. 05 LINE 2 COL 1 SOURCE IS WS-PROCESS-DATE. 05 LINE 2 COL 30 SOURCE IS WS-USER-NAME.
この例では、
- 2行目の1桁目には、WORKING-STORAGE SECTION の WS-PROCESS-DATE の値が印字されます。
- 2行目の30桁目には、WORKING-STORAGE SECTION の WS-USER-NAME の値が印字されます。
SOURCE句によって、これらのデータ項目に格納されている値が、指定された位置に自動的に出力されるのです。
サンプルプログラム
以下に、SOURCE句を使った簡単な報告書作成のサンプルプログラムを示します。このプログラムは、ヘッダー部分に動的な日付とユーザー名を表示する例です。
IDENTIFICATION DIVISION.
PROGRAM-ID. SOURCE-DEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-PROGRAM-DATE PIC X(10).
01 WS-USER-ID PIC X(8) VALUE 'USER001'.
01 WS-USER-NAME PIC X(20) VALUE 'COBOL技術者'.
01 WS-REPORT-LINE-1.
05 FILLER PIC X(10) VALUE '日付:'.
05 WS-REPORT-DATE-OUT SOURCE IS WS-PROGRAM-DATE.
05 FILLER PIC X(10) VALUE 'ユーザーID:'.
05 WS-REPORT-USERID-OUT SOURCE IS WS-USER-ID.
01 WS-REPORT-LINE-2.
05 FILLER PIC X(10) VALUE '氏名:'.
05 WS-REPORT-USERNAME-OUT SOURCE IS WS-USER-NAME.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
> 現在の日付を取得してフォーマットする
ACCEPT WS-PROGRAM-DATE FROM DATE.
> DATE句のデフォルトフォーマットは YYYYMMDD なので、YYYY/MM/DD に変換
STRING WS-PROGRAM-DATE(1:4) '/'
WS-PROGRAM-DATE(5:2) '/'
WS-PROGRAM-DATE(7:2)
DELIMITED BY SIZE INTO WS-PROGRAM-DATE.
> 報告書を出力する (REPORT SECTION を使用しない単純な例)
> 本来は REPORT SECTION で定義し、GENERATE 文で出力します。
> ここではSOURCE句の動作確認のために簡易的に表示します。
DISPLAY WS-REPORT-LINE-1.
DISPLAY WS-REPORT-LINE-2.
STOP RUN.
【コードのポイント】
- WORKING-STORAGE SECTION で、報告書に出力したいデータ項目(WS-PROGRAM-DATE, WS-USER-ID, WS-USER-NAME)を定義しています。
- WS-REPORT-LINE-1 および WS-REPORT-LINE-2 は、報告書の行を構成するレコード定義です。
- SOURCE IS 句を使って、各報告書項目(WS-REPORT-DATE-OUT, WS-REPORT-USERID-OUT, WS-REPORT-USERNAME-OUT)が、対応するWORKING-STORAGE SECTION のデータ項目から値を取得するように指定しています。
- `ACCEPT WS-PROGRAM-DATE FROM DATE.` で現在の日付を取得し、後続の STRING 文で表示しやすい形式(YYYY/MM/DD)に変換しています。
- このサンプルでは、REPORT SECTION の `GENERATE` 文を使わずに `DISPLAY` 文で直接出力していますが、SOURCE句の「指定されたデータ項目から値を取得して印字する」という動作は共通です。実際の報告書作成では、REPORT SECTION でprintable item を定義し、`GENERATE` 文で出力するのが一般的です。
応用・注意点
1. データ項目のピクチャー句の互換性
SOURCE句で指定するデータ項目(例: WS-USER-NAME)のピクチャー句と、printable item のピクチャー句は、互換性がある必要があります。一般的には、SOURCE句で指定するデータ項目のピクチャー句を、printable item のピクチャー句よりも広めに定義しておくと、データオーバーフローを防ぎやすくなります。あるいは、MOVE文で明示的に変換してから SOURCE句で指定する方法もあります。
2. EDITING FORM 句との組み合わせ
数値データなどを報告書に出力する場合、EDITING FORM句(例: Z, , ., / など)と組み合わせて、見やすい形式に整形することがよくあります。SOURCE句は、これらの編集済みデータをそのまま受け取ることができます。
01 WS-AMOUNT PIC 9(7) VALUE 12345. 01 WS-EDITED-AMOUNT. 05 COLUMN 10 SOURCE IS WS-AMOUNT EDITING ').99'.
この場合、WS-AMOUNT の値が編集され、例えば「 123.45」のように表示されます。
3. MOVE 文との違い
SOURCE句は「印字直前に自動的にMOVEが行われる」イメージですが、これはあくまで概念的な説明です。実際には、`GENERATE` 文が実行される際に、SOURCE句で指定されたデータ項目の値がprintable item に転送されます。明示的に `MOVE` 文を使用したい場合は、SOURCE句ではなく、printable item 自体に直接 MOVE するか、あるいは MOVE した結果を SOURCE句で参照するデータ項目を別に用意する必要があります。
4. 複雑なロジックの回避
SOURCE句で指定するデータ項目には、複雑な計算ロジックや条件分岐を直接記述することはできません。これらのロジックは、PROCEDURE DIVISION で `WORKING-STORAGE SECTION` のデータ項目に対して実行し、その結果を SOURCE句で参照するようにしてください。これにより、コードの可読性と保守性が向上します。
SOURCE句は、COBOLでの報告書作成において、動的なデータ連携を実現するための強力な機能です。今回ご紹介した内容を参考に、ぜひ現場での報告書作成に活用してみてください。

コメント