2009年05月20日 open-cobol(1.0)儂(わし)的解釈によるメモ
_ open-cobol(1.0)儂(わし)的解釈によるメモ
さて、私自身COBOLと付き合い出して20年以上になるわけだが(あっ、メインフレームのね)、正直、以下のサンプルで使ってる程度の命令、構文が理解できてればバッチ処理に関しては(たぶん)充分。ただし、実際に業務システムを構築する際には、JCL(Job Control Language)やユーティリティ類との組合せで力を発揮するものなので、LinuxやCygwin上でのopen-cobolではCOBOLの良さが見えにくいかもしれない。
ちなみにデータベース、オンライン処理(DB/DC)に関してはメーカー(処理系)依存が大きいもんなので、一般論で語るのは何かと難しい。
インストール
Berkeley DB(4.7)
- tar xvzf db-4.7.25.tar.gz
- cd db-4.7.25/build_unix
- ../dist/configure
- make
- make install
- vi /etc/ld.so.conf
/usr/local/BerkeleyDB.4.7/lib
- ldconfig
open-cobol(1.0)
- tar xvzf open-cobol-1.0.tar.gz
- cd open-cobol-1.0
- CPPFLAGS=-I/usr/local/BerkeleyDB.4.7/include LDFLAGS=-L/usr/local/BerkeleyDB.4.7/lib ./configure
- make
- make install
サンプルプログラム
*00111111111122222222223333333333444444444455555555556666666666777 *89012345678901234567890123456789012345678901234567890123456789012 * * open-cobol sample by m-ito@myh.no-ip.org in 2009.05.20 * * Compile : cobc -x sample.cob * Run : LS=ls.dat IDX=idx.dat REL=rel.dat ./sample * * ================================================== * 見出し部 * ================================================== IDENTIFICATION DIVISION. PROGRAM-ID. SAMPLE. AUTHOR. M-ITO. * ================================================== * 環境部 * ================================================== ENVIRONMENT DIVISION. * -------------------------------------------------- * 入出力節 * -------------------------------------------------- INPUT-OUTPUT SECTION. FILE-CONTROL. * * LINE SEQENTIOAL(テキストファイル形式) * SELECT LS-FILE ASSIGN "LS" ORGANIZATION LINE SEQUENTIAL STATUS LS-STS.
ASSIGN "LS"の場合、実際に割り当てられるファイルは環境変数LSから取得される(open-cobol独自仕様?)。
ORGANIZATION LINE SEQUENTIALは、いわゆるテキストファイル(エディタで作れるやつ)を順編成ファイルとして扱うことが出来るので、UNIXやWindows環境では便利。
ORGANIZATION SEQUENTIALは、本来の(メインフレーム上での)順編成ファイルを扱う場合。
* * INDEX(索引順編成形式) * SELECT IDX-FILE ASSIGN "IDX" ORGANIZATION INDEXED ACCESS DYNAMIC RECORD KEY IDX-KEY ALTERNATE RECORD KEY IS IDX-KEY2 WITH DUPLICATES STATUS IDX-STS.
索引順編成ファイルはBerkeley DBを利用して実装されている。ちょっとしたデータ管理ならデータベースが無くてもこれで充分かもしれない。(トランザクション、ロールバックが使えれば本当にデータベースは必要無いかも)
* * RELATIVE(相対編成形式) * SELECT REL-FILE ASSIGN "REL" ORGANIZATION RELATIVE ACCESS DYNAMIC RELATIVE KEY REL-KEY STATUS REL-STS.
相対編成ファイルも一時期ある顧客のシステムでよく使った。ようは、件数を指定して直接その件数目にアクセスできる形式。
* ================================================== * データ部 * ================================================== DATA DIVISION. * -------------------------------------------------- * ファイル節 * -------------------------------------------------- FILE SECTION. * * LINE SEQENTIOAL(テキストファイル形式) * FD LS-FILE. 01 LS-REC. 02 LS-SEQ PIC S9(3) SIGN IS LEADING SEPARATE CHARACTER. 02 LS-DATA PIC X(80).
SIGN IS LEADINGとSEPARATE CHARACTERもUNIX, Windows環境で、数値データをASCIIフラットファイルに格納して扱う(UNIXという考え方 定理5)のに非常に適している。S9(3)の場合は"-999" 〜 "+999"の4byteの文字列として格納される。
* * INDEX(索引順編成形式) * FD IDX-FILE. 01 IDX-REC. 02 IDX-KEY PIC S9(3) SIGN IS LEADING SEPARATE CHARACTER. 02 IDX-DATA. 03 IDX-KEY2 PIC X(10). 03 FILLER PIC X(70). * * RELATIVE(相対編成形式) * FD REL-FILE. 01 REL-REC. 02 REL-SEQ PIC S9(3) SIGN IS LEADING SEPARATE CHARACTER. 02 REL-DATA PIC X(80). * -------------------------------------------------- * 作業領域節 * -------------------------------------------------- WORKING-STORAGE SECTION.
WORKING-STORAGE SECTIONでは変数の定義を行う。常に批判の的になる事だが、基本的にCOBOLで扱う変数は全て大局(グローバル)変数なのだ。
例
- X(10) 10バイトの文字列
- 9(10) 10桁の正整数
- S9(10) 10桁の整数
- S9(10)V9(5) 15桁(小数点以下5桁)の実数
- N(10) 日本語10桁の文字列
01 LS-STS PIC X(2). 01 IDX-STS PIC X(2). 01 REL-STS PIC X(2). * 01 END-SW PIC X(3) VALUE "OFF". 01 INV-SW PIC X(3) VALUE "OFF".
VALUE句で初期値を指定する。
01 REL-KEY PIC 9(3). 01 WK-SEQ PIC S9(3). 01 I PIC 9(3). 01 J PIC 9(3). * 01 WK-UNSTRING PIC X(80). 01 WK-UNSTRING-1 PIC X(10). 01 WK-UNSTRING-2 PIC X(10). 01 WK-UNSTRING-3 PIC X(10). 01 WK-UNSTRING-4 PIC X(10). * 01 WK-INSPECT PIC X(80). 01 WK-INSPECT-CNT PIC 9(3). * 01 WK-EDIT-1 PIC ---,---,---9. 01 WK-EDIT-2 PIC ZZZ,ZZZ,ZZZ9. * 01 WK-COMPUTE PIC S9(10)V9(10). 01 WK-COMPUTE-2 PIC ---,---,---9.9(10).
数値項目を簡単に文書的に見やすく編集する機能があるのがCOBOLの良い所。
* 01 WK-DIVIDE-SHO PIC S9(10). 01 WK-DIVIDE-AMARI PIC S9(10). * 01 WK-VALUEHEX PIC X(4) VALUE X"B4C1BBFA".
16進の定数は X"16進数表現" で表す。
* 01 WK-VALUEKANJI PIC N(2) VALUE "漢字". * 01 WK-ACCEPT PIC X(80). * 01 WK-REDEFINES PIC X(7). 01 WK-REDEFINES-R REDEFINES WK-REDEFINES. 02 WK-REDEFINES-G PIC X(1). 02 WK-REDEFINES-NN PIC X(2). 02 WK-REDEFINES-TT PIC X(2). 02 WK-REDEFINES-HH PIC X(2).
REDEFINES句はCOBOLに特徴的な機能。異なる変数を同じ領域に重ね合わせるイメージ。他の言語ならポインターを使うような場面かと思うが、この使い勝手はCOBOLに独特な物で、他の言語では味わえない。
* 01 WK-OCCURS. 02 FILLER OCCURS 12. 03 WK-OCCURS-X PIC X(1). 01 WK-OCCURS2. 02 FILLER OCCURS 3. 03 FILLER OCCURS 4. 04 WK-OCCURS2-X PIC X(1).
配列はOCCURS句で指定する。多次元配列もできる。
* 01 WK-SEARCH-TABLE-R. 02 FILLER PIC X(16) VALUE "000001YAGI". 02 FILLER PIC X(16) VALUE "000002NAKAKOJI". 02 FILLER PIC X(16) VALUE "000003WATANABE". 02 FILLER PIC X(16) VALUE "000004WAKIYAMA". 02 FILLER PIC X(16) VALUE "000005MIYOSHI". 02 FILLER PIC X(16) VALUE "000006KOBAYASHI". 02 FILLER PIC X(16) VALUE "000007MATSUI". 02 FILLER PIC X(16) VALUE "000008HOSONO". 02 FILLER PIC X(16) VALUE "000009NAKAMURA". 02 FILLER PIC X(16) VALUE "000010ITO". 01 WK-SEARCH-TABLE REDEFINES WK-SEARCH-TABLE-R. 02 WK-SEARCH OCCURS 10 ASCENDING KEY WK-SEARCH-KEY INDEXED BY WK-SEARCH-IDX. 03 WK-SEARCH-KEY PIC X(6). 03 WK-SEARCH-NAME PIC X(10). 01 WK-SEARCH-FIND-SW PIC X(3).
テーブルワークエリアに対しての2分木サーチに言語レベルで対応している。
* 01 WK-FUNCTION-DATE PIC X(80). * 01 WK-INITIALIZE. 02 FILLER PIC X(7) VALUE "XXXXXXX". 02 FILLER PIC 9(7) VALUE 9999999. 02 WK-INITIALIZE-X PIC X(7) VALUE "XXXXXXX". 02 WK-INITIALIZE-9 PIC 9(7) VALUE 9999999. * ================================================== * 手続き部 * ================================================== PROCEDURE DIVISION. * -------------------------------------------------- * 主処理 * -------------------------------------------------- MAIN-EN. * * 順編成ファイルテスト PERFORM SUB-LS-FILE-TEST-EN THRU SUB-LS-FILE-TEST-EX.
サブルーチン呼び出しはPERFORM文で行う。
* * 索引順編成ファイルテスト PERFORM SUB-IDX-FILE-TEST-EN THRU SUB-IDX-FILE-TEST-EX. * * 相対編成ファイルテスト PERFORM SUB-REL-FILE-TEST-EN THRU SUB-REL-FILE-TEST-EX. * * IF文テスト PERFORM SUB-IF-TEST-EN THRU SUB-IF-TEST-EX. * * EVALUATE文テスト PERFORM SUB-EVALUATE-TEST-EN THRU SUB-EVALUATE-TEST-EX. * * PERFORM文テスト PERFORM SUB-PERFORM-TEST-EN THRU SUB-PERFORM-TEST-EX. * * UNSTRING文テスト PERFORM SUB-UNSTRING-TEST-EN THRU SUB-UNSTRING-TEST-EX. * * INSPECT文テスト PERFORM SUB-INSPECT-TEST-EN THRU SUB-INSPECT-TEST-EX. * * 編集テスト PERFORM SUB-EDIT-TEST-EN THRU SUB-EDIT-TEST-EX. * * COMPUTE文テスト PERFORM SUB-COMPUTE-TEST-EN THRU SUB-COMPUTE-TEST-EX. * * DIVIDE文テスト PERFORM SUB-DIVIDE-TEST-EN THRU SUB-DIVIDE-TEST-EX. * * VALUE(HEX)文テスト PERFORM SUB-VALUEHEX-TEST-EN THRU SUB-VALUEHEX-TEST-EX. * * VALUE(漢字)文テスト PERFORM SUB-VALUEKANJI-TEST-EN THRU SUB-VALUEKANJI-TEST-EX. * * ACCEPT文テスト PERFORM SUB-ACCEPT-TEST-EN THRU SUB-ACCEPT-TEST-EX. * * REDEFINES文テスト PERFORM SUB-REDEFINES-TEST-EN THRU SUB-REDEFINES-TEST-EX. * * OCCURS文テスト PERFORM SUB-OCCURS-TEST-EN THRU SUB-OCCURS-TEST-EX. * * SEARCH文テスト PERFORM SUB-SEARCH-TEST-EN THRU SUB-SEARCH-TEST-EX. * * FUNCTION-DATE文テスト PERFORM SUB-DATE-TEST-EN THRU SUB-DATE-TEST-EX. * * INITIALIZE文テスト PERFORM SUB-INITIALIZE-TEST-EN THRU SUB-INITIALIZE-TEST-EX. * MAIN-EX. MOVE ZERO TO RETURN-CODE. GOBACK.
プログラムの終了には上記のGOBACK以外にSTOP RUNもよく使われる。
* -------------------------------------------------- * 順編成ファイルテスト * -------------------------------------------------- SUB-LS-FILE-TEST-EN. DISPLAY "== SUB-LS-FILE-TEST-EN ==" * * LS-FILEにテストデータ出力 * MOVE -5 TO WK-SEQ.
ワークへの代入はMOVE文で行う。
OPEN OUTPUT LS-FILE.
ファイルのアクセスに先だってOPEN文によるオープン処理(そのままやがな)が必要。
* ADD 1 TO WK-SEQ.
計算命令はCOMPUTE文というのが有って、通常の計算式はそちらを使う事が多いけれど、単純に1インクリメントする場合はADD文を使う事が多い(気分的なもの)。wk-seq = wk-seq + 1とwk-seq++の違いみたいな物。
MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 1" TO LS-DATA. WRITE LS-REC.
ファイルへの書き出しはWRITE文で行う。書き出しの単位は常にレコード単位となる。
* ADD 1 TO WK-SEQ. MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 2" TO LS-DATA. WRITE LS-REC. * ADD 1 TO WK-SEQ. MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 3" TO LS-DATA. WRITE LS-REC. * ADD 1 TO WK-SEQ. MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 4" TO LS-DATA. WRITE LS-REC. * ADD 1 TO WK-SEQ. MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 5" TO LS-DATA. WRITE LS-REC. * ADD 1 TO WK-SEQ. MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 6" TO LS-DATA. WRITE LS-REC. * ADD 1 TO WK-SEQ. MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 7" TO LS-DATA. WRITE LS-REC. * ADD 1 TO WK-SEQ. MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 8" TO LS-DATA. WRITE LS-REC. * ADD 1 TO WK-SEQ. MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 9" TO LS-DATA. WRITE LS-REC. * ADD 1 TO WK-SEQ. MOVE WK-SEQ TO LS-SEQ. MOVE "LINE 10" TO LS-DATA. WRITE LS-REC. * CLOSE LS-FILE.
ファイルを使い終ったらCLOSE文でクローズ処理(これまたそのまま...)を行う。バッファーと物理ディスクとの同期が行われる(たぶん)。
* * LS-FILE 読み込み * OPEN INPUT LS-FILE. * MOVE "OFF" TO END-SW. READ LS-FILE AT END MOVE "ON" TO END-SW END-READ.
順編成ファイルの読み込みはREAD AT END文を使う。
PERFORM UNTIL (END-SW = "ON")
条件指定の繰り返しにはPERFORM UNTIL文を使う。他の言語と違って繰り返しを抜ける条件を指定する点に注意。
DISPLAY "LS-FILE : " LS-REC
メッセージの出力にはDISPLAY文を使う。メインフレームの場合はUPON ほにゃららで出力先を指定できたが、open-cobolの場合にどんな出力先指定が出来るかは未調査。
READ LS-FILE AT END MOVE "ON" TO END-SW END-READ END-PERFORM. * CLOSE LS-FILE. * DISPLAY "== SUB-LS-FILE-TEST-EX ==". SUB-LS-FILE-TEST-EX. EXIT.
サーブルーチンの最後はEXIT文で閉める。
* -------------------------------------------------- * 索引順編成ファイルテスト * -------------------------------------------------- SUB-IDX-FILE-TEST-EN. DISPLAY "== SUB-IDX-FILE-TEST-EN ==" * * IDX-FILEにテストデータ出力 * OPEN INPUT LS-FILE. OPEN OUTPUT IDX-FILE. * MOVE "OFF" TO END-SW. READ LS-FILE AT END MOVE "ON" TO END-SW END-READ. PERFORM UNTIL (END-SW = "ON") MOVE LS-REC TO IDX-REC WRITE IDX-REC READ LS-FILE AT END MOVE "ON" TO END-SW END-READ END-PERFORM. * CLOSE LS-FILE. CLOSE IDX-FILE. * * IDX-FILE直読み * OPEN INPUT IDX-FILE. * MOVE 1 TO IDX-KEY. MOVE "OFF" TO INV-SW READ IDX-FILE INVALID MOVE "ON" TO INV-SW END-READ.
索引順編成ファイルを読む場合はREAD INVALID文を使う。
DISPLAY "IDX-FILE DIRECT(IDX-KEY = " IDX-KEY ") : " IDX-REC. * CLOSE IDX-FILE. * * IDX-FILE位置指定&連続読み * OPEN INPUT IDX-FILE. * MOVE "OFF" TO END-SW MOVE "OFF" TO INV-SW MOVE 3 TO IDX-KEY. START IDX-FILE KEY >= IDX-KEY INVALID MOVE "ON" TO INV-SW END-START. READ IDX-FILE NEXT AT END MOVE "ON" TO END-SW END-READ. PERFORM UNTIL (END-SW = "ON") DISPLAY "IDX-FILE(IDX-KEY >= " IDX-KEY ") : " IDX-REC READ IDX-FILE NEXT AT END MOVE "ON" TO END-SW END-READ END-PERFORM.
索引順編成ファイルの特定のレコードに位置付けるにはSTART INVALID文を使い、位置付けたレコードからキー順に読み込むにはREAD NEXT文を使用する。
* CLOSE IDX-FILE. * * IDX-FILE ALTERNATE-KEYによる位置指定&連続読み * OPEN INPUT IDX-FILE. * MOVE "OFF" TO END-SW MOVE "OFF" TO INV-SW MOVE "LINE 3" TO IDX-KEY2. START IDX-FILE KEY >= IDX-KEY2 INVALID MOVE "ON" TO INV-SW END-START. READ IDX-FILE NEXT AT END MOVE "ON" TO END-SW END-READ. PERFORM UNTIL (END-SW = "ON") DISPLAY "IDX-FILE(IDX-KEY2 >= " IDX-KEY2 ") : " IDX-REC READ IDX-FILE NEXT AT END MOVE "ON" TO END-SW END-READ END-PERFORM.
索引順編成ファイルの特定のレコードに位置付けるには複数のキー(ALTERNATE KEY)が利用できる。
* CLOSE IDX-FILE. * DISPLAY "== SUB-IDX-FILE-TEST-EX ==". SUB-IDX-FILE-TEST-EX. EXIT. * -------------------------------------------------- * 相対編成ファイルテスト * -------------------------------------------------- SUB-REL-FILE-TEST-EN. DISPLAY "== SUB-REL-FILE-TEST-EN ==" * * REL-FILEにテストデータ出力 * OPEN INPUT LS-FILE. OPEN OUTPUT REL-FILE. * MOVE ZERO TO REL-KEY. MOVE "OFF" TO END-SW. READ LS-FILE AT END MOVE "ON" TO END-SW END-READ. PERFORM UNTIL (END-SW = "ON") MOVE LS-REC TO REL-REC ADD 1 TO REL-KEY WRITE REL-REC READ LS-FILE AT END MOVE "ON" TO END-SW END-READ END-PERFORM. * CLOSE LS-FILE. CLOSE REL-FILE. * * REL-FILE読み込み * OPEN INPUT REL-FILE. * MOVE "OFF" TO INV-SW MOVE 6 TO REL-KEY. READ REL-FILE INVALID MOVE "ON" TO INV-SW END-READ. PERFORM UNTIL (INV-SW = "ON") DISPLAY "REL-FILE : " REL-REC ADD 1 TO REL-KEY READ REL-FILE INVALID MOVE "ON" TO INV-SW END-READ END-PERFORM.
相対編成ファイルの読み込みにはREAD INVALID文を使用する。
* CLOSE REL-FILE. * DISPLAY "== SUB-REL-FILE-TEST-EX ==". SUB-REL-FILE-TEST-EX. EXIT. * -------------------------------------------------- * IF文テスト * -------------------------------------------------- SUB-IF-TEST-EN. DISPLAY "== SUB-IF-TEST-EN ==" * OPEN INPUT LS-FILE. * MOVE "OFF" TO END-SW. READ LS-FILE AT END MOVE "ON" TO END-SW END-READ. PERFORM UNTIL (END-SW = "ON") IF (LS-SEQ < ZERO) DISPLAY "MINUS : " LS-REC ELSE DISPLAY "PLUS : " LS-REC END-IF
IF文の条件式には >, >=, =, <=, <, AND, OR が使える。
READ LS-FILE AT END MOVE "ON" TO END-SW END-READ END-PERFORM. * CLOSE LS-FILE. * DISPLAY "== SUB-IF-TEST-EX ==". SUB-IF-TEST-EX. EXIT. * -------------------------------------------------- * EVALUATE文テスト * -------------------------------------------------- SUB-EVALUATE-TEST-EN. DISPLAY "== SUB-EVALUATE-TEST-EN ==" * OPEN INPUT LS-FILE. * MOVE "OFF" TO END-SW. READ LS-FILE AT END MOVE "ON" TO END-SW END-READ. PERFORM UNTIL (END-SW = "ON") EVALUATE TRUE WHEN (LS-SEQ < ZERO) DISPLAY "MINUS : " LS-REC WHEN (LS-SEQ > ZERO) DISPLAY "PLUS : " LS-REC WHEN OTHER DISPLAY "ZERO : " LS-REC END-EVALUATE
条件多分岐にはEVALUATE文を使う。
READ LS-FILE AT END MOVE "ON" TO END-SW END-READ END-PERFORM. * CLOSE LS-FILE. * DISPLAY "== SUB-EVALUATE-TEST-EX ==". SUB-EVALUATE-TEST-EX. EXIT. * -------------------------------------------------- * PERFORM文テスト * -------------------------------------------------- SUB-PERFORM-TEST-EN. DISPLAY "== SUB-PERFORM-TEST-EN ==" * PERFORM VARYING I FROM 1 BY 3 UNTIL (I > 20) DISPLAY "PERFORM I = " I END-PERFORM.
繰り返し文の一例。変数Iの値を1から3づつ増分し、Iが20より大きくなるまで繰り返す。
* DISPLAY "== SUB-PERFORM-TEST-EX ==". SUB-PERFORM-TEST-EX. EXIT. * -------------------------------------------------- * UNSTRING文テスト * -------------------------------------------------- SUB-UNSTRING-TEST-EN. DISPLAY "== SUB-UNSTRING-TEST-EN ==". * MOVE "APPLE ORANGE LEMON PINE" TO WK-UNSTRING. UNSTRING WK-UNSTRING DELIMITED BY ALL SPACE INTO WK-UNSTRING-1 WK-UNSTRING-2 WK-UNSTRING-3 WK-UNSTRING-4. DISPLAY "UNSTRING-1 =(" WK-UNSTRING-1 ")" DISPLAY "UNSTRING-2 =(" WK-UNSTRING-2 ")" DISPLAY "UNSTRING-3 =(" WK-UNSTRING-3 ")" DISPLAY "UNSTRING-4 =(" WK-UNSTRING-4 ")" * MOVE "APPLE,ORANGE,LEMON,PINE" TO WK-UNSTRING. UNSTRING WK-UNSTRING DELIMITED BY "," INTO WK-UNSTRING-1 WK-UNSTRING-2 WK-UNSTRING-3 WK-UNSTRING-4. DISPLAY "UNSTRING-1 =(" WK-UNSTRING-1 ")" DISPLAY "UNSTRING-2 =(" WK-UNSTRING-2 ")" DISPLAY "UNSTRING-3 =(" WK-UNSTRING-3 ")" DISPLAY "UNSTRING-4 =(" WK-UNSTRING-4 ")"
文字列の分割にはUNSTRING文を使う。メインフレームではあまり無いが、CSVファイルを扱う場合に便利。
* DISPLAY "== SUB-UNSTRING-TEST-EX ==". SUB-UNSTRING-TEST-EX. EXIT. * -------------------------------------------------- * INSPECT文テスト * -------------------------------------------------- SUB-INSPECT-TEST-EN. DISPLAY "== SUB-INSPECT-TEST-EN ==". * MOVE "AAA BBB AAA CCC AAA EEE AAA" TO WK-INSPECT. MOVE ZERO TO WK-INSPECT-CNT. INSPECT WK-INSPECT TALLYING WK-INSPECT-CNT FOR ALL "AAA". DISPLAY "INSPECT-CNT = " WK-INSPECT-CNT. * INSPECT WK-INSPECT REPLACING ALL "AAA" BY "aaa". DISPLAY "WK-INSPECT(REPLACED) = " WK-INSPECT.
文字列の置換や文字列の出現回数を数えるにはINSPECT REPLACE文やINSPECT TALLYING文を使う。
* DISPLAY "== SUB-INSPECT-TEST-EX ==". SUB-INSPECT-TEST-EX. EXIT. * -------------------------------------------------- * 編集テスト * -------------------------------------------------- SUB-EDIT-TEST-EN. DISPLAY "== SUB-EDIT-TEST-EN ==". * MOVE 123456 TO WK-EDIT-1. DISPLAY "WK-EDIT-1 [123456] = " WK-EDIT-1. MOVE -123456 TO WK-EDIT-1. DISPLAY "WK-EDIT-1 [-123456] = " WK-EDIT-1. MOVE 123456 TO WK-EDIT-2. DISPLAY "WK-EDIT-2 [123456] = " WK-EDIT-2. MOVE -123456 TO WK-EDIT-2. DISPLAY "WK-EDIT-2 [-123456] = " WK-EDIT-2.
PIC句を使うと数値データを簡単に見やすい形式に編集できる。
* DISPLAY "== SUB-EDIT-TEST-EX ==". SUB-EDIT-TEST-EX. EXIT. * -------------------------------------------------- * COMPUTE文テスト * -------------------------------------------------- SUB-COMPUTE-TEST-EN. DISPLAY "== SUB-COMPUTE-TEST-EN ==". * COMPUTE WK-COMPUTE = 1000 * 123 / (100 - 10 + 123). MOVE WK-COMPUTE TO WK-COMPUTE-2. DISPLAY "WK-COMPUTE = " WK-COMPUTE-2.
一般的な計算はCOMPUTE文で行う。
* DISPLAY "== SUB-COMPUTE-TEST-EX ==". SUB-COMPUTE-TEST-EX. EXIT. * -------------------------------------------------- * DIVIDE文テスト * -------------------------------------------------- SUB-DIVIDE-TEST-EN. DISPLAY "== SUB-DIVIDE-TEST-EN ==". * DIVIDE 100 BY 27 GIVING WK-DIVIDE-SHO REMAINDER WK-DIVIDE-AMARI.
でも割算の余りを求めたい場合にはDIVIDE文が便利。
DISPLAY "DIVIDE 100/27 = " WK-DIVIDE-SHO " ... " WK-DIVIDE-AMARI. * DISPLAY "== SUB-DIVIDE-TEST-EX ==". SUB-DIVIDE-TEST-EX. EXIT. * -------------------------------------------------- * VALUE(HEX)文テスト * -------------------------------------------------- SUB-VALUEHEX-TEST-EN. DISPLAY "== SUB-VALUEHEX-TEST-EN ==". * DISPLAY "VALUE HEX = (" WK-VALUEHEX ")".
16進数でもデータの表現ができる。
* DISPLAY "== SUB-VALUEHEX-TEST-EX ==". SUB-VALUEHEX-TEST-EX. EXIT. * -------------------------------------------------- * VALUE(漢字)文テスト * -------------------------------------------------- SUB-VALUEKANJI-TEST-EN. DISPLAY "== SUB-VALUEKANJI-TEST-EN ==". * DISPLAY "VALUE KANJI = (" WK-VALUEKANJI ")".
当然漢字も扱える。ただし、メーカ依存(機種依存)あり。
* DISPLAY "== SUB-VALUEKANJI-TEST-EX ==". SUB-VALUEKANJI-TEST-EX. EXIT. * -------------------------------------------------- * ACCEPT文テスト * -------------------------------------------------- SUB-ACCEPT-TEST-EN. DISPLAY "== SUB-ACCEPT-TEST-EN ==". * DISPLAY "ACCEPT FROM SYSIN(何か入力して下さい): ". ACCEPT WK-ACCEPT FROM SYSIN. DISPLAY "WK-ACCEPT SYSIN = " WK-ACCEPT. * ACCEPT WK-ACCEPT FROM DATE. DISPLAY "WK-ACCEPT DATE = " WK-ACCEPT. * ACCEPT WK-ACCEPT FROM TIME. DISPLAY "WK-ACCEPT TIME = " WK-ACCEPT.
SYSINからの入力、日付の取得、時刻の取得にはACCEPT文を利用する。
* DISPLAY "== SUB-ACCEPT-TEST-EX ==". SUB-ACCEPT-TEST-EX. EXIT. * -------------------------------------------------- * REDEFINES文テスト * -------------------------------------------------- SUB-REDEFINES-TEST-EN. DISPLAY "== SUB-REDEFINES-TEST-EN ==". * MOVE "4210519" TO WK-REDEFINES. DISPLAY "WK-REDEFINES-G = " WK-REDEFINES-G. DISPLAY "WK-REDEFINES-NN = " WK-REDEFINES-NN. DISPLAY "WK-REDEFINES-TT = " WK-REDEFINES-TT. DISPLAY "WK-REDEFINES-HH = " WK-REDEFINES-HH.
データを決まったフォーマットに分割するのにREDEFINES句は便利。
* DISPLAY "== SUB-REDEFINES-TEST-EX ==". SUB-REDEFINES-TEST-EX. EXIT. * -------------------------------------------------- * OCCURS文テスト * -------------------------------------------------- SUB-OCCURS-TEST-EN. DISPLAY "== SUB-OCCURS-TEST-EN ==". * MOVE "ABCDEFGHIJKL" TO WK-OCCURS. PERFORM VARYING I FROM 1 BY 1 UNTIL (I > 12) DISPLAY "WK-OCCURS-X(" I ") = " WK-OCCURS-X(I) END-PERFORM. * MOVE "ABCDEFGHIJKL" TO WK-OCCURS2. PERFORM VARYING I FROM 1 BY 1 UNTIL (I > 3) PERFORM VARYING J FROM 1 BY 1 UNTIL (J > 4) DISPLAY "WK-OCCURS2-X(" I " " J ") = " WK-OCCURS2-X(I J) END-PERFORM END-PERFORM.
配列にはOCCURS句を使用する。
* DISPLAY "== SUB-OCCURS-TEST-EX ==". SUB-OCCURS-TEST-EX. EXIT. * -------------------------------------------------- * SEARCH文テスト * -------------------------------------------------- SUB-SEARCH-TEST-EN. DISPLAY "== SUB-SEARCH-TEST-EN ==". * SEARCH ALL WK-SEARCH AT END MOVE "OFF" TO WK-SEARCH-FIND-SW WHEN (WK-SEARCH-KEY(WK-SEARCH-IDX) = "000005") MOVE "ON" TO WK-SEARCH-FIND-SW END-SEARCH
ワークエリアの2分木サーチがSEARCH ALL文で出来る。
* IF (WK-SEARCH-FIND-SW = "ON") DISPLAY "SEARCH OK KEY = " WK-SEARCH-KEY(WK-SEARCH-IDX) DISPLAY "SEARCH OK NAME = " WK-SEARCH-NAME(WK-SEARCH-IDX) ELSE DISPLAY "SEARCH NG" END-IF. * DISPLAY "== SUB-SEARCH-TEST-EX ==". SUB-SEARCH-TEST-EX. EXIT. * -------------------------------------------------- * FUNCTION-DATE文テスト * -------------------------------------------------- SUB-DATE-TEST-EN. DISPLAY "== SUB-FUNCTION-DATE-TEST-EN ==". * MOVE FUNCTION CURRENT-DATE TO WK-FUNCTION-DATE. DISPLAY "WK-FUNCTION-DATE = " WK-FUNCTION-DATE.
日付の年を西暦4桁で取得する場合はFUNCTION CURRENT-DATEを使う。
* DISPLAY "== SUB-FUNCTION-DATE-TEST-EX ==". SUB-DATE-TEST-EX. EXIT. * -------------------------------------------------- * INITIALIZE文テスト * -------------------------------------------------- SUB-INITIALIZE-TEST-EN. DISPLAY "== SUB-INITIALIZE-TEST-EN ==". * DISPLAY "WK-INITIALIZE(BEFORE) = " WK-INITIALIZE. INITIALIZE WK-INITIALIZE. DISPLAY "WK-INITIALIZE(AFTER) = " WK-INITIALIZE.
ワークエリアの初期化にはINITIALIZE文を使う。PIC句に合わせた適切な値で初期化してくれる。
* DISPLAY "== SUB-INITIALIZE-TEST-EX ==". SUB-INITIALIZE-TEST-EX. EXIT.
実行結果
== SUB-LS-FILE-TEST-EN == LS-FILE : -004LINE 1 LS-FILE : -003LINE 2 LS-FILE : -002LINE 3 LS-FILE : -001LINE 4 LS-FILE : +000LINE 5 LS-FILE : +001LINE 6 LS-FILE : +002LINE 7 LS-FILE : +003LINE 8 LS-FILE : +004LINE 9 LS-FILE : +005LINE 10 == SUB-LS-FILE-TEST-EX ==
== SUB-IDX-FILE-TEST-EN == IDX-FILE DIRECT(IDX-KEY = +001) : +001LINE 6 IDX-FILE(IDX-KEY >= +003) : +003LINE 8 IDX-FILE(IDX-KEY >= +004) : +004LINE 9 IDX-FILE(IDX-KEY >= +005) : +005LINE 10 IDX-FILE(IDX-KEY >= -001) : -001LINE 4 IDX-FILE(IDX-KEY >= -002) : -002LINE 3 IDX-FILE(IDX-KEY >= -003) : -003LINE 2 IDX-FILE(IDX-KEY >= -004) : -004LINE 1 IDX-FILE(IDX-KEY2 >= LINE 3 ) : -002LINE 3 IDX-FILE(IDX-KEY2 >= LINE 4 ) : -001LINE 4 IDX-FILE(IDX-KEY2 >= LINE 5 ) : +000LINE 5 IDX-FILE(IDX-KEY2 >= LINE 6 ) : +001LINE 6 IDX-FILE(IDX-KEY2 >= LINE 7 ) : +002LINE 7 IDX-FILE(IDX-KEY2 >= LINE 8 ) : +003LINE 8 IDX-FILE(IDX-KEY2 >= LINE 9 ) : +004LINE 9 == SUB-IDX-FILE-TEST-EX ==
== SUB-REL-FILE-TEST-EN == REL-FILE : +001LINE 6 REL-FILE : +002LINE 7 REL-FILE : +003LINE 8 REL-FILE : +004LINE 9 REL-FILE : +005LINE 10 == SUB-REL-FILE-TEST-EX ==
== SUB-IF-TEST-EN == MINUS : -004LINE 1 MINUS : -003LINE 2 MINUS : -002LINE 3 MINUS : -001LINE 4 PLUS : +000LINE 5 PLUS : +001LINE 6 PLUS : +002LINE 7 PLUS : +003LINE 8 PLUS : +004LINE 9 PLUS : +005LINE 10 == SUB-IF-TEST-EX ==
== SUB-EVALUATE-TEST-EN == MINUS : -004LINE 1 MINUS : -003LINE 2 MINUS : -002LINE 3 MINUS : -001LINE 4 ZERO : +000LINE 5 PLUS : +001LINE 6 PLUS : +002LINE 7 PLUS : +003LINE 8 PLUS : +004LINE 9 PLUS : +005LINE 10 == SUB-EVALUATE-TEST-EX ==
== SUB-PERFORM-TEST-EN == PERFORM I = 001 PERFORM I = 004 PERFORM I = 007 PERFORM I = 010 PERFORM I = 013 PERFORM I = 016 PERFORM I = 019 == SUB-PERFORM-TEST-EX ==
== SUB-UNSTRING-TEST-EN == UNSTRING-1 =(APPLE ) UNSTRING-2 =(ORANGE ) UNSTRING-3 =(LEMON ) UNSTRING-4 =(PINE ) UNSTRING-1 =(APPLE ) UNSTRING-2 =(ORANGE ) UNSTRING-3 =(LEMON ) UNSTRING-4 =(PINE ) == SUB-UNSTRING-TEST-EX ==
== SUB-INSPECT-TEST-EN == INSPECT-CNT = 004 WK-INSPECT(REPLACED) = aaa BBB aaa CCC aaa EEE aaa == SUB-INSPECT-TEST-EX ==
== SUB-EDIT-TEST-EN == WK-EDIT-1 [123456] = 12,3456 WK-EDIT-1 [-123456] = -12,3456 WK-EDIT-2 [123456] = 12,3456 WK-EDIT-2 [-123456] = 12,3456 == SUB-EDIT-TEST-EX ==
== SUB-COMPUTE-TEST-EN == WK-COMPUTE = 577.4647887323 == SUB-COMPUTE-TEST-EX ==
== SUB-DIVIDE-TEST-EN == DIVIDE 100/27 = +0000000003 ... +0000000019 == SUB-DIVIDE-TEST-EX ==
== SUB-VALUEHEX-TEST-EN == VALUE HEX = (漢字) == SUB-VALUEHEX-TEST-EX ==
== SUB-VALUEKANJI-TEST-EN == VALUE KANJI = (漢字) == SUB-VALUEKANJI-TEST-EX ==
== SUB-ACCEPT-TEST-EN == ACCEPT FROM SYSIN(何か入力して下さい): 適当に入力 WK-ACCEPT SYSIN = 適当に入力 WK-ACCEPT DATE = 090521 WK-ACCEPT TIME = 20181282 == SUB-ACCEPT-TEST-EX ==
== SUB-REDEFINES-TEST-EN == WK-REDEFINES-G = 4 WK-REDEFINES-NN = 21 WK-REDEFINES-TT = 05 WK-REDEFINES-HH = 19 == SUB-REDEFINES-TEST-EX ==
== SUB-OCCURS-TEST-EN == WK-OCCURS-X(001) = A WK-OCCURS-X(002) = B WK-OCCURS-X(003) = C WK-OCCURS-X(004) = D WK-OCCURS-X(005) = E WK-OCCURS-X(006) = F WK-OCCURS-X(007) = G WK-OCCURS-X(008) = H WK-OCCURS-X(009) = I WK-OCCURS-X(010) = J WK-OCCURS-X(011) = K WK-OCCURS-X(012) = L WK-OCCURS2-X(001 001) = A WK-OCCURS2-X(001 002) = B WK-OCCURS2-X(001 003) = C WK-OCCURS2-X(001 004) = D WK-OCCURS2-X(002 001) = E WK-OCCURS2-X(002 002) = F WK-OCCURS2-X(002 003) = G WK-OCCURS2-X(002 004) = H WK-OCCURS2-X(003 001) = I WK-OCCURS2-X(003 002) = J WK-OCCURS2-X(003 003) = K WK-OCCURS2-X(003 004) = L == SUB-OCCURS-TEST-EX ==
== SUB-SEARCH-TEST-EN == SEARCH OK KEY = 000005 SEARCH OK NAME = MIYOSHI == SUB-SEARCH-TEST-EX ==
== SUB-FUNCTION-DATE-TEST-EN == WK-FUNCTION-DATE = 2009052120181282+0900 == SUB-FUNCTION-DATE-TEST-EX ==
== SUB-INITIALIZE-TEST-EN == WK-INITIALIZE(BEFORE) = XXXXXXX9999999XXXXXXX9999999 WK-INITIALIZE(AFTER) = XXXXXXX9999999 0000000 == SUB-INITIALIZE-TEST-EX ==