SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

COBOLプログラミング

COBOLプログラミング ファイル処理編その2

OpenCOBOLを使用したファイル処理の基本プログラミング

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード サンプルソース (2.0 KB)

サンプルプログラムの作成 2

コーディング解説

 前回同様、各部の構成に分解して、それぞれ機能を解説します。なお、前回解説した部分と重複する部分は割愛いたします。

ENVIRONMENT DIVISION

 今回は入出力節のみ記述し、入力ファイル2つと出力ファイル2つを定義しています。

環境部のコーディング
000500 ENVIRONMENT DIVISION.
000600 INPUT-OUTPUT SECTION.
000700 FILE-CONTROL.
000800 SELECT I-FILE1
000900     ASSIGN TO W-INPUT-FILENAME1
001000     ORGANIZATION LINE SEQUENTIAL.
001100 SELECT I-FILE2
001200     ASSIGN TO W-INPUT-FILENAME2
001300     ORGANIZATION LINE SEQUENTIAL.
001400 SELECT O-FILE1
001500     ASSIGN TO W-OUTPUT-FILENAME1
001600     ORGANIZATION LINE SEQUENTIAL.
001700 SELECT O-FILE2
001800     ASSIGN TO W-OUTPUT-FILENAME2
001900     ORGANIZATION LINE SEQUENTIAL.

 すべて順編成ファイルのため、ORGANIZATION LINE SEQUENTIALの記述があります。

DATA DIVISION

 今回もファイル節と作業場所節を記述しています。

ファイル節の記述

 順序番号002200から002400と、002500から002700までが入力ファイルのレコード定義、002800から003100と、003200から003500までが出力ファイルのレコード定義です。いずれも1024バイトのエリアを定義していますが、1024バイトの固定長という意味でなく、入出力作業領域とでも理解しておいてください。本稿では固定長レコードを取り扱っていますが、可変長レコードも取り扱うことができます。

データ部のコーディングその1(ファイル節)
002000 DATA DIVISION.
002100 FILE SECTION.
002200 FD  I-FILE1
002300     LABEL RECORDS ARE STANDARD.
002400 01  PIC X(1024).
002500 FD  I-FILE2
002600     LABEL RECORDS ARE STANDARD.
002700 01  PIC X(1024).
002800 FD  O-FILE1
002900     LABEL RECORDS ARE STANDARD.
003000 01  OUT-REC1.
003100     03 PIC X(1024).
003200 FD  O-FILE2
003300     LABEL RECORDS ARE STANDARD.
003400 01  OUT-REC2.
003500     03 PIC X(1024).
作業場所節の記述

 順序番号003600はコマンドライン引数の個数を格納する変数です。

 順序番号003800から004100は、環境部で指定された入出力ファイルのファイル名を指定する変数です。今回はコマンドライン引数から入力するようにしています。

 順序番号004200は同一商品コードでの集計に使用します。

 順序番号004300から004700はマスタデータのレコードを保存しておく領域です。ファイル節でレコード定義した領域と同じサイズで定義します。順序番号004700のように、使用しない項目はFILLERで定義します。

 以下、順序番号004800から005200は売上データのレコードを保存しておく領域、順序番号005300から005800は集計データ出力前データを保存しておく領域です。

データ部のコーディングその2(作業節)
003600 WORKING-STORAGE SECTION.
003700 77  ARG PIC 99.
003800 77  W-INPUT-FILENAME1 PIC X(256) VALUE "match.in1".
003900 77  W-INPUT-FILENAME2 PIC X(256) VALUE "match.in2".
004000 77  W-OUTPUT-FILENAME1 PIC X(256) VALUE "match.out".
004100 77  W-OUTPUT-FILENAME2 PIC X(256) VALUE "error.out".
004200 77  WK-CNT PIC 9(7) VALUE 0.
004300 01  INP-REC1.
004400     03 KEYC PIC X(5).
004500     03 NAME PIC X(20).
004600     03 PRICE PIC 99999v99.
004700     03 FILLER PIC X(994).
004800 01  INP-REC2.
004900     03 KEYC PIC X(5).
005000     03 SDATE PIC X(8).
005100     03 CNT PIC 9(5).
005200     03 FILLER PIC X(1006).
005300 01  OUT-REC.
005400     03 KEYC PIC X(5).
005500     03 NAME PIC X(20).
005600     03 PRICE PIC ZZZZ9.99.
005700     03 CNT PIC ZZZ,ZZ9.
005800     03 PROCEEDS PIC ZZ,ZZZ,ZZ9.99.

 順序番号004400、004900、005400等で、ファイル編集項目で同一の名称が定義されています。この場合、処理部で当該項目を使用する場合は、項目が特定できるように上位の項目で修飾して使用します。

PROCEDURE DIVISION

コマンドライン引数の利用

 前回はファイルの指定をハードコーディングしていましたが、今回はコマンドライン引数を利用します。

 順序番号006000で引数の個数を取得しています。今回は入力ファイル2つと出力ファイル2つを引数で取得しますので、引数が4個以外の場合はエラーとしてプログラムの実行を終了します(順序番号006100~006300)。

 取得した引数をそれぞれファイル名の領域に格納しています(順序番号006500~006800)。

