COBOLはCOmonBusinessOrientedLanguageの略であり,事務処理をプログラミングすることを指向している。 具体的には表形式(2次元データ)の帳票を編集,作成する機能を言語自体がそなえており,その枠組みに沿って作れば比較的初心者でもビジネスに耐えるプログラムを作成できる。実際,プログラマの半数はCOBOLプログラマであるとさえ言われているし,現在良く話題に上るJavaやC++(C#)などへの書き換えもほとんど進んでいない。他の言語を習う前に,COBOLの類型的なデータ操作に慣れておいて損はない。
とはいうものの,COBOLは汎用機でしか動かない言語であって, なかなかPCやWSにコンパイラを移植することができなかったので, プロジェクトの現場に出ないと学習できない言語であった。 しかし,幸運にも TinyCOBOLというフリーのUnix用コンパイラがリリースされ, 安価なPC LinuxでもCOBOLを学習できるようになったので, 感謝の上利用させていただくことにする。 本レポートはLinuxでTinyCOBOLを学習するためのガイドである。 Linux用といっても,gcc+asがあれば動作するので, Windows+Cygwinでもできる。Windowsでの動作に興味のある方は、姉妹編の Windows(Cygwin)でのOpenCOBOLインストールを 参照されたい。OpenCOBOLは基本的にTiny-COBOLを日本語化したものであるので、本ページの 内容をwindowsで実践してみることができる。
参考URLの上から5つを参考にして欲しい。 COBOL の講習、チュートリアル、サン プル(英語) が最もまとまっている。
書籍では,400冊以上のCOBOLの本が出版されている。
TinyCOBOLに付属しているサンプルコードは30セット以上あり,参考になるが,初学者にいきなりはきついので,COBOLの代表的命令をマスターした後に読むと良い。
実行する場合は,インストールディレクトリ/test.code/t00 に移動した後,makeを行って,testeを実行する。
フリーのCOBOLコンパイラとしてTinyCOBOLの他にも,open-cobol, COBOL2Cなどの選択肢もあるが,インストールの容易性と,いくつかの テストの結果,著者のVine2.0環境ではtiny-cobol0.53が最も安定してコンパイル& リンクできたので選択した。Vine Linux2.5とMiracleLinux2.0ではtiny-cobol0.58でも安定していた。
TinyCOBOLは基本的に大文字,小文字を区別しない(文字データは区別する)。大文字しか許さない処理系もあるので移植の際は注意する。 また,0.57以前においてはファイルのREADにおいて,AT ENDは有効であるが, NOT AT ENDは文法エラーになる。これは, AT ENDブロックの中で, ファイルの終わりに到達したかのフラグを立てて,PERFORMのUNTIL条件で使うことで 回避する。0.58では使えるようになっている。
インストール(管理者のみ) http://prdownloads.sf.net/tiny-cobol/ から,tinycobol-0.62.tar.gz をダウンロードし,/usr/localに保存を想定。 $./configure (注:これに失敗した場合,$./configure --with-libdb=3 を行う。) $make #make install コンパイルは以下のように,ファイル名の.cob以前の部分を指定する。 hello.cobを例にする。 $htcobol -v hello.cob して $ls とすると, hello というファイルが出現する。これが実行プログラムである。 unixの場合,実行プログラム名=実行命令なので, $hello と入力すると,結果が出る。 サンプルコードのコンパイル(test.code/t00の場合) $cd test.code/t00 Makefile(バッチファイル。JCLみたいなもの)の指示通りコンパイル。 $make 実行 $teste
言語の最初のプログラムはいつでも,"HELLO WORLD!!" 。 一行表示だけのプログラムから,5千行のプログラムまでも ほんの数歩。 何事もはじめるまでが大変で,クセになってしまえば後は何とかなるものでは? まずエディタ(viやemacs。ここではvi)でhello.cobを作成する。 $vi hello.cob a(で挿入モード)
* hello.cob : The First and Shortest COBOL Program. IDENTIFICATION DIVISION. PROGRAM-ID. HELLO. ENVIRONMENT DIVISION. DATA DIVISION. PROCEDURE DIVISION. DISPLAY 'HELLO WORLD!!'. STOP RUN.
(エディタから抜けるための操作:viでは、Esc ZZ) $ 解説) 正式には,全行の1番目から6番目のカラムは一連番号領域といって,行番号 を記入するが,TinyCOBOLではこの領域を省略できる。OpenCOBOLでは省略できないので注意。 先頭(本来なら7カラム目)に"*"があると,その行はコメントとみなされて, プログラムの実行と無関係になる。 COBOLプログラムは4つのDIVISIONを必ず含む。 IDENTIFICATION DIVISION. はProgram-idを書くところと思ってよい。 ENVIRONMENT DIVISION. はマシン環境,入出力ファイル割り当てを書く。 ファイル名と入出力装置名の割り当てが最も重要であるが,今回はファイルを 使わないので空でよい。 DATA DIVISION. は利用する変数を宣言する。 hello.cobは変数を利用しないので,DATA DIVISIONは空で良い。 PROCEDURE DIVISION. は変数を利用した処理を書く。 DISPLAY 'HELLO WORLD!!'. で,'HELLO WORLD!!' を画面に表示する。 DISPLAYは定数や変数を画面に表示する命令である。 STOP RUN. プログラムの停止命令である。 hello.cobで有効な命令と言えるのは,DISPLAY文だけである。 VBやPerlであればPrint文1行ですむところを,各DIVISIONの中身がなくとも 宣言して使わなければいけないところが,COBOLの冗長なところであるが, 構造が明確でエラーを見つけやすいという面もある。 $htcobol -x hello $hello とすると,以下の結果が出る。 HELLO WORLD!! COBOLでループ(繰り返し処理)は PERFORM を主に用いるので,例をあげる。 一番目と2番目,3番目と4番目は全く同じ結果になる。*1から10までを表示する)
IDENTIFICATION DIVISION. PROGRAM-ID. ten1. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 Num1 PIC 99 VALUE ZEROS. PROCEDURE DIVISION. begin. PERFORM 10 TIMES Compute Num1 = Num1+1 DISPLAY Num1 END-PERFORM. STOP RUN.*1から10までを表示する)
IDENTIFICATION DIVISION. PROGRAM-ID. ten2. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 Num1 PIC 99 VALUE ZEROS. PROCEDURE DIVISION. begin. PERFORM Varying Num1 From 1 By 1 Until Num1 >10 DISPLAY Num1 END-PERFORM. STOP RUN.*1から10までの和を求める)
IDENTIFICATION DIVISION. PROGRAM-ID. sum1. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 Num1 PIC 99 VALUE ZEROS. 01 Sum1 PIC 99 VALUE ZEROS. PROCEDURE DIVISION. begin. PERFORM 10 TIMES Compute Num1 = Num1+1 Compute Sum1 = Sum1 + Num1 END-PERFORM. DISPLAY Sum1 STOP RUN.*1から10までの和を求める)
IDENTIFICATION DIVISION. PROGRAM-ID. sum2. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 Num1 PIC 99 VALUE ZEROS. 01 Sum1 PIC 99 VALUE ZEROS. PROCEDURE DIVISION. begin. PERFORM Varying Num1 From 1 By 1 Until Num1 >10 Compute Sum1 = Sum1 + Num1 END-PERFORM. DISPLAY Sum1 STOP RUN.
日本語の部分がプログラムによって変わるところである。 {...}は...の1回以上の繰り返し, [...]は...の0か1回の出現(省略可)を表す。 (XXX | YYY | ..) は XXXかYYY..のどれか一つであることを表す。
COBOLプログラムは以下の4つのDIVISION(部、軍事用語で師団の意味)の組である。 見出し部 IDENTIFICATION DIVISION. PROGRAM-ID. プログラム名. 環境部 ENVIRONMENT DIVISION. [CONFIGURATION SECTION. [SOURCE-COMPUTER. 開発マシン] [OBJECT-COMPUTER. 実行マシン] [SPECIAL-NAMES. 特別名称文] ] [INPUT-OUTPUT SECTION. {FILE-CONTROL. SELECT ファイル名 ASSIGN TO デバイス名. I-O-CONTROL. 入出力制御文 } ] データ部 DATA DIVISION. [FILE SECTION. {FD ファイル名. 01 レコード定義文. フィールド定義文 } ] [WORKING-STORAGE SECTION. { 01 レコード定義文. フィールド定義文 } ] 手続き部 PROCEDURE DIVISION. [DECLARATIVES. {節名 SECTION. USE文. 段落名. [文]]}] END DECLARATIVES. ] { 節名 SECTION. {段落名. {文} } }
データ名,手続き名のルールは以下のとおりである。 30字以内。英字,数字,"-"で構成。"-"は先頭におけない。 英字を1字以上含める。ただし手続き名は数字だけであってもよい。 予約語は使用できない。
ACCEPT, ACCESS, ADD, ADVANCING, AFTER, ALL, ALPHABET, ALPHABETIC, ALPHABETIC-LOWER, ALPHABETIC-UPPER, ALPHANUMERIC, ALPHANUMERIC-EDITED , ALSO, ALTER, ALTERNATES, AND, ANY, ARE, AREA, AREAS, ASCENDING, ASSIGN, AT, AUTHOR
BEFORE, BIMARY, BLANK, BLOCK, BOTTOM, BY
CALL, CANCEL, CD, CF, CH, CHARACTER, CHARACTERS, CLASS, CLOCK-UNITS , CLOSE, COBOL, CODE, CODE-SET, COLLATING, COLUMN, COMMA, COMMON, COMMUNICATION , COMP, COMPUTATIONAL, COMPUTE, CONFIGURATION, CONTAINS, CONTENT, CONTINUE, CONTROL, CONTROLS, CONVERTING, COPY, CORR, CORRESPONDING, COUNT, CURRENCY
DATA, DATE, DATE-COMPILED, DATE-WRITTEN, DAY, DAY-OF-WEEK, DE, DEBUG-CONTENTS , DEBUG-ITEM, DEBUG-LINE, DEBUG-NAME, DEBUGGING, DECIMAL-POINT, DECLARATIVES, DELETE, DELIMITED, DELIMITER, DEPENDING, DESCENDING, DESTINATION, DETAIL, DISABLE, DISPLAY, DIVIDE, DIVISION, DOWN, DUPLICATES, DYNAMIC
EGI, ELSE, EMI, ENABLE, END, END-ADD, END-CALL, END-COMPUTE, END-DELETE, END-DEVIDE, END-EVALUATE , END-IF, END-MULTIPLY, END-OF-PAGE, END-PERFORM, END-READ, END-RECIEVE, END-RETURN, END-REWRITE, END-SERCH, END-START, END-STRING, END-SUBTRACT, END-UNSTRING, END-WRITE, ENTER, ENVIRONMENT , EOP, EQUAL, ERROR, ESI, EVALUATE, EVERY, EXCEPTION, EXIT, EXTEND, EXTERNAL
FALSE, FD, FILE, FILE-CONTROL, FILLER, FINAL, FIRST, FOOTING, FOR, FROM, FUNCTION
GENERATE, GIVING, GLOBAL, GO, GREATER, GROUP
HEADING, HIGH-VALUE, HIGH-VALUES
I-O, I-O-CONTROL, IDENTIFICATION, IF, IN, INDEX, INDEXED, INDICATE, INITIAL, INITIALIZEINTO, INITIATE, INPUT, INPUT-OUTPUT, INSPECT, INSTALLATION, INTO, INVALID, IS
(JAPANESE), JUST, JUSTIFIED
(KANJI), KEY
LABEL, LAST, LEADING, LEFT, LENGTH, LESS, LIMIT, LIMITS, LINAGE, LINAGE-COUNTER , LINE, LINE-COUNTER, LINES, LINKAGE, LOCK, LOW-VALUE, LOW-VALUES
MEMORY, MERGE, MESSAGE, MODE, MODULES, MOVE, MULTIPLE, MULTIPLY
NATIVE, NEGATIVE, NEXT, NO, NOT, NUMBER, NUMERIC, NUMERIC-EDITED
OBJECT-COMPTER, OCCURS, OF, OFF, OMITTED, ON, OPEN, OPTIONAL, OR, ORDER, ORGANIZATION, OTHER, OUTPUT, OVERFLOW, PACKED-DECIMAL , PADDING, PAGE, PAGE-COUNTER, PERFORM, PF, PH, PIC, PICTURE, PLUS, POINTER, POSITION, POSITIVE, PRINTING, PROCEDURE, PROCEDURES, PROCEED, PROGRAM, PROGRAM-ID, PURGE
QUEUE, QUOTE, QUOTES
RANDAM, RD, READ, RECIEVE, RECORD, RECORDS, REDEFINES, REEL, REFERENCE, REFERENCES, RELATIVE, RELEASE, REMAINDER, REMOVAL, RENAMES, REPLACE, REPLACING, REPORT, REPORTING, REPORTS, RERUN, RESERVE, RESET, RETURN, REVERSED, REWIND, REWRITE, RF, RH, RIGHT, ROUNDED, RUN
SAME, SD, SEARCH, SECTION, SECURITY, SEGMENT, SEGMENT-LIMIT , SELECT, SEND, SENTENCE, SEPARATE, SEQUENCE, SEQUENTIAL, SET, SIGN, SIZE, SORT, SORT-MERGE, SOURCE, SOURCE-COMPUTER , SPACE, SPACES, SPECIAL-NAMES, STANDARD, STANDARD-1, STANDARD-2, START, STATUS, STOP, STRING, SUB-QUEUE-1, SUB-QUEUE-2, SUBQUEUE-3, SUBTRACT, SUM, SUPPRESS, SYMBOLIC, SYNC, SYNCRONIZED
TABLE, TALLYING, TAPE, TERMINAL, TERMINATE, TEST, TEXT, THAN, THEN, THROUGH, THRU, TIME, TIMES, TO, TOP, TRAILING, TRUE, TYPE
UNIT, UNSTRING, UNTIL, UP, UPON, USAGE, USING
VALUE, VALUES, VARYING
WHEN, WITH, WORKING-STORAGE, WRITE
ZERO, ZEROES, ZEROS
DATA DIVISIONで行う。 X: 数字以外の文字1字 9: 数字1字 Z: 9と同じだが,Zero Supress(0なら空白の置き換わる)される。 S: "+" または "-" の演算符号。記憶場所はとらない。 V: 想定小数点。記憶場所はとらない。 ,: ","を挿入する位置。有効数字の左にあった場合は空白に置き換わる。 B,0,/: これらを書いた位置に,空白,"0","/" が入る。 .: "."の位置に小数点が挿入される。 CR,DB: Credit(貸方)とDebit(借方)。データが負の場合にこれらが挿入される。 \: 有効数字の直前にひとつ"\"を挿入。 *: 有効数字の左側を"*"に置換。 -: 数値が正の時は空白。負の時は数字の直前に"-"を挿入。 +: 数値が負の時は空白。正の時は数字の直前に"+"を挿入。 5桁の数字 COUNTを宣言する場合: 02 COUNT PIC 99999. または DATA DIVISION. 02 COUNT PIC 9(5). 10文字の文字列 NAME を宣言する場合。 02 NAME PIC XXXXXXXXXX. または, 02 NAME PIC X(10). 注)日本メーカー製品で日本語全角文字を表すNが使えることがある。 Nが使えない場合でも,X 2文字でN相当とすれば問題ない。 ただし,Unixでは通常EUCでないとコンパイルできない。
accept データ名 [from 呼び名] フォーマット from がないと標準入力(キーボード入力)とみなされる。
*キーボード入力の例 IDENTIFICATION DIVISION. program-id. accept2. ENVIRONMENT DIVISION. DATA DIVISION. *作業領域の定義 ・・・ プログラムで使用する作業用領域の定義 WORKING-STORAGE SECTION. *「入出力用作業領域を英数字タイプ3桁分でAAAという名前で定義する。」 01 AAA PIC XXX. *** [手続き部] ・・・ プログラム処理を記述する部 PROCEDURE DIVISION. * [ACCEPT]:キーボードからのデータの入力 DISPLAY "INPUT 3 ALPHANUM>" WITH NO ADVANCING. ACCEPT AAA. * [DISPLAY]:画面上に表示させる DISPLAY AAA. STOP RUN.
* コマンドライン入力の例 IDENTIFICATION DIVISION. PROGRAM-ID. accept-from-cmdline. ENVIRONMENT DIVISION. CONFIGURATION SECTION. DATA DIVISION. WORKING-STORAGE SECTION. * コマンド全体を格納するTEMP変数 01 TEMP PIC X(256). * 手続き部:データを操作して、ロジックを実行する。 PROCEDURE DIVISION. * コマンドライン全体をTEMPに格納 ACCEPT TEMP FROM COMMAND-LINE. * 表示 DISPLAY TEMP. STOP RUN.
日付,時間取得の例 * currentTime.cob * $Date: 2002/04/08 04:37:54 $ * $Author: shirokaz $ * $Revision: 1.9 $ *** <処理概要> * 現在時刻をディスプレイに表示する。 ********************************************************************* *** [見出し部] ・・・ プログラムの見出しを記述する部 IDENTIFICATION DIVISION. * プログラムIDを記述 PROGRAM-ID. currentTime. * 作成者を記述 AUTHOR. shirokaz. * ********************************************************************* *** [環境部] ・・・ 使用するコンピュータの環境を定義する部 ENVIRONMENT DIVISION. * ********************************************************************* *** [データ部] ・・・ プログラムで使用するデータの構造・属性を * 定義する部 DATA DIVISION. * 作業領域の定義 ・・・ プログラムで使用する作業用領域の定義 WORKING-STORAGE SECTION. *「現在日付取得用作業領域を定義する。」 * YYMMDD 01 CurrentDate. 02 CurrentYear PIC 9(2). 02 CurrentMonth PIC 9(2). 02 CurrentDay PIC 9(2). *「日数取得用作業領域を定義する。」 * YYDDD 01 DayOfYear. 02 FILLER PIC 9(2). 02 YearDay PIC 9(3). *「現在時刻取得用作業領域を定義する。」 * HHMMSSss s = S/100 01 CurrentTime. 02 CurrentHour PIC 9(2). 02 CurrentMinute PIC 9(2). 02 FILLER PIC 9(4). ********************************************************************* *** [手続き部] ・・・ プログラム処理を記述する部 PROCEDURE DIVISION. Begin. * [ACCEPT 〜 FROM DATE]:現在日付の取得 ACCEPT CurrentDate FROM DATE YYMMDD. * ;現在日付をCurrtntDateにYYMMDD形式で取得する * [ACCEPT 〜 FROM DAY]:現在までの日数を取得 ACCEPT DayOfYear FROM DAY YYDDD. * ;現在までの日数をDayOfYearにYYYYDDD形式で取得する * [ACCEPT 〜 FROM TIME]:現在時刻を取得 ACCEPT CurrentTime FROM TIME. * ;現在時刻をCurrtntTimeに取得する * * [DISPLAY]:画面上に表示させる DISPLAY CurrentDay "/" CurrentMonth "/20" CurrentYear. DISPLAY "Today is day " YearDay " of the year". DISPLAY "The time is " CurrentHour ":"CurrentMinute. * ;取得した現在日付・日数・現在時刻を画面に表示させる。 * [STOP RUN]:プログラムの終了 STOP RUN.
DISPLAY データ名 [UPON 呼び名] [WITH NO ADVANCING] UPONがないと標準出力(ディスプレイ)とみなされる。 WITH NO ADVANCINGがないと表示後に改行される。
MOVE { データ名 } TO { データ名 } 最初のデータ名は定数を含む。 (1)基本項目、集団項目、レコードなどの転記を行う (2)転記の方法には次の2種類がある (a)数字転記 送り出し側が基本項目で、受け取り側が数字項目の場合に行われる転記方法であり、 右づめで転記される 想定小数点の指定があるときには、受け取り側項目の小数点位置に桁合わせして転記される ・受け取り側の桁数が大きいときは、余った桁にゼロが埋められる ・受け取り側の桁数が小さいときは、けた落ちする (b)英数字転記 受け取り側が英数字基本項目、あるいは受け取り側が集団項目である場合に行われる転記方法であり、 左づめで転記される ・受け取り側の桁数が大きいときは、余った桁に空白が埋められる ・受け取り側の桁数が小さいときは、桁落ちする (3)英数字項目を数字項目へ転記してはならない (4)ある記憶領域を特殊な文字で埋める場合、表意定数を指定する (5)受け取り側が英数字編集項目または数字編集項目の場合は、転記の際に編集が行われる 受け取り側が英数字編集項目の場合の転記規則は、受け取り側が英数字項目の規則に準じ、 数字編集項目の場合は、数字項目の場合の規則に準じる (6)JUSTIFIED RIGHT(右桁よせ) 英数字同士のMOVEで,データのPIC宣言の最後にJUSTIFIED RIGHTを指定すると, 右側から転記される。 例) MOVE "ABCDE" TO AAA.
STRING {データ名 DELIMITED BY データ名} INTO データ名 [WITH POINTER データ名] [ON OVERFLOW 文] [NOT ON OVERFLOW 文] [END-STRING] UNSTRING データ名 [DELIMITED BY [ALL] データ名 [OR [ALL] データ名]] INTO {データ名 [DELIMITER IN データ名] [COUNT IN データ名]} [WITH POINTER データ名] [TALLING データ名] [ON OVERFLOW 文] [NOT ON OVERFLOW 文] [END-UNSTRING] 例) *〔データ部〕 77 AN-1 PIC X(6) VALUE "STRING". 77 AN-2 PIC X(5) VALUE "STATE". 77 AN-4 PIC X(6) VALUE "MENT#0". 77 AN-5 PIC X(4) VALUE "#123". 77 AN-7 PIC X(20) VALUE "********************". 77 ED-8 PIC 99 VALUE 3. *〔手続き部〕 STRING AN-1 SPACE AN-2 DELIMITED BY SIZE AN-4 AN-5 DELIMITED BY "#" INTO AN-7 WITH POINTER ED-8. *〔データ部〕 01 NAMES. 02 NAME PIC X(20) OCCURS 10 TIMES. *〔手続き部〕 UNSTRING TEMP DELIMITED BY ' ' INTO NAME(1) NAME(2) NAME(3) NAME(4) NAME(5) NAME(6) NAME(7) NAME(8) NAME(9) NAME(10). UNSTRINGは不定長形式のデータファイル(CSVなど)を扱うのに便利である。 注) 処理系によって日本語と英語の混在が許されないことがあるので注意。
COMPUTE {一意名 [ROUNDED]} データ名 = 算術式 [ON SIZE ERROR 無条件文] 算術演算子は, +, -, *, /, **(べき乗)の5つである。 ADD,SUBTRACT, MULTIPLY, DIVIDEなどの命令と同等である。 ROUNDEDは四捨五入の指示,ON SIZE ERRORは桁あふれ処理の指示である。 例)
IDENTIFICATION DIVISION. * プログラムIDを記述 PROGRAM-ID. ex-compute. *** [環境部] ・・・ 使用するコンピュータの環境を定義する部 ENVIRONMENT DIVISION. *** [データ部] ・・・ プログラムで使用するデータの構造・属性を * 定義する部 DATA DIVISION. * 作業領域の定義 ・・・ プログラムで使用する作業用領域の定義 WORKING-STORAGE SECTION. * 「計算・結果表示用作業領域を定義する。」 01 VA PIC 9(3) VALUE 35. 01 VB PIC 9(3) VALUE 102. 01 VC PIC 9(3) VALUE 72. 01 VD PIC 9(2) VALUE 10. 01 A1 PIC 9(5). 01 A2 PIC S9(5). 01 A3 PIC 99V999. 01 A4 PIC 99.999. 01 A5 PIC 999,999. 01 A6 PIC ZZZZZ9. 01 A7 PIC 9(20). * *** [手続き部] ・・・ プログラム処理を記述する部 PROCEDURE DIVISION. * [COMPUTE]:式で指定した計算を行う COMPUTE A1 = VA * VB. * ;A1にVA×VBの計算結果を設定 COMPUTE A2 = VA - VB. * ;A2にVA−VBの計算結果を設定 COMPUTE A3 = VB / VC. * ;A3にVB÷VCの計算結果を設定(表示は99V999形式) COMPUTE A4 = VB / VC. * ;A4にVB÷VCの計算結果を設定(表示は99.999形式) COMPUTE A5 = VB * VC. * ;A5にVB×VCの計算結果を設定(表示は999,999形式) COMPUTE A6 = VB * VC. * ;A6にVB×VCの計算結果を設定(表示はZZZZZ9形式) COMPUTE A7 = VC ** VD. * ;A7にVCのVD乗の計算結果を設定 * * [DISPLAY]:画面上に表示させる DISPLAY "VA = " VA ", VB = " VB ", VC = " VC ", VD = " VD. * ;各初期値を表示 DISPLAY "VA * VB = " A1. DISPLAY "VA - VB = " A2. DISPLAY "VB / VC = " A3. DISPLAY "VB / VC = " A4. DISPLAY "VB * VC = " A5. DISPLAY "VB * VC = " A6. DISPLAY "VB ** VC = " A7. * ;各計算結果を表示 * [STOP RUN]:プログラムの終了 STOP RUN. 実行結果) VA = 035, VB = 102, VC = 072, VD = 10 VA * VB = 03570 VA - VB = -00067 VB / VC = 01.416 VB / VC = 01.416 VB * VC = 007,344 VB * VC = 7344 VB ** VC = 03743906242624487424
EVALUATE (データ名 または TRUE) [ALSO (データ名 または TRUE)] {(WHEN (ANY または 条件 または TRUE または [NOT] (データ名 または 定数 または 算術式)) [ ALSO ( ANY または 条件 または TRUE または [NOT] (データ名 または 定数 または 算術式)] 文 } [WHEN OTHER 文] [END-EVALUATE] 要するに,こう書く。 evaluate 項目名 when "a" perform 手続きA when "b" perform 手続きB when "c" perform 手続きC when other perform 手続きD end-evaluate.
IF その1) IF 条件 THEN 文 [ ELSE 文 ] END-IF IF その2) IF 条件 THEN 文 または NEXT SENTENCE [{ELSE 文 または ELSE NEXT SENTENCE }] END-IF 条件: ( データ名 または 定数 または 算術式 ) [ IS [NOT] = または IS [NOT] < または IS [NOT] > または IS [NOT] EQUAL TO または IS [NOT] LESS THAN または IS [NOT] GREATER THAN または IS GREATER THAN OR EQUAL TO または IS >= または IS LESS THAN OR EQUAL TO または IS <= または (データ名 または 定数 または 算術式 ) 例) IF A > 1 THEN GO TO AAA ELSE GO TO BBB END-IF.
GO TO 手続き名
01 AAA. 02 B OCCURS 2 03 C OCCURS 5 PIC XXX. C(1 1) C(1 2) C(1 3) C(1 4) C(1 5) C(2 1) C(2 2) C(2 3) C(2 4) C(2 5) 10のデータを宣言したことになる。
注)THRU は THROUGH の省略であり,どちらでも良い。 データ名は一意名(変数名)または整数(変数または定数)である。 【書き方1】 文の組を1回だけ実行する PERFORM 手続き名 [THRU 手続き名] PERFORM 無条件文 END-PERFORM 【書き方2】 文の組の実行を、特定の回数だけ繰り返す PERFORM 手続き名 [THROU 手続き名] [データ名 TIMES] PERFORM データ名 TIMES 無条件文 END-PERFORM 【書き方3】 文の組の実行を、条件を満足するまで繰り返す PERFORM 手続き名 [THRU 手続き名 ] [WITH TEST (BEFORE | AFTER)] UNTIL 条件 [無条件文-1 END-PERFORM] 【書き方4】 文の組の実行を条件を満足するまで繰り返すと同時に、 繰り返し回数に応じてデータ項目または指標名の値を変化させる PERFORM 手続き名 [THRU 手続き名 ] [WITH TEST (BEFORE | AFTER)] VARYING (変数名| 指標名) FROM (変数名 | 指標名 | 定数) BY (変数名 | 定数名) UNTIL 条件 [AFTER (変数名 | 指標名 ) FROM (データ名 | 指標名) BY データ名 UNTIL 条件] [無条件文-1 END-PERFORM] 【書き方5】 文の組の実行を無条件に繰り返す PERFORM WITH NO LIMIT 無条件文 END-PERFORM 例)
PROCEDURE DIVISION. * ラベル Begin を定義 Begin. * Starting to run program を表示 DISPLAY "Starting to run program" * うちPERFORM の例 * END-PERFORMまでの処理を3回繰り返す。 PERFORM 3 TIMES DISPLAY ">>>>This is an in line Perform" END-PERFORM * ここまでを3回繰り返す * Finsished in line Perform を表示する DISPLAY "Finished in line Perform" * 内PERFORM ここまで * * 外PERFORMの例 * OutOfLineEG を NumOfTimes 回繰り返す。 PERFORM OutOfLineEG NumOfTimes TIMES * Back in Begin. About to Stopを表示 DISPLAY "Back in Begin. About to Stop". * プログラム終了 STOP RUN. * PERFORM文で呼び出されるところ OutOfLineEG を定義 OutOfLineEG. * >>>> This is an out of line Perform を表示 DISPLAY ">>>> This is an out of line Perform".
OPEN {INPUT {ファイル名−1} OUTPUT {ファイル名−2} I-O {ファイル名−3} EXTEND {ファイル名−4} CLOSE {ファイル名} ファイル名−1には、入力ファイルのファイル名を指定する ファイル名−2には、出力ファイルのファイル名を指定する ファイル名−3には、入出力ファイルのファイル名を指定する ファイル名−4には、拡張出力ファイル(順アクセスの大記憶装置のファイルのみ) のファイル名を指定する 例) file-control. select inp-fl assign "b:\rei.dat" organization line sequential. select out-fl assign "b:\rei.out" organization line sequential. open input inp-fl. open output out-fl. close inp-fl, out-fl.
READ ファイル名 [NEXT] RECORD AT END 文 [NOT AT END 文] [END-READ] WRITE レコード名 [ AFTER ADVANCING { PAGE 整数 [ LINE or LINES *} [ END-WRITE ] 例)
IDENTIFICATION DIVISION. PROGRAM-ID. ReadRelative. AUTHOR. MICHAEL COUGHLAN. * Reads a Relative file directly or in sequence ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT SupplierFile ASSIGN TO "RELSUPP.DAT" ORGANIZATION IS RELATIVE ACCESS MODE IS DYNAMIC RELATIVE KEY IS SupplierKey FILE STATUS IS Supplierstatus. DATA DIVISION. FILE SECTION. FD SupplierFile. 01 SupplierRecord. 88 EndOfFile VALUE HIGH-VALUES. 02 SupplierCode PIC 99. 02 SupplierName PIC X(20). 02 SupplierAddress PIC X(50). WORKING-STORAGE SECTION. 01 SupplierStatus PIC X(2). 88 RecordFound VALUE "00". 01 SupplierKey PIC 99. 01 PrnSupplierRecord. 02 PrnSupplierCode PIC BB99. 02 PrnSupplierName PIC BBX(20). 02 PrnSupplierAddress PIC BBX(50). 01 ReadType PIC 9. 88 DirectRead VALUE 1. 88 SequentialRead VALUE 2. PROCEDURE DIVISION. BEGIN. OPEN INPUT SupplierFile. DISPLAY "Read type : Direct read = 1, Sequential read = 2 --> " WITH NO ADVANCING. ACCEPT ReadType. IF DirectRead DISPLAY "Enter supplier code key (2 digits) --> " WITH NO ADVANCING ACCEPT SupplierKey READ SupplierFile INVALID KEY DISPLAY "SUPP STATUS :-", SupplierStatus END-READ PERFORM DisplayRecord END-IF IF SequentialRead READ SupplierFile NEXT RECORD AT END SET EndOfFile TO TRUE END-READ PERFORM UNTIL EndOfFile PERFORM DisplayRecord READ SupplierFile NEXT RECORD AT END SET EndOfFile TO TRUE END-READ END-PERFORM END-IF CLOSE SupplierFile. STOP RUN. DisplayRecord. IF RecordFound MOVE SupplierCode TO PrnSupplierCode MOVE SupplierName TO PrnSupplierName MOVE SupplierAddress TO PrnSupplierAddress DISPLAY PrnSupplierRecord END-IF.
SEARCH データ名 [VARYING データ名] [AT END 文] {WHEN 条件 (文 または NEXT SENTENCE)} [END-SEARCH] SEARCH ALL データ名 [AT END 文] WHEN (データ名 = データ名) または 条件 { AND (データ名 = データ名) または 条件) } (文 または NEXT SENTENCE) [END-SEARCH]
identification division. program-id. searchSample. environment division. data division. working-storage section. 01 SEISEKI-TBL. 05 PIC X(8) VALUE "MIHO 100". 05 PIC X(8) VALUE "AKINA030". 05 PIC X(8) VALUE "RIE 050". 05 PIC X(8) VALUE "MIKA 060". 05 PIC X(8) VALUE "KEIKO090". 01 TBL REDEFINES SEISEKI-TBL. 05 DE-TA OCCURS 5 INDEXED BY SIHYOU. 10 NAMAE PIC X(5). 10 TENSUU PIC 999. 01 SIRABERU-NAMAE PIC X(5). 01 MESAGE. 10 NAMAE2 PIC X(5). 10 M1 PIC X(12) VALUE "さんの点数は". 10 TENSUU2 PIC ZZ9. 10 M2 PIC X(6) VALUE "点です". PROCEDURE DIVISION. HAJIME. ACCEPT SIRABERU-NAMAE. SET SIHYOU TO 1. SEARCH DE-TA AT END DISPLAY "該当者なしです" WHEN SIRABERU-NAMAE = NAMAE (SIHYOU) MOVE NAMAE (SIHYOU) TO NAMAE2 MOVE TENSUU (SIHYOU) TO TENSUU2 DISPLAY MESAGE. STOP RUN.
置換) INSPECT データ名 REPLACING (ALL または LEADING または FIRST) データ名 BY データ名 CHARACTERS BY データ名 (BEFORE または AFTER) [INITIAL データ名] カウント) INSPECT データ名 TALLYING データ名 FOR (ALL または LEADING または FIRST) データ名 CHARACTERS) (BEFORE または AFTER) [INITIAL データ名] 例)
IDENTIFICATION DIVISION. PROGRAM-ID. SAMPLE. DATA DIVISION. WORKING-STORAGE SECTION. 01 男性数 PIC 9(4) VALUE ZERO. 01 女性数 PIC 9(4) VALUE ZERO. CONSTANT SECTION. 01 参加者名 PIC X(50) VALUE "Mr.Brown Mrs.Brown Mr.Jones Mrs.Margaret Mr.Smith". PROCEDURE DIVISION. DISPLAY "旅行参加者名: " 参加者名. DISPLAY " ". INSPECT 参加者名 TALLYING 男性数 FOR ALL "Mr.". DISPLAY "男性は、" 男性数 "名です。". INSPECT 参加者名 TALLYING 女性数 FOR ALL "Mrs.". DISPLAY "女性は、" 女性数 "名です。". END PROGRAM SAMPLE.
大規模なプログラムになると,メインテナンスのためにファイルを分割して作成,コンパイルし,後でリンクして実行モジュールを作る。以下は2つに分けた例である。
--- メインプログラム ---* caller.cob IDENTIFICATION DIVISION. PROGRAM-ID. caller. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 HELLO PIC X(12) VALUE "Hello World!". PROCEDURE DIVISION. CALL "callee" USING HELLO. STOP RUN.--- 副プログラム ---
* callee.cob IDENTIFICATION DIVISION. PROGRAM-ID. callee. ENVIRONMENT DIVISION. DATA DIVISION. LINKAGE SECTION. 01 HELLO PIC X(12). PROCEDURE DIVISION USING HELLO. DISPLAY HELLO. STOP RUN.
USING HELLOのHELLO が普通の言語の関数の引数ということになる。 まずそれぞれをオブジェクトプログラムにコンパイルする。 $ htcobol -c caller.cob $ htcobol -c callee.cob cコンパイラでcobolライブラリ,数学ライブラリとリンクする。 $ gcc -o caller caller.o callee.o -lhtcobol -lm 実行する。 $ caller Hello World! 注)このような手順を書いたシェルファイルを作って実行しても良い。 ただし大きなシステムになるとMakefileを作って,無駄な再コンパイルを 防いだほうが良い。
肥満度判定システム~/public_html/cgi-bin/fatness/ index.html フレームHTML fatness.html フォーム入力HTML fatness.cgi パラメータ解釈,cobol起動perlスクリプト cgi-lib.pl CGIライブラリ fatness fatness.cobをコンパイルしたモジュール アクセス権限はディレクトリごと 755 にしておけば,大抵の場合安全である。
<HTML> <HEAD><TITLE>肥満度判定</TITLE></HEAD> <FRAMESET ROWS="50%,50%"> <FRAME SRC="fatness.html" NAME="inputform" SCROLLING="auto"> <FRAME NAME="outputarea" SCROLLING="auto"> </FRAMESET> </HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="ja-jp"> <head> <meta http-equiv="content-type" content="text/html; charset=euc-jp"> <TITLE>肥満度判定</TITLE> </HEAD> <BODY> <h1>肥満度判定</h1> <FORM method="GET" action="./fatness.cgi" target="outputarea"> <h2>身長 <input type="text" name="height"></h2> <h2>体重 <input type="text" name="weight"></h2> <h2><input type="submit" value="判定"></h2> </FORM> <HR> <a href="/index.html">sakura</a> </BODY> </HTML>
#!/usr/bin/perl require 'cgi-lib.pl'; &ReadParse(*in); $height = $in{'height'}; $weight = $in{'weight'}; system "./fatness $height $weight"; exit;
IDENTIFICATION DIVISION. PROGRAM-ID. fatness. ENVIRONMENT DIVISION. CONFIGURATION SECTION. DATA DIVISION. WORKING-STORAGE SECTION. * コマンド全体を格納するTEMP変数 77 i pic 999 value 0. 77 j pic 999 value 0. 01 inum pic 999 value 0. 01 height pic 999 value 0. 01 weight pic 999 value 0. 01 fatness pic 999 value 0. 01 WORKSTR PIC X(20). 02 C OCCURS 20 PIC X. 01 TEMP PIC X(60). 01 strs. 02 str pic x(20) occurs 3. * 手続き部:データを操作して、ロジックを実行する。 PROCEDURE DIVISION. * コマンドライン全体をTEMPに格納 ACCEPT TEMP FROM COMMAND-LINE. unstring TEMP DELIMITED BY ' ' INTO STR(1) STR(2) STR(3). PERFORM atoi varying j from 2 by 1 until j = 4 * display height weight compute fatness = (height - 100)*0.9 -weight DISPLAY "Content-type: text/html". DISPLAY. display "<H2>あなたは肥満度 " fatness "です</h2>". display "<H3>-5 から 5が適正です</h3>". STOP RUN. * PIC X() データを PIC 9()データに変換 atoi. move str(j) to workstr. compute inum = 0. PERFORM test before varying i from 1 by 1 until i = 20 if c(i) is = "0" then compute inum = inum*10 + 0 end-if if c(i) is = "1" then compute inum = inum*10 + 1 end-if if c(i) is = "2" then compute inum = inum*10 + 2 end-if if c(i) is = "3" then compute inum = inum*10 + 3 end-if if c(i) is = "4" then compute inum = inum*10 + 4 end-if if c(i) is = "5" then compute inum = inum*10 + 5 end-if if c(i) is = "6" then compute inum = inum*10 + 6 end-if if c(i) is = "7" then compute inum = inum*10 + 7 end-if if c(i) is = "8" then compute inum = inum*10 + 8 end-if if c(i) is = "9" then compute inum = inum*10 + 9 end-if * display i " " c(i) " " inum end-perform. if j = 2 then compute height = inum. if j = 3 then compute weight = inum.
$cd $cd cobol $cd sample1020 $ls で構成ファイル一覧を見ることができる。