第12章 コマンドでの利用方法

12.1 概要

SIT COBOLは、SIT COBOL専用エディタにおいてCOBOLプログラムを実行することができるが、COBOLプログラムを実行する方法はそれだけではなく、コマンドプロンプト上で、実行することもできる。

この章では、その方法について説明する。

[注意] > SIT COBOLを、コマンドで利用するには、有償ライセンスが必要となる。

12.2 利用方法

12.2.1 コマンドプロンプトの起動

最初に、コマンドプロンプトを起動する。起動のしかたは下記のとおりである。

(1) スタートメニューから起動する手順
  1. 「スタート」ボタンをクリックする。
  2. 「Windows システムツール」をクリックする。
  3. 「コマンドプロンプト」をクリックする。
(2) 検索バーから起動する手順
  1. デスクトップ左下または中央にある「検索バー」をクリックする。
  2. キーボードを操作して、検索バーに「cmd」と入力する。
  3. 検索結果に表示される「コマンドプロンプト」をクリックする。
(3) ショートカットキーから起動する手順
  1. キーボードの「Windows」キーと「R」キーを同時に押する。
  2. 「ファイル名を指定して実行」のウィンドウが表示されます。
  3. 「名前」の入力欄に「cmd」と入力する。
  4. 「OK」をクリックする。

12.2.2 SIT COBOLの起動

SIT COBOLを起動するには、SIT COBOLをセットアップしたフォルダ配下にある ‘sitcobol_bat.exe’を起動する。
例えば、SIT COBOLをセットアップしたフォルダが、D:\sitcobol にある場合は、次のようにして起動する。
(’\‘は、Windows上では’¥’記号なので注意のこと)

> d:\sitcobol\sitcobol_bat.exe --version
Smart Interpreter Training COBOL Ver11 1.6.0

>


ここで、‘--version’は、SIT COBOLのバージョンを調べるオプションである。上記では、1.6.0 のバージョンのSIT COBOLが起動していることがわかる。
sitcobol_bat.exeに指定できることのオプションは、下記のように、’--help’を指定する。

> d:\sitcobol\sitcobol_bat.exe --help
  Usage: sitcobol_bat.py [xxx.cob(or xxx.cbl)]... [trace] [lang=[ja|en]] [no_progress]
                         [copy=dddd] ... [call_path=eeee] ...
                         [--help] [--version]

         xxx.cob/xxx.cbl:  COBOL Source Files
         dddd:        Copy Reference Folder. Multiple specifications are allowed.
         eeee:        Folder where subprograms exist. Multiple specification are allowd.
         trace:       Display Execution Lines
         lang:        Language ja: japanese(default) or en: English
         no_progress: Do not display progress
         --help:      Display Help
         --version:   Display Version

>


12.2.3 オプションの説明

(1) 実行するプログラムの指定(.cob または .cbl)

xxx.cobまたはxxx.cblは、SIT COBOLが実行するプログラムを指定する。例えば、次のようなプログラムがあったとする。

D:\test\sample.cob:
000010 IDENTIFICATION DIVISION.
000020 PROGRAM-ID. SAMPLE01.
000030 PROCEDURE DIVISION.
000040 MAIN01.
000050     DISPLAY "HELLO WORLD".
000060     STOP RUN.

上記のプログラムは、sitcobol_bat.exeに、下記のようにプログラム名を指定すると実行される。

> d:\sitcobol\sitcobol_bat.exe d:\test\sample.cob
HELLO WORLD

>


もちろん、相対パス指定も可能である。例えばカレントフォルダを d:\sitcobolに移動して、次のように指定にしてもよい。

> cd d:\sitcobol
> .\sitcobol_bat.exe ..\test\sample.cob
HELLO WORLD

>


また、プログラムは同時に複数指定できる。このとき、プログラムは、指定された順に実行される。
例えば、次のようなプログラムを追加で作成したとする。

D:\test\sample2.cob:
000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. SAMPLE02.
000300 PROCEDURE DIVISION.
000400 MAIN02.
000500     DISPLAY "WELCOME".
000600     STOP RUN.

sample.cobとsample2.cobを下記のように指定すると、それぞれの結果が順次出力される。

> d:\sitcobol\sitcobol_bat.exe d:\test\sample.cob d:\test\sample2.cob
HELLO WORLD
WELCOME

>


SIT COBOLは、インタープリタなので、このような動作をするが、通常のCOBOLコンパイラで、このように指定すると2つのプログラムからなる1つの実行形式(EXE)を作成するという指定になるので注意されたい。

(2) traceオプション

traceを指定すると、実行した行が’>’と共に表示される。

> d:\sitcobol\sitcobol_bat.exe d:\test\sample.cob d:\test\sample2.cob trace
>000040 MAIN00.
>000050     display "HELLO WORLD".
HELLO WORLD
>000060     STOP RUN
>000400 MAIN00.
>000500     display "WELCOME".
WELCOME
>000600     STOP RUN

>


(3) langオプション

メッセージ等の出力の言語タイプを指定する。既定値は日本語(lang=ja)であるが、英語にする場合には、lang=enと指定する。
例えば、次のように存在しないプログラムを指定したときのエラーメッセージは次のようになる。

> d:\sitcobol\sitcobol_bat.exe no-exist-prog.cob
**[致命的] no-exist-prog.cobが見つからない

> d:\sitcobol\sitcobol_bat.exe no-exist-prog.cob lang=en
**[FATAL] no-exist-prog.cob is not found

>


(4) no_progressオプション

SIT COBOLは、インタープリタなので、プログラムは一度、中間言語に変換してから実行する。
プログラムがある程度大きくなると、中間言語に変換するのに時間がかかるので、中間言語変換中であることがわかるように次のようなプログレス状態が表示される。(複数行表示されているが、実際は直後の1行に順次表示される)

> \sitcobol\sitcobol_bat.exe long-program.cob
Ready o.........  10%
Ready oo........  20%
Ready ooo.......  30%
     :
Ready oooooooooo  100%

  <実行結果>


この表示を不要とするのが、no_progressオプションである。
プログラムの実行結果をリダイレクトした場合に、このプログレス状態もリダイレクション先に出力されることがあり、それを防ぐような場合に指定する。

(5) copyオプション

copyオプションは、登録集原文(コピー原文)の存在場所を指定するオプションである。
例えば、次のようなプログラムがあったとする。

d:\test\copy_test.cob
000010 IDENTIFICATION DIVISION.
000020 PROGRAM-ID. COPY_TEST.
000030 DATA DIVISION.
000040 COPY COPY001.
000050 PROCEDURE DIVISION.
000060     DISPLAY MESS1.
000070     STOP RUN.

d:\test\copy\copy001.cob
000010 01 MESS1 PIC X(20) VALUE "HELLO WORLD".

copy_text.cobが、COPY原文copy001.cobを参照できるようにするには、次のようにcopyオプションでフォルダを指定する。

> d:\sitcobol\sitcobol_bat.exe d:\test\copy_test.cob copy=d:\test\copy
HELLO WORRLD

>


copyオプションは複数個指定することができる。
また、SIT COBOLが、コピー原文検索する順序は次のとおりである。

  1. 最初のcopyオプションで指定されたフォルダを検索する。
  2. 2つめのcopyオプションで指定されたフォルダを検索する。
  3. 指定されているcopyオプション分繰り返す。
  4. 最後に、カレントフォルダ(*1)を参照する。

(*1) カレントフォルダは、sitcobol_bat.exeに直接指定されたプログラムが存在するフォルダである。
上記の例では、‘d:\test’ がカレントディレクトリとなる。

(6) call_pathオプション

call_pathオプションは、CALL文によって呼ばれるプログラムの検索場所を指定するオプションである。
例えば、次のようなプログラムがあったとする。

d:\test\call_test.cob
000010 IDENTIFICATION DIVISION.
000020 PROGRAM-ID. CALL_TEST.
000050 PROCEDURE DIVISION.
000060     CALL "subprog1".
000070     STOP RUN.

d:\others\subprog1.cob
000010 IDENTIFICATION DIVISION.
000020 PROGRAM-ID. SUBPROG1.
000050 PROCEDURE DIVISION.
000060     DISPLAY "HELLO WORLD".
000070     EXIT PROGRAM.

call_test.cobから、subprog1.cobを呼ぶことができるようにするには、次のようにcall_pathオプションを指定する。

> d:\sitcobol\sitcobol_bat.exe d:\test\call_test.cob call_path=d:\others
HELLO WORRLD

>


call_pathオプションは複数指定することができる。
また、SIT COBOLが、CALLに指定されたプログラムを検索する順序は次のとおりである。

  1. 最初に、カレントフォルダ(*1)を参照する。
  2. 最初のcall_pathオプションで指定されたフォルダを検索する。
  3. 2つめのcall_pathオプションで指定されたフォルダを検索する。
  4. 指定されているcall_pathオプション分繰り返す。

(*1) カレントフォルダは、sitcobol_bat.exeに直接指定されたプログラムが存在するフォルダである。

上記の例では、call_test.cobが存在するフォルダである’d:\test’ がカレントディレクトリとなる。また、CALL文が成功した際には、カレントディレクトリは、呼び出したプログラムが存在するフォルダとなる。すなわち、上記の例では、subprog1.cobが呼ばれたときは、’d:\others’がカレントディレクトリとなる。
さらに、制御がそのsubprog1.cobからcall_test.cobに戻ってきたときは、カレントディレクトリは、subprog1.cobを呼ぶ前の状態に戻る。

なお、SIT COBOLの場合、CALLに指定するのは、PROGRAM-ID段落で指定されたプログラム名ではなく、COBOLプログラムのファイル名自身である。
すなわち、CALL “ABC” と指定されていたときは、ファイル’ABC.cob’ , ‘ABC.cbl’ を検索するので注意されたい。

12.3 バッチ処理例

ここでは、バッチ処理の例として在庫管理システムの一部処理を見ていく。
商品(電化商品)の仕入れや販売といったトランザクションにより「在庫マスタ」にある在庫数を増減させていく例である。

12.3.1 各種マスタの作成

まずは、本例で使用する商品マスタ、在庫マスタ、倉庫マスタ、顧客マスタ(いずれも索引ファイル)を作成する。入力はCSVファイルである。

商品マスタ

商品マスタとは、1つ1つの商品(商品コード)について、商品名称、その他商品に関する属性をもつファイルである。

(1) レコードフォーマット

商品マスタのレコードは次のような構成になっているものとする。
レコードは便宜上、コピー原文「商品レコード.cob」として参照されるものとする。
主キーは、最初の「M商品コード」である。

000000 01 商品マスタレコード.
000010    COPY 商品レコード.

(商品レコード.cob)

000000     05  M商品コード          PIC X(10).   *> 商品コード(ユニーク)
000010     05  M商品名              PIC X(30).   *> 商品名
000020     05  M商品カテゴリ        PIC X(20).   *> 商品カテゴリ(テレビ、冷蔵庫など)
000030     05  M仕入先コード        PIC X(10).   *> 仕入先コード
000040     05  M仕入単価            PIC 9(7).    *> 仕入れ単価(整数)
000050     05  M販売単価            PIC 9(7).    *> 販売単価(整数)
000060     05  M在庫単位            PIC X(10).   *> 在庫単位(個、台など)
000070     05  M保証期間            PIC 9(2).    *> 保証期間(月単位)
000080     05  M登録日              PIC 9(8).    *> 登録日 (YYYYMMDD)
000090     05  M最終更新日          PIC 9(8).    *> 最終更新日 (YYYYMMDD)
(2) 初期データ(CSV形式)

商品マスタを作成するためのCSVデータは次のようなデータとする。
商品マスタレコードを構成するデータ項目の内容が、カンマ(‘,’)によって区切られている形式である。

(商品マスタ初期データ.csv)

TV000001,4K OLED テレビ 55インチ,テレビ,SUPP001,25000,55000,台,24,20240301,20240310
TV000002,4K LED テレビ 50インチ,テレビ,SUPP002,18000,45000,台,24,20240302,20240311
TV000003,8K 有機ELテレビ 65インチ,テレビ,SUPP003,35000,75000,台,36,20240303,20240312
FR000004,ノンフロン冷蔵庫 400L,冷蔵庫,SUPP004,30000,65000,台,36,20240304,20240313
FR000005,大型冷蔵庫 600L,冷蔵庫,SUPP005,45000,90000,台,36,20240305,20240314
WM000006,ドラム式洗濯機 10kg,洗濯機,SUPP006,40000,80000,台,24,20240306,20240315
WM000007,縦型洗濯機 8kg,洗濯機,SUPP007,20000,45000,台,24,20240307,20240316
AC000008,エアコン 6畳用,エアコン,SUPP008,28000,60000,台,60,20240308,20240317
AC000009,エアコン 10畳用,エアコン,SUPP009,35000,75000,台,60,20240309,20240318
MV000010,電子レンジ 20L,電子レンジ,SUPP010,10000,25000,台,12,20240310,20240319
MV000011,オーブンレンジ 30L,電子レンジ,SUPP011,15000,35000,台,12,20240311,20240320
IH000012,IHクッキングヒーター,キッチン家電,SUPP012,18000,40000,台,24,20240312,20240321
VC000013,ロボット掃除機,掃除機,SUPP013,25000,55000,台,24,20240313,20240322
VC000014,コードレス掃除機,掃除機,SUPP014,15000,32000,台,24,20240314,20240323
PC000015,ノートパソコン 15インチ,パソコン,SUPP015,50000,110000,台,12,20240315,20240324
PC000016,デスクトップパソコン,パソコン,SUPP016,70000,150000,台,12,20240316,20240325
SP000017,スマートフォン 128GB,スマートフォン,SUPP017,60000,120000,台,12,20240317,20240326
SP000018,スマートフォン 256GB,スマートフォン,SUPP018,80000,150000,台,12,20240318,20240327
TB000019,タブレット 10インチ,タブレット,SUPP019,40000,90000,台,12,20240319,20240328
TB000020,タブレット 12インチ,タブレット,SUPP020,60000,130000,台,12,20240320,20240329
(3) 商品マスタ作成プログラム

下記が商品マスタを作成するプログラムである。
CSVファイルから商品データを1件1件読み込み、UNSTRING文によりデータをカンマで区切って商品マスタの各項目に値を転記し、商品マスタ(‘商品マスタ.seqlite3’)に書き込んでいる。なお、最後の項目のあとにカンマがないと最後の項目の値が取得できないので、000360行目のSTRING文で強制的に最後にカンマを挿入している。

(商品マスタ作成.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 商品マスタ作成.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 商品マスタ ASSIGN TO "商品マスタ.sqlite3"
000060         ORGANIZATION IS INDEXED
000070         ACCESS MODE IS DYNAMIC
000080         RECORD KEY IS M商品コード
000090         FILE STATUS IS ファイルステータス.
000100*
000110     SELECT 商品マスタCSV ASSIGN TO "商品マスタ初期データ.CSV"
000120         ORGANIZATION IS LINE SEQUENTIAL.
000130 DATA DIVISION.
000140 FILE SECTION.
000150 FD 商品マスタ.
000160 01 商品マスタレコード.
000170    COPY 商品レコード.
000180 FD 商品マスタCSV.
000190 01 CSVレコード          PIC X(100).
000200 WORKING-STORAGE SECTION.
000210 01 ファイルステータス      PIC X(2).
000220 01 CSVデータ.
000230    COPY 商品レコード REPLACING //M// BY //WSー//.  *> 部分置換指定。先頭の'M'を'WS-'に変える
000240 PROCEDURE DIVISION.
000250 開始処理.
000260     OPEN INPUT 商品マスタCSV.
000270     OPEN OUTPUT 商品マスタ.
000280*
000290     PERFORM FOREVER
000300*       CSVファイルを読み込む。AT ENDなら終了
000310        READ 商品マスタCSV
000320           AT END
000330              EXIT PERFORM
000340        END-READ
000350*       CSVレコードの最後にカンマ(',')を付与する。
000360        STRING FUNCTION TRIM(CSVレコード) "," 
000370           DELIMITED BY SIZE INTO CSVレコード
000380*       CSVレコードを項目単位に分解(","で区切る)
000390        UNSTRING CSVレコード
000400           DELIMITED BY ","
000410           INTO WSー商品コード,  WSー商品名, 
000420                WSー商品カテゴリ,WSー仕入先コード, 
000430                WSー仕入単価,    WSー販売単価,
000440                WSー在庫単位,    WSー保証期間, 
000450                WSー登録日,      WSー最終更新日 
000460        DISPLAY "'" CSVデータ "'"              
000470*       商品マスタへの書き込み
000480        WRITE 商品マスタレコード FROM CSVデータ
000490        IF ファイルステータス NOT = "00"
000500           DISPLAY "マスタファイル書き込みエラー "
000510            "ファイルステータス=" ファイルステータス
000520        END-IF
000530     END-PERFORM.
000540*
000550     CLOSE 商品マスタCSV.
000560     CLOSE 商品マスタ.
000570     STOP RUN.
(4) 実行

プログラムの実行は次のようにする。
ここで、’D:¥batch_sample’は、本バッチプログラムのサンプルが格納されているフォルダである。

> d:\sitcobol\sitcobol_bat.exe d:\batch_sample\商品マスタ作成.cob

>


在庫マスタ

在庫マスタとは、1つ1つの商品(商品コード)について、その商品の在庫数、その他在庫関連の属性をもつファイルである。

(1) レコードフォーマット

在庫マスタのレコードは次のような構成になっているものとする。
レコードは便宜上、コピー原文「在庫レコード.cob」として参照されるものとする。
主キーは、最初の「M商品コード」(商品マスタと連携)である。

000160 01 在庫マスタレコード.
000170    COPY 在庫レコード.

(在庫レコード.cob)

000000     05  M商品コード          PIC X(10).   *> 商品コード(商品マスタと連携)
000010     05  M倉庫コード          PIC X(10).   *> 倉庫コード
000020     05  M現在庫数            PIC 9(7).    *> 現在の在庫数
000030     05  M引当済数            PIC 9(7).    *> 引当済数
000040     05  M最終在庫更新日      PIC 9(8).    *> 最終在庫更新日 (YYYYMMDD)
(2) 初期データ(CSV形式)

在庫マスタを作成するためのCSVデータは次のようなデータとする。
在庫マスタレコードを構成するデータ項目の内容が、カンマ(‘,’)によって区切られている形式である。

(在庫マスタ初期データ.csv)

TV000001,WH001,50,10,20250310
TV000002,WH002,30,5,20250311
TV000003,WH003,20,2,20250312
FR000004,WH001,45,15,20250313
FR000005,WH002,35,10,20250314
WM000006,WH003,40,20,20250315
WM000007,WH001,25,5,20250316
AC000008,WH002,30,10,20250317
AC000009,WH003,15,3,20250318
MV000010,WH001,50,12,20250319
MV000011,WH002,20,5,20250320
IH000012,WH003,35,10,20250321
VC000013,WH001,40,15,20250322
VC000014,WH002,25,7,20250323
PC000015,WH003,10,2,20250324
PC000016,WH001,15,3,20250325
SP000017,WH002,20,5,20250326
SP000018,WH003,10,2,20250327
TB000019,WH001,25,7,20250328
TB000020,WH002,35,10,20250329
(3) 在庫マスタ作成プログラム

下記が在庫マスタを作成するプログラムである。
CSVファイルから在庫データを1件1件読み込み、UNSTRING文によりデータをカンマで区切って在庫マスタの各項目に値を転記し、在庫マスタ(‘在庫マスタ.seqlite3’)に書き込んでいる。なお、最後の項目のあとにカンマがないと最後の項目の値が取得できないので、000360行目のSTRING文で強制的に最後にカンマを挿入している。

(在庫マスタ作成.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 在庫マスタ作成.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 在庫マスタ ASSIGN TO "在庫マスタ.sqlite3"
000060         ORGANIZATION IS INDEXED
000070         ACCESS MODE IS DYNAMIC
000080         RECORD KEY IS M商品コード
000090         FILE STATUS IS ファイルステータス.
000100*
000110     SELECT 在庫マスタCSV ASSIGN TO "在庫マスタ初期データ.CSV"
000120         ORGANIZATION IS LINE SEQUENTIAL.
000130 DATA DIVISION.
000140 FILE SECTION.
000150 FD 在庫マスタ.
000160 01 在庫マスタレコード.
000170    COPY 在庫レコード.
000180 FD 在庫マスタCSV.
000190 01 CSVレコード          PIC X(100).
000200 WORKING-STORAGE SECTION.
000210 01 ファイルステータス      PIC X(2).
000220 01 CSVデータ.
000230    COPY 在庫レコード REPLACING //M// BY //WSー//.  *> 部分置換指定。先頭の'M'を'WS-'に変える
000240 PROCEDURE DIVISION.
000250 開始処理.
000260     OPEN INPUT 在庫マスタCSV.
000270     OPEN OUTPUT 在庫マスタ.
000280*
000290     PERFORM FOREVER
000300*       CSVファイルを読み込む。AT ENDなら終了
000310        READ 在庫マスタCSV
000320           AT END
000330              EXIT PERFORM
000340        END-READ
000350*       CSVレコードの最後にカンマ(',')を付与する。
000360        STRING FUNCTION TRIM(CSVレコード) "," 
000370           DELIMITED BY SIZE INTO CSVレコード
000380*       CSVレコードを項目単位に分解(","で区切る)
000390        UNSTRING CSVレコード
000400           DELIMITED BY ","
000410           INTO WSー商品コード, WSー倉庫コード, 
000420                WSー現在庫数,   WSー引当済数, 
000430                WSー最終在庫更新日
000440        DISPLAY "'" CSVデータ "'"
000450*       在庫マスタへの書き込み
000460        WRITE 在庫マスタレコード FROM CSVデータ
000470        IF ファイルステータス NOT = "00"
000480           DISPLAY "マスタファイル書き込みエラー:"
000490           "ファイルステータス=" ファイルステータス
000500        END-IF
000510     END-PERFORM.
000520*
000530     CLOSE 在庫マスタCSV.
000540     CLOSE 在庫マスタ.
000550     STOP RUN.
(4) 実行

プログラムの実行は次のようにする。
ここで、’D:¥batch_sample’は、本バッチプログラムのサンプルが格納されているフォルダである。

> d:\sitcobol\sitcobol_bat.exe d:\batch_sample\在庫マスタ作成.cob

>


倉庫マスタ

倉庫マスタとは、在庫を保有する倉庫について、その倉庫名、所在地等の属性をもつファイルである。

(1) レコードフォーマット

倉庫マスタのレコードは次のような構成になっているものとする。
レコードは便宜上、コピー原文「倉庫レコード.cob」として参照されるものとする。
主キーは、最初の「M倉庫コード」である。

000160 01 倉庫マスタレコード.
000170    COPY 倉庫レコード.

(倉庫レコード.cob)

000000     05 M倉庫コード          PIC X(10).   *> ユニークな倉庫識別コード
000010     05 M倉庫名              PIC X(20).   *> 倉庫の名称
000020     05 M所在地              PIC X(40).   *> 倉庫の所在地
000030     05 M電話番号            PIC X(15).   *> 倉庫の連絡先電話番号
(2) 初期データ(CSV形式)

倉庫マスタを作成するためのCSVデータは次のようなデータとする。
倉庫マスタレコードを構成するデータ項目の内容が、カンマ(‘,’)によって区切られている形式である。

(倉庫マスタ初期データ.csv)

WH001,東京倉庫,東京都江東区,03-1234-5678
WH002,大阪倉庫,大阪府大阪市,06-9876-5432
WH003,福岡倉庫,福岡県福岡市,092-1111-2222
(3) 倉庫マスタ作成プログラム

下記が在庫マスタを作成するプログラムである。
CSVファイルから在庫データを1件1件読み込み、UNSTRING文によりデータをカンマで区切って倉庫マスタの各項目に値を転記し、倉庫マスタ(‘倉庫マスタ.seqlite3’)に書き込んでいる。なお、最後の項目のあとにカンマがないと最後の項目の値が取得できないので、000360行目のSTRING文で強制的に最後にカンマを挿入している。

(倉庫マスタ作成.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 倉庫マスタ作成.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 倉庫マスタ ASSIGN TO "倉庫マスタ.sqlite3"
000060         ORGANIZATION IS INDEXED
000070         ACCESS MODE IS DYNAMIC
000080         RECORD KEY IS M倉庫コード
000090         FILE STATUS IS ファイルステータス.
000100*
000110     SELECT 倉庫マスタCSV ASSIGN TO "倉庫マスタ初期データ.CSV"
000120         ORGANIZATION IS LINE SEQUENTIAL.
000130 DATA DIVISION.
000140 FILE SECTION.
000150 FD 倉庫マスタ.
000160 01 倉庫マスタレコード.
000170    COPY 倉庫レコード.
000180 FD 倉庫マスタCSV.
000190 01 CSVレコード          PIC X(100).
000200 WORKING-STORAGE SECTION.
000210 01 ファイルステータス      PIC X(2).
000220 01 CSVデータ.
000230    COPY 倉庫レコード REPLACING //M// BY //WSー//.  *> 部分置換指定。先頭の'M'を'WS-'に変える
000240 PROCEDURE DIVISION.
000250 開始処理.
000260     OPEN INPUT 倉庫マスタCSV.
000270     OPEN OUTPUT 倉庫マスタ.
000280*
000290     PERFORM FOREVER
000300*       CSVファイルを読み込む。AT ENDなら終了
000310        READ 倉庫マスタCSV
000320           AT END
000330              EXIT PERFORM
000340        END-READ
000350*       CSVレコードの最後にカンマ(',')を付与する。
000360        STRING FUNCTION TRIM(CSVレコード) "," 
000370           DELIMITED BY SIZE INTO CSVレコード
000380*       CSVレコードを項目単位に分解(","で区切る)
000390        UNSTRING CSVレコード
000400           DELIMITED BY ","
000410           INTO WSー倉庫コード,  WSー倉庫名, 
000420                WSー所在地,      WSー電話番号 
000430        DISPLAY "'" CSVデータ "'"
000440*       倉庫マスタへの書き込み
000450        WRITE 倉庫マスタレコード FROM CSVデータ
000460        IF ファイルステータス NOT = "00"
000470           DISPLAY "マスタファイル書き込みエラー "
000480           "ファイルステータス=" ファイルステータス
000490        END-IF
000500     END-PERFORM.
000510*
000520     CLOSE 倉庫マスタCSV.
000530     CLOSE 倉庫マスタ.
000540     STOP RUN.
(4) 実行

プログラムの実行は次のようにする。
ここで、’D:¥batch_sample’は、本バッチプログラムのサンプルが格納されているフォルダである。

> d:\sitcobol\sitcobol_bat.exe d:\batch_sample\倉庫マスタ作成.cob

>


顧客マスタ

顧客マスタとは、顧客について、顧客名、住所、電話番号等の属性をもつファイルである。

(1) レコードフォーマット

顧客マスタのレコードは次のような構成になっているものとする。
レコードは便宜上、コピー原文「顧客レコード.cob」として参照されるものとする。
主キーは、最初の「M顧客コード」である。

000160 01 顧客マスタレコード.
000170    COPY 顧客レコード.

(顧客レコード.cob)

000000     05 M顧客コード          PIC X(10).   *> ユニークな顧客識別コード
000010     05 M顧客名              PIC X(20).   *> 顧客の氏名
000020     05 M住所                PIC X(40).   *> 顧客の住所
000030     05 M電話番号            PIC X(15).   *> 顧客の連絡先電話番号
000040     05 Mメールアドレス      PIC X(30).   *> 顧客のメールアドレス
(2) 初期データ(CSV形式)

顧客マスタを作成するためのCSVデータは次のようなデータとする。
顧客マスタレコードを構成するデータ項目の内容が、カンマ(‘,’)によって区切られている形式である。

(顧客マスタ初期データ.csv)

CUST0001,田中 商店,東京都千代田区,03-1234-5678,tanaka@example.com
CUST0002,鈴木 販売店,神奈川県横浜市,045-9876-5432,suzuki@example.com
CUST0003,高橋 ホームセンター,大阪府大阪市,06-1111-2222,takahashi@example.com
CUST0004,佐藤 商店,愛知県名古屋市,052-3333-4444,sato@example.com
CUST0005,山田 販売店,福岡県福岡市,092-5555-6666,yamada@example.com
CUST0006,遠藤 商店,山梨県甲斐市,055-289-3333,endo@example.com
CUST0007,小島 電気店,岡山県岡山市,086-111-2222,kojima@example.com
CUST0008,高田 商会,長野県長野市,026-222-5555,takada@example.com
CUST0009,渋谷 販売店,沖縄県那覇市,098-555-6666,shibuya@example.com
CUST0010,西野 ホームセンター,秋田県秋田市,018-666-7777,nishino@example.com
(3) 顧客マスタ作成プログラム

下記が顧客マスタを作成するプログラムである。
CSVファイルから顧客データを1件1件読み込み、UNSTRING文によりデータをカンマで区切って顧客マスタの各項目に値を転記し、顧客マスタ(‘顧客マスタ.seqlite3’)に書き込んでいる。なお、最後の項目のあとにカンマがないと最後の項目の値が取得できないので、000360行目のSTRING文で強制的に最後にカンマを挿入している。

(顧客マスタ作成.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 顧客マスタ作成.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 顧客マスタ ASSIGN TO "顧客マスタ.sqlite3"
000060         ORGANIZATION IS INDEXED
000070         ACCESS MODE IS DYNAMIC
000080         RECORD KEY IS M顧客コード
000090         FILE STATUS IS ファイルステータス.
000100*
000110     SELECT 顧客マスタCSV ASSIGN TO "顧客マスタ初期データ.CSV"
000120         ORGANIZATION IS LINE SEQUENTIAL.
000130 DATA DIVISION.
000140 FILE SECTION.
000150 FD 顧客マスタ.
000160 01 顧客マスタレコード.
000170    COPY 顧客レコード.
000180 FD 顧客マスタCSV.
000190 01 CSVレコード          PIC X(100).
000200 WORKING-STORAGE SECTION.
000210 01 ファイルステータス      PIC X(2).
000220 01 CSVデータ.
000230    COPY 顧客レコード REPLACING //M// BY //WSー//.  *> 部分置換指定。先頭の'M'を'WS-'に変える
000240 PROCEDURE DIVISION.
000250 開始処理.
000260     OPEN INPUT 顧客マスタCSV.
000270     OPEN OUTPUT 顧客マスタ.
000280*
000290     PERFORM FOREVER
000300*       CSVファイルを読み込む。AT ENDなら終了
000310        READ 顧客マスタCSV
000320           AT END
000330              EXIT PERFORM
000340        END-READ
000350*       CSVレコードの最後にカンマ(',')を付与する。
000360        STRING FUNCTION TRIM(CSVレコード) "," 
000370           DELIMITED BY SIZE INTO CSVレコード
000380*       CSVレコードを項目単位に分解(","で区切る)
000390        UNSTRING CSVレコード
000400           DELIMITED BY ","
000410           INTO WSー顧客コード,  WSー顧客名, 
000420                WSー住所,        WSー電話番号, 
000430                WSーメールアドレス
000440        DISPLAY "'" CSVデータ "'"
000450*       顧客マスタへの書き込み
000460        WRITE 顧客マスタレコード FROM CSVデータ
000470        IF ファイルステータス NOT = "00"
000480           DISPLAY "マスタファイル書き込みエラー "
000490           "ファイルステータス=" ファイルステータス
000500        END-IF
000510     END-PERFORM.
000520*
000530     CLOSE 顧客マスタCSV.
000540     CLOSE 顧客マスタ.
000550     STOP RUN.
(4) 実行

プログラムの実行は次のようにする。
ここで、’D:¥batch_sample’は、本バッチプログラムのサンプルが格納されているフォルダである。

> d:\sitcobol\sitcobol_bat.exe d:\batch_sample\顧客マスタ作成.cob

>


12.3.2 トランザクション処理

さて、各マスタができたところで、次にトランザクション処理を行うプログラムを作成する。
トランザクションとは、業務処理の単位となるデータの一連の流れを指す。例えば、商品の入庫や売上による出庫といった処理が該当する。これらの処理は、在庫マスタの情報を更新し、適切な在庫管理を行うために不可欠である。

トランザクションデータは、商品コード、倉庫コード、トランザクション種別(入庫・出庫)、数量、取引日、顧客コード などの情報を持ち、これをもとに在庫の増減を管理する。
入庫トランザクションでは在庫数を増やし、出庫トランザクションでは在庫数を減らし、必要に応じて引当処理を行う。

次に、トランザクションデータを基に在庫マスタを更新するプログラムを作成する。このプログラムの主な処理は以下の通りである。

  1. トランザクションデータの読み込み
    ‘トランザクションデータ.csv’ を順次読み込み、各トランザクション(入庫・出庫)を処理する。

  2. 在庫マスタの更新

  1. 発注帳票作成
    ’発注.dat’より、発注帳票’発注帳票.txt’を作成する。

  2. 欠品帳票作成
    欠品情報データである’欠品.dat’をもとに’欠品帳票.txt’を作成する。

このプログラムを実行することで、トランザクションデータを適用し、在庫状況を正しく管理することが可能となる。さらに、在庫不足を自動検知し、発注や欠品管理を行うことで、円滑な在庫運用を実現する。

これら3つのプログラムおよび関連するファイルの関連は下記の図のとおりである。

プログラム関連図


では、次に、在庫マスタ更新プログラム、発注帳票作成プログラム、欠品帳票作成プログラムを作成していく。

12.3.3 在庫マスタ更新プログラム

在庫マスタ更新プログラムは、例えば次のようなプログラムとなる。

なお、このプログラムではトランザクション処理が適切に行われているかどうかを確認するため、000730行目のDISPLAYで、入力のトランザクションデータの内容を、また、000740行目のDISPLAYで、在庫マスタレコードの更新前のデータを、000940行目のDISPLAYで更新後のデータをログとして出力している。

(在庫マスタ更新.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 在庫マスタ更新.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 在庫マスタ ASSIGN TO "在庫マスタ.sqlite3"
000060         ORGANIZATION IS INDEXED
000070         ACCESS MODE IS DYNAMIC
000080         RECORD KEY IS M商品コード
000090         FILE STATUS IS ファイルステータス.
000100     SELECT トランザクションCSV 
000110         ASSIGN TO "トランザクションデータ.csv"
000120         ORGANIZATION IS LINE SEQUENTIAL.
000130     SELECT 発注ファイル ASSIGN TO "発注.dat"
000140         ORGANIZATION IS SEQUENTIAL.
000150     SELECT 欠品ファイル ASSIGN TO "欠品.dat"
000160         ORGANIZATION IS SEQUENTIAL.
000170 DATA DIVISION.
000180 FILE SECTION.
000190 FD 在庫マスタ.
000200 01 在庫マスタレコード.
000210     COPY 在庫レコード.
000220 FD トランザクションCSV.
000230 01 CSVレコード          PIC X(50).
000240 FD 発注ファイル.
000250 01 発注レコード.
000260     COPY 発注レコード.
000270 FD 欠品ファイル.
000280 01 欠品レコード.
000290     COPY 欠品レコード.
000300 WORKING-STORAGE SECTION.
000310 01 ファイルステータス      PIC X(2).
000320 01 CSVデータ.
000330     05 WS-商品コード    PIC X(10).
000340     05 WS-倉庫コード    PIC X(10).
000350     05 WS-トランザクション種別 PIC X(4).   *> 入庫 or 出庫
000360     05 WS-数量          PIC 9(7).
000370     05 WS-取引日        PIC 9(8).
000380     05 WS-顧客コード    PIC X(10).
000390 01 閾値                    PIC 9(7) VALUE 10.
000400 PROCEDURE DIVISION.
000410 開始処理.
000420     OPEN INPUT トランザクションCSV.
000430     OPEN I-O 在庫マスタ.
000440     OPEN OUTPUT 発注ファイル.
000450     OPEN OUTPUT 欠品ファイル.
000460     
000470     PERFORM FOREVER
000480*       CSVファイルを読み込む。AT ENDなら終了
000490        READ トランザクションCSV
000500           AT END
000510              EXIT PERFORM
000520        END-READ
000530*       CSVレコードの最後にカンマ(',')を付与する。
000540        STRING FUNCTION TRIM(CSVレコード) "," 
000550           DELIMITED BY SIZE INTO CSVレコード
000560*       CSVレコードを項目単位に分解(","で区切る)
000570        UNSTRING CSVレコード
000580           DELIMITED BY ","
000590           INTO WS-商品コード, WS-倉庫コード, 
000600                WS-トランザクション種別, WS-数量, 
000610                WS-取引日, WS-顧客コード
000620*       在庫マスタの照合
000630*       商品が見つからない場合はログを出力して次の繰り返しへ
000640        MOVE WS-商品コード TO M商品コード
000650        READ 在庫マスタ
000660           INVALID KEY 
000670              DISPLAY "不明商品: 商品コード=" WS-商品コード
000680              EXIT PERFORM CYCLE
000690        END-READ
000700*       在庫マスタの更新、および欠品データ、発注データの出力
000710        PERFORM 在庫調整処理
000720     END-PERFORM.
000730     
000740     CLOSE トランザクションCSV.
000750     CLOSE 在庫マスタ.
000760     CLOSE 発注ファイル.
000770     CLOSE 欠品ファイル.
000780     STOP RUN.
000790     
000800 在庫調整処理.
000810     DISPLAY "".
000820     DISPLAY "'" CSVデータ "'".
000830     DISPLAY "  BEFORE:" 在庫マスタレコード.
000840*    トランザクションの種別が「入庫」の場合
000850     IF WS-トランザクション種別 = "入庫"
000860        ADD WS-数量 TO M現在庫数
000870*    トランザクションの種別が「出庫」の場合
000880     ELSE
000890*       すべての数量を引き当てられる場合は、在庫量を減らす。
000900        IF M現在庫数 >= WS-数量
000910           SUBTRACT WS-数量 FROM M現在庫数
000920           ADD WS-数量 TO M引当済数
000930*       すべてを引き当てられない場合は欠品情報を出力する。
000940        ELSE
000950           MOVE WS-商品コード TO 欠品商品コード
000960           MOVE WS-倉庫コード TO 欠品倉庫コード
000970           COMPUTE 欠品数 = WS-数量 - M現在庫数
000980           MOVE WS-取引日     TO 欠品日
000990           MOVE WS-顧客コード TO 欠品顧客コード
001000           WRITE 欠品レコード
001010           MOVE 0 TO M現在庫数
001020        END-IF
001030     END-IF
001040*    最終在庫更新日を更新して、在庫マスタを更新する
001050     MOVE WS-取引日 TO M最終在庫更新日.
001060     REWRITE 在庫マスタレコード.
001070     DISPLAY "  AFTER: " 在庫マスタレコード.
001080*    在庫が閾値よりもすくないときは、発注データを出力する。
001090     IF M現在庫数 < 閾値
001100        MOVE WS-商品コード TO 発注商品コード
001110        MOVE WS-倉庫コード TO 発注倉庫コード
001120        MOVE 20 TO 発注数
001130        MOVE WS-取引日 TO 発注日
001140        WRITE 発注レコード
001150     END-IF.

ここで、’トランザクションデータ.csv’は、具体的には次のようなデータである。

VC000014,WH001,入庫,6,20250310,
FR000005,WH001,入庫,23,20250329,
TV000001,WH002,出庫,16,20250308,CUST0005
VC000014,WH003,出庫,11,20250320,CUST0003
AC000009,WH002,出庫,8,20250328,CUST0009
MV000010,WH002,入庫,7,20250318,
WM000006,WH003,入庫,11,20250312,
TB000020,WH003,入庫,14,20250321,
TV000001,WH002,入庫,17,20250308,
     :

また、発注レコード.cob、欠品レコード.cobは次のような内容とする。

(発注レコード.cob)

000000     05 発注商品コード      PIC X(10).
000010     05 発注倉庫コード      PIC X(10).
000020     05 発注数            PIC 9(7).
000030     05 発注日            PIC 9(8).

(欠品レコード.cob)

000000     05 欠品商品コード      PIC X(10).
000010     05 欠品倉庫コード      PIC X(10).
000020     05 欠品数              PIC 9(7).
000030     05 欠品日              PIC 9(8).
000040     05 欠品顧客コード      PIC X(10).

実行結果は以下のとおりである。

> d:\sitcobol\sitcobol_bat.exe d:\batch_sample\顧客マスタ更新.cob
'PC000015  WH001     出庫  000000820250314CUST0007  '
  BEFORE:PC000015  WH003     0000010000000220250324
  AFTER: PC000015  WH003     0000002000001020250314

'IH000012  WH002     出庫  000001620250317CUST0007  '
  BEFORE:IH000012  WH003     0000035000001020250321
  AFTER: IH000012  WH003     0000019000002620250317

'FR000005  WH001     出庫  000000920250307CUST0009  '
  BEFORE:FR000005  WH002     0000035000001020250314
  AFTER: FR000005  WH002     0000026000001920250307

'TV000003  WH001     入庫  000000720250303          '
  BEFORE:TV000003  WH003     0000020000000220250312
  AFTER: TV000003  WH003     0000027000000220250303
     
      : (省略) 
>


12.3.4 発注帳票作成プログラム

発注帳票作成プログラムは、発注データを入力し、発注一覧を作成するプログラムである。
今回は次のようなイメージの帳票を作成する。

------------------------------------------------------------------------------------------
項番 商品コード 商品名                               倉庫名              発注数 発注日                       
------------------------------------------------------------------------------------------
   1 PC000015   ノートパソコン 15インチ      東京倉庫          20 25/03/14                              
   2 AC000009   エアコン 10畳用          大阪倉庫          20 25/03/28                              
   3 PC000015   ノートパソコン 15インチ      福岡倉庫          20 25/03/08                              
   4 PC000016   デスクトップパソコン         福岡倉庫          20 25/03/11                              
   5 PC000016   デスクトップパソコン         大阪倉庫          20 25/03/12                              
   6 TV000002   4K LED テレビ 50インチ   大阪倉庫          20 25/03/27                              
   7 AC000009   エアコン 10畳用          東京倉庫          20 25/03/15                              
   8 PC000015   ノートパソコン 15インチ      東京倉庫          20 25/03/25                              
   9 PC000015   ノートパソコン 15インチ      大阪倉庫          20 25/03/19                              
  10 PC000016   デスクトップパソコン         福岡倉庫          20 25/03/13                              
------------------------------------------------------------------------------------------

発注帳票作成プログラムは次のようになる。

(発注帳票作成.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 発注帳票作成.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 発注ファイル ASSIGN TO "発注.dat"
000060         ORGANIZATION IS SEQUENTIAL.
000070
000080     SELECT 商品マスタ ASSIGN TO "商品マスタ.sqlite3"
000090         ORGANIZATION IS INDEXED
000100         ACCESS MODE IS DYNAMIC
000110         RECORD KEY IS M商品コード.
000120
000130     SELECT 倉庫マスタ ASSIGN TO "倉庫マスタ.sqlite3"
000140         ORGANIZATION IS INDEXED
000150         ACCESS MODE IS DYNAMIC
000160         RECORD KEY IS M倉庫コード.
000170
000180     SELECT 発注帳票 ASSIGN TO "発注帳票.txt"
000190         ORGANIZATION IS LINE SEQUENTIAL.
000200
000210 DATA DIVISION.
000220 FILE SECTION.
000230 FD 発注ファイル.
000240 01 発注レコード.
000250    COPY 発注レコード.
000260
000270 FD 商品マスタ.
000280 01 商品マスタレコード.
000290     COPY 商品レコード.
000300
000310 FD 倉庫マスタ.
000320 01 倉庫マスタレコード.
000330    COPY 倉庫レコード.
000340
000350 FD 発注帳票.
000360 01 発注帳票レコード PIC X(90).
000370
000380 WORKING-STORAGE SECTION.
000390 01 ヘッダ行           PIC X(90) VALUE
000400                          "項番 商品コード "
000410                        & "商品名                               " 
000420                        & "倉庫名              "
000430                        & "発注数 発注日".
000440 01 区切り線           PIC X(90) VALUE ALL "-".
000450 01 明細行.
000460    02 明細項番        PIC ZZZ9 VALUE 1.
000470    02                 PIC X(1) VALUE SPACE.
000480    02 明細商品コード  PIC X(10).
000490    02                 PIC X(1) VALUE SPACE.
000500    02 明細商品名      PIC N(18).
000510    02                 PIC X(1) VALUE SPACE.
000520    02 明細倉庫名      PIC N(10).
000530    02                 PIC X(1) VALUE SPACE.
000540    02 明細発注数      PIC ZZZZ9.
000550    02                 PIC X(1) VALUE SPACE.
000560    02 明細発注日      PIC 99/99/99.
000570
000580 PROCEDURE DIVISION.
000590 開始処理.
000600     OPEN INPUT 発注ファイル.
000610     OPEN INPUT 商品マスタ.
000620     OPEN INPUT 倉庫マスタ.
000630     OPEN OUTPUT 発注帳票.
000640
000650     WRITE 発注帳票レコード FROM 区切り線.
000660     WRITE 発注帳票レコード FROM ヘッダ行.
000670     WRITE 発注帳票レコード FROM 区切り線.
000680
000690     PERFORM FOREVER
000700*      発注ファイル読込。AT ENDとなったら終了。
000710       READ 発注ファイル
000720         AT END 
000730           EXIT PERFORM
000740       END-READ
000750       MOVE SPACES TO 明細商品名
000760       MOVE SPACES TO 明細倉庫名
000770*      商品マスタより商品名を検索
000780       MOVE 発注商品コード TO M商品コード
000790       READ 商品マスタ
000800         INVALID KEY 
000810           MOVE "不明" TO 明細商品名
000820           DISPLAY "不明:" 発注商品コード
000830         NOT INVALID KEY 
000840           MOVE M商品名 OF 商品マスタ TO 明細商品名 *> 英数字項目から日本語項目への転記なので
000850                                                     *> 半角文字は空白も含めて全角文字になる
000860       END-READ
000870*      倉庫マスタより倉庫名を検索。
000880       MOVE 発注倉庫コード TO M倉庫コード
000890       READ 倉庫マスタ
000900         INVALID KEY 
000910           MOVE "不明" TO 明細倉庫名
000920           DISPLAY "不明:" 発注倉庫コード
000930         NOT INVALID KEY 
000940           MOVE M倉庫名 TO 明細倉庫名               *> 英数字項目から日本語項目への転記なので
000950                                                     *> 半角文字は空白も含めて全角文字になる
000960       END-READ
000970*      明細行の作成
000980       MOVE 発注商品コード TO 明細商品コード
000990       MOVE 発注数         TO 明細発注数
001000       MOVE 発注日         TO 明細発注日
001010       WRITE 発注帳票レコード FROM 明細行
001020
001030       ADD 1 TO 明細項番
001040           
001050     END-PERFORM.
001060     WRITE 発注帳票レコード FROM 区切り線.
001070
001080     CLOSE 発注ファイル.
001090     CLOSE 商品マスタ.
001100     CLOSE 倉庫マスタ.
001110     CLOSE 発注帳票.
001120     STOP RUN.

(補足)

発注帳票をよく見ると、例えば「ノートパソコン 15インチ 東京倉庫」は、2回出力されている。
これはトランザクションデータの中に同じ商品の取引が何度もあり、その都度在庫数をチェックし、閾値以下であれば発注データとして繰り返し出力しているからである。
本来は修正が必要であるが、どのように修正するかは、ぜひ課題として取り組んでいただきたい。

実行結果は次のとおりである。

> d:\sitcobol\sitcobol_bat.exe d:\batch_sample\発注帳票作成.cob

>


12.3.5 欠品帳票作成プログラム

発注帳票作成プログラムは、欠品データを入力し、欠品一覧を作成するプログラムである。
今回は次のようなイメージの帳票を作成する。

----------------------------------------------------------------------------------------------------                    
項番 顧客コード 顧客名               商品コード 商品名                     倉庫名    欠品数 欠品日                                                 
----------------------------------------------------------------------------------------------------                    
   1 CUST0005   山田 販売店     PC000015   ノートパソコン 15インチ 福岡倉庫     13 25/03/08                                                
   2 CUST0006   遠藤 ホームセンター PC000016   デスクトップパソコン    福岡倉庫      1 25/03/11                                                
   3 CUST0001   田中 商店      PC000015   ノートパソコン 15インチ 東京倉庫     16 25/03/25                                                
   4 CUST0003   高橋 ホームセンター PC000016   デスクトップパソコン    福岡倉庫     22 25/03/13                                                
----------------------------------------------------------------------------------------------------   

欠品帳票作成プログラムは次のようになる。

(欠品帳票作成.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 欠品帳票作成.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 欠品ファイル ASSIGN TO "欠品.dat"
000060         ORGANIZATION IS SEQUENTIAL.
000070
000080     SELECT 商品マスタ ASSIGN TO "商品マスタ.sqlite3"
000090         ORGANIZATION IS INDEXED
000100         ACCESS MODE IS DYNAMIC
000110         RECORD KEY IS M商品コード.
000120
000130     SELECT 倉庫マスタ ASSIGN TO "倉庫マスタ.sqlite3"
000140         ORGANIZATION IS INDEXED
000150         ACCESS MODE IS DYNAMIC
000160         RECORD KEY IS M倉庫コード.
000170
000180     SELECT 顧客マスタ ASSIGN TO "顧客マスタ.sqlite3"
000190         ORGANIZATION IS INDEXED
000200         ACCESS MODE IS DYNAMIC
000210         RECORD KEY IS M顧客コード.
000220
000230     SELECT 欠品帳票 ASSIGN TO "欠品帳票.txt"
000240         ORGANIZATION IS LINE SEQUENTIAL.
000250
000260 DATA DIVISION.
000270 FILE SECTION.
000280 FD 欠品ファイル.
000290 01 欠品レコード.
000300    COPY 欠品レコード.
000310
000320 FD 商品マスタ.
000330 01 商品マスタレコード.
000340     COPY 商品レコード.
000350
000360 FD 倉庫マスタ.
000370 01 倉庫マスタレコード.
000380    COPY 倉庫レコード.
000390
000400 FD 顧客マスタ.
000410 01 顧客マスタレコード.
000420    COPY 顧客レコード.
000430
000440 FD 欠品帳票.
000450 01 欠品帳票レコード PIC X(120).
000460
000470 WORKING-STORAGE SECTION.
000480 01 ヘッダ行           PIC X(90) VALUE
000490                          "項番 顧客コード 顧客名               "
000500                        & "商品コード "
000510                        & "商品名                     " 
000520                        & "倉庫名    " 
000530                        & "欠品数 欠品日".
000540 01 区切り線           PIC X(100) VALUE ALL "-".
000550 01 明細行.
000560    02 明細項番        PIC ZZZ9 VALUE 1.
000570    02                 PIC X(1) VALUE SPACE.
000580    02 明細顧客コード  PIC X(10).
000590    02                 PIC X(1) VALUE SPACE.
000600    02 明細顧客名      PIC N(10).
000610    02                 PIC X(1) VALUE SPACE.
000620    02 明細商品コード  PIC X(10).
000630    02                 PIC X(1) VALUE SPACE.
000640    02 明細商品名      PIC N(13).
000650    02                 PIC X(1) VALUE SPACE.
000660    02 明細倉庫名      PIC N(5).
000670    02                 PIC X(1) VALUE SPACE.
000680    02 明細発注数      PIC ZZZZ9.
000690    02                 PIC X(1) VALUE SPACE.
000700    02 明細発注日      PIC 99/99/99.
000710
000720 PROCEDURE DIVISION.
000730 開始処理.
000740     OPEN INPUT 欠品ファイル.
000750     OPEN INPUT 商品マスタ.
000760     OPEN INPUT 倉庫マスタ.
000770     OPEN INPUT 顧客マスタ.
000780     OPEN OUTPUT 欠品帳票.
000790
000800     WRITE 欠品帳票レコード FROM 区切り線.
000810     WRITE 欠品帳票レコード FROM ヘッダ行.
000820     WRITE 欠品帳票レコード FROM 区切り線.
000830
000840     PERFORM FOREVER
000850*      発注ファイル読込。AT ENDとなったら終了。
000860       READ 欠品ファイル
000870         AT END 
000880           EXIT PERFORM
000890       END-READ
000900       MOVE SPACES TO 明細商品名
000910       MOVE SPACES TO 明細倉庫名
000920*      商品マスタより商品名を検索
000930       MOVE 欠品商品コード TO M商品コード
000940       READ 商品マスタ
000950         INVALID KEY 
000960           MOVE "不明" TO 明細商品名
000970           DISPLAY "不明:" 欠品商品コード
000980         NOT INVALID KEY 
000990           MOVE M商品名 OF 商品マスタ TO 明細商品名 *> 英数字項目から日本語項目への転記なので
001000                                                     *> 半角文字は空白も含めて全角文字になる
001010       END-READ
001020*      倉庫マスタより倉庫名を検索。
001030       MOVE 欠品倉庫コード TO M倉庫コード
001040       READ 倉庫マスタ
001050         INVALID KEY 
001060           MOVE "不明" TO 明細倉庫名
001070           DISPLAY "不明:" 欠品倉庫コード
001080         NOT INVALID KEY 
001090           MOVE M倉庫名 TO 明細倉庫名               *> 英数字項目から日本語項目への転記なので
001100                                                     *> 半角文字は空白も含めて全角文字になる
001110       END-READ
001120*      顧客マスタより顧客名を検索。
001130       MOVE 欠品顧客コード TO M顧客コード
001140       READ 顧客マスタ
001150         INVALID KEY 
001160           MOVE "不明" TO 明細顧客名
001170           DISPLAY "不明:" 欠品顧客コード
001180         NOT INVALID KEY 
001190           MOVE M顧客名 TO 明細顧客名               *> 英数字項目から日本語項目への転記なので
001200                                                     *> 半角文字は空白も含めて全角文字になる
001210       END-READ
001220*      明細行の作成
001230       MOVE 欠品商品コード TO 明細商品コード
001240       MOVE 欠品顧客コード TO 明細顧客コード
001250       MOVE 欠品数         TO 明細発注数
001260       MOVE 欠品日         TO 明細発注日
001270       WRITE 欠品帳票レコード FROM 明細行
001280
001290       ADD 1 TO 明細項番
001300           
001310     END-PERFORM.
001320     WRITE 欠品帳票レコード FROM 区切り線.
001330
001340     CLOSE 欠品ファイル.
001350     CLOSE 商品マスタ.
001360     CLOSE 倉庫マスタ.
001370     CLOSE 顧客マスタ.
001380     CLOSE 欠品帳票.
001390     STOP RUN.

(補足)

出力された欠品帳票は、明細が顧客コードの昇順ではない。これは、入力の欠品データが、トランザクション発生順に出力されているからである。
明細を、顧客コード順に出力するには修正が必要であるが、その修正は、ぜひ課題として取り組んでいただきたい。

実行結果は次のとおりである。

> d:\sitcobol\sitcobol_bat.exe d:\batch_sample\欠品帳票作成.cob

>


12.3.6 ジョブ制御

さて、以上で、「在庫マスタ更新」、「発注帳票作成」、「欠品帳票作成」の3つのプログラムの用意が出来たが、これらの3つのプログラムは、一連の流れで実行する必要がある。

そもそも、コンピュータの処理は、単一のプログラムだけで完結することは少ない。業務においては、複数の処理を決まった順序で実行する必要がある。たとえば、このトランザクション処理例のように、在庫情報を更新した後に、発注すべき商品を洗い出し、さらにその結果を元に帳票を出力する、といった一連の処理である。

このように、複数のプログラムや処理ステップをひとまとまりの「ジョブ(JOB)」として定義し、順序通りに実行させる仕組みを「ジョブ制御」と呼ぶ。そして、ジョブ制御を行うための記述言語を「ジョブ制御言語(JCL: Job Control Language)」といい、主に汎用機(メインフレーム)環境において利用されている。

一方で、Windows環境において同様の役割を果たすものとしては、バッチファイル(.bat)やPowerShellスクリプト(.ps1)が存在する。これらも、複数のプログラムを順序通りに呼び出し、必要なファイル操作を行いながら処理を進めるという点で、JCLと極めてよく似た性質を持つ。

例えば、次のようなバッチファイルが、本例の一連のプログラムを実行するバッチファイルとなる。

(バッチ処理サンプル.bat)
----

@echo off

rem コマンドプロンプトのコード系をutf-8に設定
chcp 65001

rem 環境変数の設定
set sitcobol=d:\sitcobol\sitcobol_bat.exe
set prg_path=d:\batch_sample

rem 在庫マスタ更新
%sitcobol% %prg_path%\在庫マスタ更新.cob
if errorlevel 1 goto ERROR

rem 発注帳票作成
%sitcobol% %prg_path%\発注帳票作成.cob
if errorlevel 1 goto ERROR

rem 欠品帳票作成
%sitcobol% %prg_path%\欠品帳票作成.cob
if errorlevel 1 goto ERROR

goto END

:ERROR
echo エラーが発生しました。
exit /b 1

:END
echo 正常に終了しました。

(注意)

  1. 上記のバッチファイルにおいて、各プログラムの実行後に、errorlevelによりプログラムの終了状態をチェックしているが、現段階での各プログラムにおいては、プログラム中でRETURN-CODE(errorlevelに相当)に1を設定してSTOP RUNを実行していないので、errorlevelは常に0となる。
  2. 環境変数sitcobol_pathおよびprg_pathは各々の環境に合わせて修正が必要である。
  3. chcpによって、バッチ走行環境をutf-8にしているが、これはコマンドプロンプトの既定値がシフトJIS(chcp=932)となっているためである。走行環境をUTF-8にしなかった場合、出力されるメッセージが文字化け等を引き起こす。

12.4 バッチ処理例の改善(よりバッチプログラムらしく)

このバッチプログラムを並列で実行する場合、どのような弊害が発生するかを考えてみよう。

まず第一に、在庫マスタが複数からアクセス更新されるので、排他制御が必要である。ただし、SITCOBOLでは索引ファイルはsqlite3で実現しており、sqliteは基本的に単一プロセスからのアクセスしか許容しないので、ここでは問題が発生する可能性があることの言及までに留めておく。

さらなる弊害を考えると、入力トランザクションである「トランザクション.csv」、テンポラリ的な中間ファイルである「欠品.dat」、「発注.dat」、「発注帳票.txt」、「欠品帳票.txt」のファイル名が固定なので、並列で実行した場合、あるプロセスで作成したこれらのファイルを、別プロセスで参照してしまうということが発生する。

この問題を解決するにはどうしたらよいか?
これらの実ファイル名が、実行時にシステム上で一意となるような名前にすればよい。
それでは、システム上で一意となるものは何か?いくつか考えられるが、自分自身のプロセスID(pid)や自分の親のプロセスID(ppid)を元に作られている名前であればバッチプログラム走行時点では、システム上で一意となるであろう。

ただ、PowerシェルであればプロセスIDの取得は容易いが、バッチファイルの場合、プロセスIDを取得するすべがない。
そこで、バッチシェルのプロセスIDをプログラム終了状態(すなわちerrorlevel)として返すようなプログラムを用意する。

(PPID取得.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. PPID取得.
000020 DATA DIVISION.
000030 WORKING-STORAGE SECTION.
000040 01 PPID PIC 9(5) comp-3.
000050 PROCEDURE DIVISION.
000060     CALL "CBL_GET_PPID" USING PPID.
000070     MOVE PPID TO RETURN-CODE.
000080     STOP RUN.

プログラムは単純で、組み込みサブルーチンCBL_GET_PPIDを呼んで、親プロセス(すなわちバッチファイル)のプロセスIDをプログラム終了コードとして返却するものである。

バッチファイル上での使い方は次のようになる。

  :
REM プロセスIDの取得
%sitcobol% %prg_path%PPID取得.cob
set pid=%errorlevel%

REM PIDを表示してみる
echo pid=%pid%

このpidを元に「トランザクション.csv」、「発注.dat」、「欠品.dat」、「発注帳票.dat」、「欠品帳票.dat」に対応する一意名をつけるとしたら例えば次のようになるであろう。

そしてこれらの名前を、環境変数経由でCOBOLプログラムに引き渡せばよい。
具体的なバッチファイルは次のようになる。

(バッチ処理サンプル2.bat)

@echo off

rem コマンドプロンプトのコード系をutf-8に設定
chcp 65001

rem 環境変数の設定
set sitcobol=d:\sitcobol\sitcobol_bat.exe
set prg_path=d:\batch_sample

rem PID取得

%sitcobol% %prg_path%\PPID取得.cob
set pid=%errorlevel%

rem トランザクションCSVの用意:本体は前段のジョブから取得すべきデータであるが
rem ここでは元ファイルをコピーするのみとする

copy %prg_path%\トランザクションデータ.csv  %prg_path%\%pid%_トランザクションデータ.csv

rem 環境変数の設定(COBOL側で参照)

set tran_file=%prg_path%\%pid%_トランザクションデータ.csv
set order_file=%prg_path%\%pid%_発注.dat
set order_text=%prg_path%\%pid%_発注帳票.txt
set out_of_stock_file=%prg_path%\%pid%_欠品.dat
set out_of_stock_text=%prg_path%\%pid%_欠品帳票.txt

rem 在庫マスタ更新
%sitcobol% %prg_path%\在庫マスタ更新2.cob
if errorlevel 1 goto ERROR

rem 発注帳票作成
%sitcobol% %prg_path%\発注帳票作成2.cob
if errorlevel 1 goto ERROR

rem 欠品帳票作成
%sitcobol% %prg_path%\欠品帳票作成2.cob
if errorlevel 1 goto ERROR

rem 不必要となったファイルの削除
del %prg_path%\%pid%_トランザクションデータ.csv
del %prg_path%\%pid%_発注.dat
del %prg_path%\%pid%_欠品.dat

goto END

:ERROR
echo エラーが発生しました。
exit /b 1

:END
echo 正常に終了しました。

上記バッチファイルでは最後に 「%pid%_発注帳票.txt」および「%pid%_欠品帳票.txt」を残しているが、これらの帳票はこの時点で印刷や電子化が終了していないからである。

さて、バッチファイル側はこれでよいとして、プログラム側は、それぞれのファイル名を環境変数経由で取得するようにする改造が必要である。
具体的には、各ファイルのASSIGN文をデータ指定にし、ACCEPT FROM ENVIROMENT文で取得した実ファイル名を、そのデータ名に設定するのみである。

(在庫マスタ更新2.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 在庫マスタ更新2.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 在庫マスタ ASSIGN TO "在庫マスタ.sqlite3"
000060         ORGANIZATION IS INDEXED
000070         ACCESS MODE IS DYNAMIC
000080         RECORD KEY IS M商品コード
000090         FILE STATUS IS ファイルステータス.
000100     SELECT トランザクションCSV 
000110         ASSIGN TO TRAN-FILE                         *> 実ファイル名をデータ名TRAN-FILEに変更
000120         ORGANIZATION IS LINE SEQUENTIAL.
000130     SELECT 発注ファイル ASSIGN TO ORDER-FILE        *> 実ファイル名をデータ名ORDER-FILEに変更
000140         ORGANIZATION IS SEQUENTIAL.                 
000150     SELECT 欠品ファイル ASSIGN TO OUT-OF-STOCK-FILE *> 実ファイル名をデータ名OUT-OF-STOCK-FILEに変更
000160         ORGANIZATION IS SEQUENTIAL.
  :
000300 WORKING-STORAGE SECTION.
  :
000400 01 TRAN-FILE               PIC X(100).             *> トランザクションファイルの実ファイル名用
000410 01 ORDER-FILE              PIC X(100).             *> 発注ファイルの実ファイル名用
000420 01 OUT-OF-STOCK-FILE       PIC X(100).             *> 欠品ファイルの実ファイル名用
  :
000430 PROCEDURE DIVISION.
000440 開始処理.
000450*    ファイル名の取得
000460     ACCEPT TRAN-FILE FROM ENVIRONMENT  "tran_file".         *> 環境変数tarn_fileの値をTRAN-FILEに設定する
000470     ACCEPT ORDER-FILE FROM ENVIRONMENT "order_file".        *> 環境変数order_fileの値をORDER-FILEに設定する
000480     ACCEPT OUT-OF-STOCK-FILE FROM ENVIRONMENT               *> 環境変数out_of_stock_fileの値を
000490                                        "out_of_stock_file". *> OUT-OF-STOCK-FILEに設定する
000500     DISPLAY "TRAN-FILE=         " TRAN-FILE.
000510     DISPLAY "ORDER-FILE=        " ORDER-FILE.
000520     DISPLAY "OUT-OF-STOCK-FILE= " OUT-OF-STOCK-FILE.
000530*    ファイルを開く
000540     OPEN INPUT トランザクションCSV.
000550     OPEN I-O 在庫マスタ.
000560     OPEN OUTPUT 発注ファイル.
000570     OPEN OUTPUT 欠品ファイル.
  :

発注帳票作成.cob 、欠品帳票作成.cobも同様に実ファイル名を環境変数経由で取得するように変更する。

(発注帳票作成2.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 発注帳票作成2.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 発注ファイル ASSIGN TO ORDER-FILE     *> 実ファイル名をORDER-FILEに変更
000060         ORGANIZATION IS SEQUENTIAL.
  :
000170
000180     SELECT 発注帳票 ASSIGN TO ORDER-TEXT        *> 実ファイル名をORDER-TEXTに変更
000190         ORGANIZATION IS LINE SEQUENTIAL.
  :
000380 WORKING-STORAGE SECTION.
  :
000580 01 ORDER-FILE         PIC X(100).             *> 発注ファイルの実ファイル名用
000590 01 ORDER-TEXT         PIC X(100).             *> 発注帳票テキストの実ファイル名用
  :
000600 PROCEDURE DIVISION.
000610 開始処理.
000620     ACCEPT ORDER-FILE FROM ENVIRONMENT "order_file". *> 環境変数order_fileの値を取得
000630     ACCEPT ORDER-TEXT FROM ENVIRONMENT "order_text". *> 環境変数order_textの値を取得  
000640*
000650     OPEN INPUT 発注ファイル.
000660     OPEN INPUT 商品マスタ.
000670     OPEN INPUT 倉庫マスタ.
000680     OPEN OUTPUT 発注帳票.
  :

(欠品帳票作成2.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. 欠品帳票作成2.
000020 ENVIRONMENT DIVISION.
000030 INPUT-OUTPUT SECTION.
000040 FILE-CONTROL.
000050     SELECT 欠品ファイル ASSIGN TO OUT-OF-STOCK-FILE *> 実ファイル名をOUT-OF-STOCK-FILEに変更
000060         ORGANIZATION IS SEQUENTIAL.
  :
000230     SELECT 欠品帳票 ASSIGN TO OUT-OF-STOCK-TEXT   *> 実ファイル名をOUT-OF-STOCK-TEXTに変更
000240         ORGANIZATION IS LINE SEQUENTIAL.
  :
000470 WORKING-STORAGE SECTION.
  :
000720 01 OUT-OF-STOCK-FILE  PIC X(100).   *> 欠品ファイルの実ファイル名用
000730 01 OUT-OF-STOCK-TEXT  PIC X(100).   *> 欠品帳票の実ファイル名用
  :
000740 PROCEDURE DIVISION.
000750 開始処理.
000760     ACCEPT OUT-OF-STOCK-FILE FROM ENVIRONMENT 
000770                                   "out_of_stock_file".
000780     ACCEPT OUT-OF-STOCK-TEXT FROM ENVIRONMENT 
000790                                   "out_of_stock_text".
000800*
000810     OPEN INPUT 欠品ファイル.
000820     OPEN INPUT 商品マスタ.
000830     OPEN INPUT 倉庫マスタ.
000840     OPEN INPUT 顧客マスタ.
000850     OPEN OUTPUT 欠品帳票.
  :

12.5 バッチ処理例をすべてCOBOL化してみる

前節では、ジョブ制御言語として、バッチファイルを使用したが、SITCOBOLはある程度機能を持っているので、バッチファイルを使用しないで、すべてCOBOLで記述することもできることがある。

例えば、バッチファイルに相当するプログラムは次のようになる。
最初に、000130行において’CBL_GET_PID’で自分自身のプロセスIDを取得しているが、これは、呼ぶプログラムと呼ばれるプログラムは常に同じプロセス空間で実行され、親子関係がないからである。
環境変数設定においては、STRING文で、PIDから始まるファイル名を作成して、それを、SET ENVIRONMENT文で環境変数に設定している。(000150~000390行)
また、各COBOLプログラムを呼び出したときのプログラムの終了状態は、RETURN-CODEで参照できる。RETURN-CODEが0でない場合はエラーを表示してL-ERROR段落に制御を移すようにしている。(000580~000610行など)
また、不要なファイルの削除は、組み込みサブルーチン”CBL_DELETE_FILE”によって削除を行っている。(000790行など)

なお、本章の最初に記述したが、SITCOBOLでは、CALL文に指定するのは、ファイル名である。
すなわち、’CALL “ABC”’と記述したときは、SITCOBOLは、ABC.cob または ABC.cblというプログラムを検索して、それを呼び出す。また、呼び出すプログラムを検索するフォルダはcall_pathパラメータで指定が可能である。

(バッチ処理サンプル.cob)

000000 IDENTIFICATION DIVISION.
000010 PROGRAM-ID. バッチ処理サンプル.
000020 DATA DIVISION.
000030 WORKING-STORAGE SECTION.
000040 01 PID                     PIC 9(10).
000050 01 トランザクションデータ  PIC X(100).
000060 01 発注ファイル名          PIC X(100).
000070 01 発注帳票名              PIC X(100).
000080 01 欠品ファイル名          PIC X(100).
000090 01 欠品帳票名              PIC X(100).  
000100 PROCEDURE DIVISION.
000110 MAIN00.
000120*    プロセスIDの取得
000130     CALL "CBL_GET_PID" USING PID.
000140     
000150*    環境変数の設定
000160*    set tran_file=%pid%_トランザクションデータ.csv
000170     STRING FUNCTION TRIM(PID) "_トランザクションデータ.csv"
000180       DELIMITED BY SIZE INTO トランザクションデータ.
000190     SET ENVIRONMENT "tran_file" TO トランザクションデータ.
000200
000210*    set order_file=%pid%_発注.dat
000220     STRING FUNCTION TRIM(PID) "_発注.dat" DELIMITED BY SIZE
000230                        INTO 発注ファイル名.
000240     SET ENVIRONMENT "order_file" TO 発注ファイル名.
000250
000260*    set order_text=%pid%_発注帳票.txt
000270     STRING FUNCTION TRIM(PID) "_発注帳票.txt" DELIMITED BY SIZE
000280                        INTO 発注帳票名.
000290     SET ENVIRONMENT "order_text" TO 発注帳票名.
000300
000310*    set out_of_stock_file=%pid%_欠品.dat
000320     STRING FUNCTION TRIM(PID) "_欠品.dat" DELIMITED BY SIZE
000330                        INTO 欠品ファイル名.
000340     SET ENVIRONMENT "out_of_stock_file" TO 欠品ファイル名.
000350
000360*    set out_of_stock_text=%pid%_欠品帳票.txt
000370     STRING FUNCTION TRIM(PID) "_欠品帳票.txt" DELIMITED BY SIZE
000380                        INTO 欠品帳票名.
000390     SET ENVIRONMENT "out_of_stock_text" TO 欠品帳票名.
000400     
000410     DISPLAY "トランザクションデータ: " トランザクションデータ.
000420     DISPLAY "発注ファイル名:         " 発注ファイル名.
000430     DISPLAY "欠品ファイル名:         " 欠品ファイル名.
000440     DISPLAY "発注帳票名:             " 発注帳票名.
000450     DISPLAY "欠品帳票名:             " 欠品帳票名.
000460
000470*    トランザクションデータの用意
000480     CALL "CBL_COPY_FILE" USING "トランザクションデータ.csv"
000490                                トランザクションデータ.
000500     IF RETURN-CODE NOT = 0
000510        DISPLAY "トランザクションのコピーに失敗した code=" 
000520                RETURN-CODE
000530        GO TO L-ERROR
000540     END-IF.
000550
000560*    在庫マスタ更新
000570     CALL "在庫マスタ更新2".
000580     IF RETURN-CODE NOT = 0
000590        DISPLAY "在庫マスタ更新が失敗した code=" RETURN-CODE
000600        GO TO L-ERROR
000610     END-IF.
000620
000630*    発注帳票作成
000640     CALL "発注帳票作成2".
000650     IF RETURN-CODE NOT = 0
000660        DISPLAY "発注帳票作成が失敗した code=" RETURN-CODE
000670        GO TO L-ERROR
000680     END-IF.
000690
000700*    欠品帳票作成
000710     CALL "欠品帳票作成2".
000720     IF RETURN-CODE NOT = 0
000730        DISPLAY "欠品帳票作成が失敗した code=" RETURN-CODE
000740        GO TO L-ERROR
000750     END-IF.
000760
000770 L-ERROR.
000780*    不要となったファイルの削除
000790     CALL "CBL_DELETE_FILE" USING トランザクションデータ.
000800     IF RETURN-CODE NOT = 0
000810        DISPLAY "トランザクションデータの削除に失敗した: "
000820                "ファイル名=" トランザクションデータ
000830                ", code=" RETURN-CODE
000840     END-IF.
000850*
000860     CALL "CBL_DELETE_FILE" USING 発注ファイル名.
000870     IF RETURN-CODE NOT = 0
000880        DISPLAY "発注ファイルの削除に失敗した: "
000890                "ファイル名=" 発注ファイル名
000900                ", code=" RETURN-CODE
000910     END-IF.
000920*
000930     CALL "CBL_DELETE_FILE" USING 欠品ファイル名.
000940     IF RETURN-CODE NOT = 0
000950        DISPLAY "欠品ファイルの削除に失敗した: "
000960                "ファイル名=" 欠品ファイル名
000970                ", code=" RETURN-CODE
000980     END-IF.
000990     
001000     STOP RUN.

さらに、呼び出される3つのプログラム「在庫マスタ更新2.cob」、「発注帳票作成2.cob」、「欠品帳票作成2.cob」は最後がSTOP RUNとなっているので、それらを EXIT PROGRAMに修正する必要がある。

在庫マスタ更新2.cobの場合、このプログラムを主プログラムとして呼び出すことも想定して、STOP RUNは残してある。それは主プログラムとして実行されたとき、EXIT PROGRAMは特に何もせず次のステップへ制御を移し、「在庫調整処理」段落の手続きを実行してしまうからである。

(在庫マスタ更新2.cob)

000860     CLOSE トランザクションCSV.
000870     CLOSE 在庫マスタ.
000880     CLOSE 発注ファイル.
000890     CLOSE 欠品ファイル.
000900     EXIT PROGRAM.               *> 副プログラムの場合は呼ばれたプログラムに戻る
000910     STOP RUN.                   *> 主プログラムの場合は終了
000920     
000930 在庫調整処理.
  :

発注帳票作成2.cob、欠品帳票作成2.cobについては、一番最後の行に EXIT PROGAMを入れたが、これで主プログラムとして呼ばれたら終了となるし、副プログラムとして呼ばれたら呼ばれたプログラムに戻るが、実は EXIT PROGAMは書かなくともプログラムの最後の行には、暗黙の EXIT PROGRAMがあるとみなされる。

(発注帳票作成2.cob)

001130     CLOSE 発注ファイル.
001140     CLOSE 商品マスタ.
001150     CLOSE 倉庫マスタ.
001160     CLOSE 発注帳票.
001170     EXIT PROGRAM.                                  *> 副プログラムの場合は呼ばれたプログラムに戻る

(欠品帳票作成2.cob)

001340     CLOSE 欠品ファイル.
001350     CLOSE 商品マスタ.
001360     CLOSE 倉庫マスタ.
001370     CLOSE 顧客マスタ.
001380     CLOSE 欠品帳票.
001390     EXIT PROGRAM.

このように、SITCOBOLは、ファイルやフォルダ、プロセスIDなどを制御する機能を備えており、バッチファイル等を使わなくても、ある程度有用なアプリケーションを構築することができる。