手続き部のコーディング(その1)
005900 PROCEDURE DIVISION.
006000 ACCEPT ARG FROM ARGUMENT-NUMBER.
006100 IF ARG <> 4 THEN
006200    DISPLAY "PLEASE SHOW ME FILENAME"
006300    STOP RUN
006400 END-IF.
006500 ACCEPT W-INPUT-FILENAME1 FROM ARGUMENT-VALUE.
006600 ACCEPT W-INPUT-FILENAME2 FROM ARGUMENT-VALUE.
006700 ACCEPT W-OUTPUT-FILENAME1 FROM ARGUMENT-VALUE.
006800 ACCEPT W-OUTPUT-FILENAME2 FROM ARGUMENT-VALUE.
マッチング処理

 2つのファイルを読み、いずれもファイル終了になるまで繰り返し処理を行います(順序番号007200、007300)。

 まずは先読みをしています(順序番号007000~007100)。

 繰り返し処理の内部(順序番号007200~008600)では、入力したファイルのキー(商品コード)の条件により、それぞれの処理を行っています。

  • ファイル1とファイル2が同一キーの場合
    1. ファイル2の内容を集計する。
    2. 次のファイル2を読む。
    ※1:nのマッチングなので、この時点ではファイル1の次レコードは読みません。
  • ファイル1のキーが小さい場合
    1. 集計ファイルを出力
    2. 次のファイル1を読む
    ※マスタデータに対応する売上データがない場合です。売上0で集計ファイルを出力します。
  • 上記以外の場合(ファイル2のキーが小さい場合)
    1. エラーファイルを出力する。
    2. 次のファイル2を読む。
    ※売上データに対応するマスタデータがない場合です。エラーファイルを出力し、次の売上データ集計処理に移ります。

 なお、レコードの入出力部分の処理をPERFOREM文を使って、実際の処理を外書きにしています。1行の処理をわざわざPERFORM文で外書きにする必要は感じられないとの意見もあると思いますが、コーディングの見易さの1つの回答ということで、コーディング規約として採用するベンダは多いと思います。

手続き部のコーディング(その2)
006900 OPEN INPUT I-FILE1 I-FILE2 OUTPUT O-FILE1 O-FILE2.
007000 PERFORM FILE1-READ.
007100 PERFORM FILE2-READ.
007200 PERFORM UNTIL KEYC OF INP-REC1 = HIGH-VALUE
007300           AND KEYC OF INP-REC2 = HIGH-VALUE
007400    IF KEYC OF INP-REC1 = KEYC OF INP-REC2 THEN
007500        ADD CNT OF INP-REC2 TO WK-CNT
007600        PERFORM FILE2-READ
007700    ELSE
007800        IF KEYC OF INP-REC1 < KEYC OF INP-REC2 THEN
007900            PERFORM FILE1-OUT
008000            PERFORM FILE1-READ
008100        ELSE
008200            PERFORM FILE2-OUT
008300            PERFORM FILE2-READ
008400        END-IF
008500    END-IF
008600 END-PERFORM.
008700 CLOSE I-FILE1 I-FILE2 O-FILE1 O-FILE2.
008800 STOP RUN.
008900 FILE1-READ.
009000     READ I-FILE1 INTO INP-REC1
009100          AT END MOVE HIGH-VALUE TO KEYC OF INP-REC1.
009200     IF KEYC OF INP-REC1 = HIGH-VALUE THEN
009300         NEXT SENTENCE
009400     ELSE
009500         MOVE KEYC  OF INP-REC1 TO KEYC  OF OUT-REC
009600         MOVE NAME  OF INP-REC1 TO NAME  OF OUT-REC
009700         MOVE PRICE OF INP-REC1 TO PRICE OF OUT-REC
009800     END-IF.
009900 FILE2-READ.
010000     READ I-FILE2 INTO INP-REC2
010100          AT END MOVE HIGH-VALUE TO KEYC OF INP-REC2.
010200 FILE1-OUT.
010300     MULTIPLY PRICE OF INP-REC1 BY WK-CNT GIVING PROCEEDS.
010400     MOVE WK-CNT TO CNT OF OUT-REC.
010500     WRITE OUT-REC1 FROM OUT-REC.
010600     MOVE ZERO TO WK-CNT.
010700 FILE2-OUT.
010800     WRITE OUT-REC2 FROM INP-REC2.

 データ部で同一の項目が定義されているので、上位の名称で修飾して使用しています(順序番号007200等)。

 ここでは、"同一の項目名 OF 上位の名称"としていますが、"同一の項目名 IN 上位の名称"という記述でも問題ありません。今回はデータ名が重複していますが、ファイル名や段落名が重複していた場合も同様に上位名称で修飾し、特定が可能となるように記述する必要があります。

コンパイル

 今回のサンプルコードを用意しましたので適宜ご利用ください。サンプルコードを適当なディレクトリ、ファイルに格納してコンパイルをします。今回も、単一ソース、単純なプログラムですので、直接実行ファイルを出力する方法とします。

 以下は、ソースファイル名をtest-cob02.cobとした場合の例です。

コンパイル方法
/usr/local/bin/cobc -x test-cob02.cob

 コンパイル後に内容を確認してください。エラーがなければ同一のディレクトリに実行ファイル"test-cob02"が作成されているはずです。

次のページ
サンプルプログラムの作成 3

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
COBOLプログラミング連載記事一覧

もっと読む

この記事の著者

布施 榮一(ふせえいいち)

布施加工有限会社 代表取締役布施加工って何しているとこなの??実はIT屋さんだったりします(笑)Linux基盤各種サービスの設計構築およびコンサルティングをやっています。ブログもちょこちょこっと書いてます。Alinous-Core 正規販売代理店

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2655 2008/07/16 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング