[COBOLのはじめ方] Part22: 売上集計プログラムの作成

COBOL
“`html

はじめに

これまでのステップで、COBOLの基本的な文法、制御構文、ファイル操作などを学んできました。お疲れ様でした!😊 このステップでは、これまでの知識を総動員して、実務でもよく使われる「売上集計プログラム」を作成するミニプロジェクトに挑戦します。

このプログラムは、日々の売上データが記録されたファイルを読み込み、商品ごとに売上金額を集計して、結果を別のファイルに出力するものです。COBOLが得意とするバッチ処理の典型的な例です。さっそく仕様を確認していきましょう!💻

プログラムの仕様

今回の売上集計プログラムの仕様は以下の通りです。

1. 入力ファイル(売上データ)

入力ファイル (SALES-IN.DAT) は、1レコードが1つの売上明細を表すシーケンシャルファイルです。各レコードのレイアウトは以下の通りです。(固定長レコード)

項目名 桁数 (Bytes) データ型 内容
商品コード 5 文字 (PIC X(5)) 商品を一意に識別するコード
数量 3 数字 (PIC 9(3)) 販売した数量
単価 5 数字 (PIC 9(5)) 商品の単価

入力データ例:

A000101010000
B000200505000
A000100220000
C000302000800
B000200305000

2. 出力ファイル(集計結果)

出力ファイル (SALES-OUT.DAT) には、商品コードごとの合計売上金額を集計した結果を書き込みます。各レコードのレイアウトは以下の通りです。

項目名 桁数 (Bytes) データ型 内容
商品コード 5 文字 (PIC X(5)) 商品を一意に識別するコード
合計売上金額 8 数字 (PIC 9(8)) 商品ごとの合計売上金額 (数量 * 単価 の合計)

上記入力データに対する期待される出力データ例:

A00010030000
B00020040000
C00030016000

補足: 集計処理を行うためには、入力ファイルが商品コード順にソートされている必要があります。今回は事前にソートされている前提としますが、実務ではSORT文を使ってプログラム内でソートすることもよくあります(Step 4で学習しましたね!)。

3. 処理内容

  1. 入力ファイル (SALES-IN.DAT) を開きます。
  2. 出力ファイル (SALES-OUT.DAT) を開きます。
  3. 入力ファイルから1レコード読み込みます。
  4. ファイルの終わり (EOF) になるまで、以下の処理を繰り返します。
    1. 現在のレコードの商品コードを保持します。
    2. 同じ商品コードのレコードを続けて読み込みながら、売上金額(数量 * 単価)を合計します。
    3. 商品コードが変わるか、ファイルの終わりに達したら、保持していた商品コードと計算した合計売上金額を出力ファイルに書き込みます。
  5. 入力ファイルと出力ファイルを閉じます。

この処理方法は「コントロールブレイク(制御切れ)」と呼ばれる古典的なバッチ処理のパターンの一つです。

COBOLプログラムの構造とコード例

それでは、上記の仕様を満たすCOBOLプログラムの構造と、各DIVISIONのコード例を見ていきましょう。

1. IDENTIFICATION DIVISION

プログラムの名前を定義します。

IDENTIFICATION DIVISION.
PROGRAM-ID. SALES-SUMMARY.
AUTHOR. COBOL-LEARNER.

2. ENVIRONMENT DIVISION

プログラムが使用するファイル(入力・出力)を定義します。

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT SALES-IN-FILE ASSIGN TO "SALES-IN.DAT"
        ORGANIZATION IS LINE SEQUENTIAL.
    SELECT SALES-OUT-FILE ASSIGN TO "SALES-OUT.DAT"
        ORGANIZATION IS LINE SEQUENTIAL.
  • SELECT句で論理ファイル名 (SALES-IN-FILE, SALES-OUT-FILE) と物理ファイル名 ("SALES-IN.DAT", "SALES-OUT.DAT") を関連付けます。
  • ORGANIZATION IS LINE SEQUENTIAL は、テキストファイル(行区切り)として扱うことを示します。環境によっては ORGANIZATION IS SEQUENTIAL などが適切な場合もあります。

3. DATA DIVISION

プログラム内で使用するデータ項目(ファイルレコード、作業用変数など)を定義します。

FILE SECTION

ENVIRONMENT DIVISION で定義したファイルのレコード構造を定義します。

DATA DIVISION.
FILE SECTION.
FD  SALES-IN-FILE.
01  SALES-IN-REC.
    05 SI-PROD-CODE    PIC X(5).
    05 SI-QUANTITY     PIC 9(3).
    05 SI-UNIT-PRICE   PIC 9(5).

FD  SALES-OUT-FILE.
01  SALES-OUT-REC.
    05 SO-PROD-CODE    PIC X(5).
    05 SO-TOTAL-AMOUNT PIC 9(8).
  • FD (File Description) でファイル名を指定します。
  • 01レベルでレコード全体の名前 (SALES-IN-REC, SALES-OUT-REC) を定義します。
  • 05レベルで各項目を定義し、PIC句でデータ型と桁数を指定します。

WORKING-STORAGE SECTION

ファイルのレコード以外で、プログラム内で使用する変数を定義します。

WORKING-STORAGE SECTION.
* 作業用変数
01  WK-VARIABLES.
    05 WK-PROD-CODE    PIC X(5).
    05 WK-TOTAL-AMOUNT PIC 9(8) VALUE ZERO.
    05 WK-SUB-AMOUNT   PIC 9(8).

* ファイル終了フラグ
01  EOF-FLAG          PIC X(1) VALUE 'N'.
    88 EOF             VALUE 'Y'.
  • WK-PROD-CODE: 現在処理中の商品コードを保持します。
  • WK-TOTAL-AMOUNT: 商品ごとの合計金額を計算するために使用します。VALUE ZERO で初期値を0に設定します。
  • WK-SUB-AMOUNT: 1レコード分の売上金額(数量 * 単価)を一時的に格納します。
  • EOF-FLAG: 入力ファイルの終了を判定するためのフラグです。VALUE 'N' で初期値を ‘N’ (Not End Of File) に設定します。88レベル項目 (条件名) を使うと、IF EOF のように直感的に記述できます。

4. PROCEDURE DIVISION

プログラムの具体的な処理手順を記述します。

PROCEDURE DIVISION.
MAIN-PROC.
    * 初期処理
    PERFORM OPEN-FILES.

    * 最初のレコード読み込み
    PERFORM READ-SALES-IN.

    * ファイルの終わりまで主処理を繰り返す
    PERFORM UNTIL EOF
        MOVE SI-PROD-CODE TO WK-PROD-CODE
        MOVE ZERO         TO WK-TOTAL-AMOUNT

        * 同じ商品コードの間、集計処理を繰り返す
        PERFORM UNTIL EOF OR SI-PROD-CODE NOT = WK-PROD-CODE
            COMPUTE WK-SUB-AMOUNT = SI-QUANTITY * SI-UNIT-PRICE
            ADD WK-SUB-AMOUNT TO WK-TOTAL-AMOUNT
            PERFORM READ-SALES-IN
        END-PERFORM

        * 集計結果の出力
        PERFORM WRITE-SALES-OUT
    END-PERFORM.

    * 終了処理
    PERFORM CLOSE-FILES.

    * プログラム終了
    STOP RUN.

* --- サブルーチン ---
OPEN-FILES.
    OPEN INPUT SALES-IN-FILE.
    OPEN OUTPUT SALES-OUT-FILE.

READ-SALES-IN.
    READ SALES-IN-FILE
        AT END MOVE 'Y' TO EOF-FLAG
    END-READ.

WRITE-SALES-OUT.
    MOVE WK-PROD-CODE    TO SO-PROD-CODE.
    MOVE WK-TOTAL-AMOUNT TO SO-TOTAL-AMOUNT.
    WRITE SALES-OUT-REC.

CLOSE-FILES.
    CLOSE SALES-IN-FILE.
    CLOSE SALES-OUT-FILE.
  • 処理をPERFORM文でサブルーチン化(段落化)することで、MAIN-PROCが読みやすくなります。
  • OPEN-FILES: 入力ファイルと出力ファイルをそれぞれINPUTモード、OUTPUTモードで開きます。
  • READ-SALES-IN: 入力ファイルを1レコード読み込みます。AT END句で、ファイルの終わりに達したらEOF-FLAGに ‘Y’ を設定します。
  • MAIN-PROC内のPERFORM UNTIL EOFループ: ファイルの終わりまで処理を繰り返します。
  • 内部のPERFORM UNTIL EOF OR SI-PROD-CODE NOT = WK-PROD-CODEループ: これがコントロールブレイクの核心部分です。商品コードが変わるか、ファイルが終わるまで、同じ商品コードのデータの金額(COMPUTE WK-SUB-AMOUNT = SI-QUANTITY * SI-UNIT-PRICE)をWK-TOTAL-AMOUNTに加算(ADD)し、次のレコードを読み込みます。
  • WRITE-SALES-OUT: 商品コードが変わったタイミング(または最後の商品の処理後)で、保持していた商品コード(WK-PROD-CODE)と合計金額(WK-TOTAL-AMOUNT)を出力レコードに転記(MOVE)し、ファイルに書き込み(WRITE)ます。
  • CLOSE-FILES: 処理が完了したらファイルを閉じます。
  • STOP RUN: プログラムの実行を終了します。

実行と確認

作成したCOBOLプログラムを実行してみましょう。

1. 準備

  1. 上記のCOBOLコードをテキストエディタで作成し、SALES-SUMMARY.cbl のような名前で保存します。(拡張子は .cob など環境に合わせてください)
  2. 仕様で示したフォーマットで、入力データファイル SALES-IN.DAT を作成します。(商品コード順にソートされていることを確認してください)

2. コンパイル

GnuCOBOL (旧称 OpenCOBOL) を使用している場合、ターミナル(コマンドプロンプト)で以下のコマンドを実行してコンパイルします。

cobc -x -free SALES-SUMMARY.cbl
  • -x: 実行可能ファイルを生成するオプションです。
  • -free: フリーフォーマット形式のソースコードであることを指定します。(固定フォーマットの場合は不要です)
  • コンパイルが成功すると、実行可能ファイル (Windowsなら SALES-SUMMARY.exe, Linux/macOSなら SALES-SUMMARY) が生成されます。

3. 実行

生成された実行可能ファイルを実行します。

Windowsの場合:

.\SALES-SUMMARY.exe

Linux/macOSの場合:

./SALES-SUMMARY

プログラムが正常に実行されると、カレントディレクトリに SALES-OUT.DAT ファイルが作成されます。

4. 結果確認

生成された SALES-OUT.DAT ファイルを開き、内容が期待通り(仕様で示した出力データ例と同じ)になっているか確認してください。商品コードごとに売上金額が正しく集計されていれば成功です!🎉

まとめと次のステップ

今回は、ミニプロジェクトとして売上集計プログラムを作成しました。入力ファイルの読み込み、データ加工(計算)、集計処理(コントロールブレイク)、出力ファイルの書き込みといった、COBOLの基本的な要素を組み合わせる実践的な経験ができたと思います。

このプログラムをベースに、さらに以下のような改良を加えることも考えられます。

  • 入力データのフォーマットチェックやエラーハンドリングを追加する。
  • 集計キーを複数にする(例:店舗コード+商品コード)。
  • 出力ファイルだけでなく、画面にも結果を表示する。
  • SORT文を使って、プログラム内で入力データをソートする。

これでStep 7の最初のミニプロジェクトは完了です!この調子で、次の「簡易マスタ検索プログラムの作成」にも挑戦してみましょう。💪

参考情報:

  • GnuCOBOL 公式サイト: https://www.gnu.org/software/gnucobol/
  • GnuCOBOL Programmer’s Guide: 公式サイト内や検索エンジンで見つけることができます。詳細な文法や機能について知りたい場合に参照してください。
“`

コメント

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