位置情報で子どもの居場所をお知らせ

すみませんCOBOL初心者です。

FILE-CONTROL.
SELECT URIAGE-MOKUHYOU ASSIGN TO "c:\dat\mokuhyou.dat"
ORGANIZATION IS INDEXEDACCESS MODE IS RANDOM RECORD KEY IS UM-SHITEN-CODE.
DATADIVISION.
  FILESECTION.
  FD URIAGE-MOKUHYOU.
  01 UM-REC.
   05 UM-SHITEN.
    10 UM-SHITEN-CODEPIC X(4).
    10 UM-SHITEN-MEIPIC X(20).
   05 UM-KINGAKUPIC 9(10) OCCURS 12.
WORKING-STORAGESECTION.
  01 TSUKIPIC 9(2).
  01 WK-SHITEN-CODEPIC X(4).

PROCEDUREDIVISION.
  DISPLAY "支店コードを入力してください --> : "
  ACCEPT WK-SHITEN-CODE
  OPEN INPUT URIAGE-MOKUHYOU
  READ URIAGE-MOKUHYOU
   INVALID KEY
    DISPLAY "ERROR; 支店コード = " WK-SHITEN-CODE
   NOT INVALID KEY
    DISPLAY WK-SHITEN-CODE " の売上げ目標は " UM-REC
  END-READ.
  STOP RUN.

というプログラムを作成し、"mokuhyou.dat"という入力ファイルに正しくデータが格納されているのですが、コンパイルは問題なく、実行すると、
JMP0310I-U OPEN ERROR FILE=mokuhyou.dat. 'ACC-METHOD'. PGM=TEST046 ADR=00401258
とまず画面にでて、OKを押すと、
JMP0099I-U FORCED TERMINATION CODE=0310
というエラーになります。
おそらくファイルが正常に読み込めないものと推測されますが、解決法を教えてください。お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

う~ん、惜しい。



SELECT URIAGE-MOKUHYOU
  ASSIGN TO "C:\DAT\MOKUHYOU.TXT"
  ORGANIZATION IS SEQUENTIAL.
か、
SELECT URIAGE-MOKUHYOU
  ASSIGN TO "C:\DAT\MOKUHYOU.TXT"
  ORGANIZATION IS LINE SEQUENTIAL.
にする(行順ファイルがサポートされてて使える場合)

SELECT N-URIAGE-MOKUHYOU
  ASSIGN TO "C:\DAT\MOKUHYOU"
  ORGANIZATION IS INDEXED
  ACCESS MODE IS DYNAMIC
  RECORD KEY IS NUM-SHITEN-CODE.
にする。索引ファイルを使う場合、主ファイル名は8文字以内に、拡張子は付けないのが無難。あと、ファイル名は大文字にしとく方が無難(後述)

  05 UM-KINGAKU PIC 9(10) OCCURS 12.
の後ろに
  05 FILLER PIC X(2).
が必要(改行コードのCRとLFの分)

  MOVE UM-REC TO NUM-REC
はやっちゃいけない(テキスト側に改行コードのフィラが増え、テキストファイルと索引ファイルのレコード構造が違ってしまったから。それに各項目ごとに移送してるから不要)

  REWRITE NUM-REC

  WRITE NUM-REC
   INVALID KEY
    REWRITE NUM-REC
  END-WRITE
にする。OUTPUTオープンしてるからファイルは空になってる。つまりレコードは1つも存在しないからREWRITEは出来ない。

「WRITEしてみてINVALID KEYだったらREWRITE」をする理由は、元のテキストファイルに
0001SHITEN-A旧店名、AAに変更済~~~
0001SHITEN-AA~~~~~~~~~~~~
0002SHITEN-B~~~~~~~~~~~~
0003SHITEN-C~~~~~~~~~~~~
のように「同一の支店コードが2つ書いてあった時」のため。REWRITEではなく「同一コードが2つある」とのエラー表示をして終了するのでも良い。

これでダメだとしたら
「使ってるCOBOLに方言があって、テキストファイルを扱う場合のSELECT文に、何か特殊な書き方をしなきゃならない」

「『c:\dat\』のように、ドライブやパス指定を書けない」

「索引ファイルのファイル名には『n-mokuhyou.dat』のように拡張子は付けちゃいけない」

「索引ファイルのファイル名は『n-mokuhyou』のように8文字を超えちゃいけない」

「ファイル名に英文字の小文字を含むと問答無用でエラー」
などの制約が存在する場合がある。

特に索引ファイルでの「拡張子は付けない」と「主ファイル名は8文字以内」は注意。これを守らないとCOBOLが内部でキーファイルのファイル名を自動生成する際に、生成に失敗して実行時にOPEN文で予期せぬエラーが出る可能性が。
古いMS-DOSの仕様を引きずってて廃止して欲しい制約なんだが…。

あと「古いMS-DOSの仕様」に関連してか、ファイル名は大文字を使うのが慣例になっている。ファイル名に小文字を使うと動かないCOBOLがあるらしいので。
    • good
    • 1
この回答へのお礼

ありがとうございました。
お礼遅れて申し訳ありませんでした。
実は、言われたとおりやったつもりでしたが、やはりエラーになってしまって、半分あきらめてました。
でも、改めてこちょこちょいじってるうちに成功しました。

そこでまた新たな質問なんですが、
(1)SELECT FILE01 ASSIGN TO "c:\dat\input-file.txt".
(2)SELECT FILE01 ASSIGN TO INPUT-FL.
OPEN INPUT FILE01
というコードについて、(1)は意味が分かるのですが、(2)はどこからどういうファイルをOPENするのですか?多くのサンプルコードは(2)ですが、そのままコンパイルするとエラーになります。
ローカルフォルダのファイルを使用するという考え自体が違うのですか?
毎回基本的な質問で大変恐縮です。
書籍等を買えば載っているのでしょうが、無精者の私にぜひお力をお貸しください。

お礼日時:2007/05/31 11:11

>(2)SELECT FILE01 ASSIGN TO INPUT-FL.


>OPEN INPUT FILE01
>というコードについて、(1)は意味が分かるのですが、
>(2)はどこからどういうファイルをOPENするのですか?

どこかに
 01 INPUT-FL PIC X(80) VALUE "c:\dat\input-file.txt".
の行がありませんか?

それか、どこかに
 01 INPUT-FL PIC X(80).
の行があって、OPEN INPUT FILE01の前に
   MOVE "c:\dat\input-file.txt" TO INPUT-FL.
って書いてませんか?

普通、SELECT文には、直接ファイル名は指定しないのです。

なぜなら、以下のような手法で、複数のファイルを切り替える事が多いからです。
  MOVE "INPUT001" TO INPUT-FL.
  PERFORM MAIN-START THRU MAIN-EXIT.
  MOVE "INPUT002" TO INPUT-FL.
  PERFORM MAIN-START THRU MAIN-EXIT.
  MOVE "INPUT003" TO INPUT-FL.
  PERFORM MAIN-START THRU MAIN-EXIT.
  STOP RUN.
*
 MAIN-START.
  OPEN INPUT FILE01.
   (メインの処理)
  CLOSE FILE01.
 MAIN-EXIT.
  EXIT.

こうしておけば、OPEN前にINPUT-FLにファイル名を入れ直す事で、同じ処理で複数のファイルを繰り返して操作する事が出来ます。

また「オープンするファイル名は、起動時のコマンドラインに書いてある」と言うケースが多く、コマンドラインからファイル名をMOVEしてくる必要性から、ファイル名部分が変数になっているのが普通なのです。
    • good
    • 0
この回答へのお礼

なるほど!大変よく分かりました。
これで、一通りファイル操作の方法が理解できました。
順読みだとファイルの突合せ処理に無駄が多かったですが、索引ファイルだと効率も良いしコードもすっきりしますね!
これから本格的にCOBOLを使った業務をしないといけないので、また何かあったら教えてください。
本当にありがとうございました。

お礼日時:2007/06/01 08:43

>基本的な質問で恐縮ですが、mokuhyou.datのファイルは自分がテストデータ


>をエディタで編集し、mokuhyou.datの名前で保存しただけなのですが、
>そうではなく、mokuhyou.datは別プログラムから作成すべきということ
>なのでしょうか?

その通りです。

COBOLは以下の4種類のファイルを扱えます。
・レコード順ファイル(テキストファイル)
・行順ファイル(テキストファイル。一部のCOBOLでのみサポート)
・相対ファイル(バイナリファイル)
・索引ファイル(バイナリファイル。データとキーの2つのファイルでセット)

質問者さんのように「特定の値(支店コード)をキーにして、キーで指定したレコードを読み込む場合」は「索引ファイル」を使用します。

この「索引ファイル」は、単純なテキストファイルではなく「レコードファイル」と「キーファイル」に分かれていて、内部は「バイナリファイル」です。

で、エディタなどで書いた1行が固定長のテキストファイルを扱う場合、COBOLでは「レコード順ファイル」を用います。

なお、一部のCOBOLでは「1行が不定長でも良く、レコード終わりは改行コード」と言う、テキストファイルに特化した「行順ファイル」も扱えますが、古いCOBOLではサポートされていません。

そう言った訳で「元データがエディタで書いたテキストファイルで、それをCOBOLで扱う」と言う場合は、以下のようにします(実際の業務で「よくあるパターン」です)

●テキストインポートプログラムを用意する
1.元データのテキストファイルを「レコード順ファイル」で「INPUTオープン」する
2.実際にCOBOLで操作するデータファイルを「索引ファイル」で「I-Oオープン」し「ファイル無しエラー」を検出した場合は「OUTPUTオープン」する。
3.ソースファイルを「READ xxx NEXT」で読む。「AT END節」が実行された場合はソースファイルを最後まで読んだので全ファイルをクローズして終了。
4.読んだレコードの各項目をMOVE命令で書き出しレコードの各項目に移送する(レコード丸ごとMOVEしてはいけない。入力側と出力側で「項目の桁数」が違う可能性がある)
5.「WRITE xxx」で書き出し、もし「INVALID KEY節」が実行されたら、そのキーのレコードは既存なので「REWRITE xxx」する。つまり、レコードが無ければレコードを追加、レコードがあれば更新する事になる。
6.前の「3.」から繰り返す。

●本体のプログラム
1.実際にCOBOLで操作するデータファイルを「索引ファイル」で「I-Oオープン」する。エラーを検出した場合は「データファイルなし」としてプログラム終了
2.キーを指定して(レコードのキー項目に値を入れて)「READ」を行なう。
3.新規のレコードを追加する場合は「WRITE xxx」を、既存のレコードの内容を書き換える場合は「REWRITE」を行なう。
4.クローズして終了。

I-Oオープン、OUTPUTオープンした場合、プログラムを終了する場合は必ず「CLOSE xxx」を行なう事。クローズしないで「STOP RUN」した場合、最悪、最後に書いたレコードがファイルに反映されずに終了します。

ちなみに、COBOLで扱える各ファイルの詳細は、以下のようになります。

・レコード順ファイル
改行コードも含めて固定長であれば、エディタで書いたテキストファイルも読めるが、先頭から順に1レコードづつ読むしか出来ない。
前のレコードに戻ったり、最後のレコードに飛んだりは出来ない。
先頭レコードに戻りたい場合はクローズしてオープンし直す必要がある(REWINDと言う、先頭に戻る文を追加したCOBOLもあるが一般的ではなく、かなり特殊)
索引もキーもなにもないので「同じ内容のレコード」が複数存在する可能性もある。

・行順ファイル(一部のCOBOLでのみサポート)
レコードが固定長ではなく改行コードで区切られる事を除けば、レコード順ファイルと同じ。

・相対ファイル
ファイルの先頭にレコード管理用のヘッダがあり、レコード長は「COBOLが自動で決めた長さ」になっている。
レコードの先頭にはレコード番号がバイナリデータで記録されていて、レコードの各項目もバイナリデータになっている。
テキストファイルではないので、エディタで作る事は不可能。
言うなれば「レコード番号が索引キーになっている索引ファイル」に同等(と言ってもファイルはデータ本体のみで、キーファイルは存在しない)
キーが存在しないのでレコードの重複がチェック出来ないので「同じ内容のレコード」が複数存在する可能性もある。

・索引ファイル
COBOLで最も良く使われるファイル。と言うか、この形式のファイルがあるからCOBOLが使われると言っても過言ではない。
キーを指定する事で、特定のレコードをすぐに呼び出す事が出来る。
「READ xxx NEXT」を使えば「キーを指定せず、次のレコードを読む(オープン直後は先頭レコードを読む)」のも可能なので、レコード順ファイルで行なうような「先頭から最後まで順に処理する」と言う事も可能。
「START」を使うと「指定したキーに最も近いレコード」も探せるので「キーが○○から△△までの間だけ処理する」と言う事も可能になる。
索引キーが「キーファイル」としてデータ本体のファイルと別になっている事が多い。
普通は同一キーのレコード重複は許されないが「RECORD KEY句」に「WITH DUPLICATES」を指定すると、同一キーで複数のレコードを存在させられる。
レコードの先頭には削除フラグがバイナリデータで記録されていて、レコードの各項目もバイナリデータになっている。
テキストファイルではないので、エディタで作る事は不可能。
各レコードの「物理的なファイル位置」は「キーファイル」で管理されているので、レコードの物理的な位置はキーの順番に一致しない。最終レコードがファイルの先頭に存在したり、先頭レコードがファイルの末尾に存在したりする可能性もある。
    • good
    • 1
この回答へのお礼

丁寧なご解答ありがとうございました。
しかし、テキストインポートプログラムを下記のように作成しましたが、一番初めの質問と同じエラーがコンパイル成功後の実行時に発生してしまいます。もう一度、アホな私に原因をお教えいただけないでしょうか?

(補足)
mokhyou.datを読み込み、n-mokuhyou.datに出力しようとしています。
n-mokuhyou.datは存在させず、OPEN OUTPUT で作成しています。
エラーにはなりますが、n-mokuhyou.datは作成され、エディタで覗くと意味不明な文字がいっぱいです。
そのn-mokuhyou.datを使い、本プログラムを実行しても、同じように読込エラーとなります。

FILE-CONTROL.
SELECT URIAGE-MOKUHYOU ASSIGN TO "c:\dat\mokuhyou.dat" .
SELECT N-URIAGE-MOKUHYOU ASSIGN TO "c:\dat\n-mokuhyou.dat"
ORGANIZATION IS INDEXEDACCESS MODE IS DYNAMIC RECORD
KEY IS NUM-SHITEN-CODE.
DATA DIVISION.
FILE SECTION.
FD URIAGE-MOKUHYOU.
01 UM-REC.
05 UM-SHITEN.
10 UM-SHITEN-CODE PIC X(4).
10 UM-SHITEN-MEI PIC X(20).
05 UM-KINGAKU PIC 9(10) OCCURS 12.
FD N-URIAGE-MOKUHYOU.
01 NUM-REC.
05 NUM-SHITEN.
10 NUM-SHITEN-CODE PIC X(4).
10 NUM-SHITEN-MEI PIC X(20).
05 NUM-KINGAKU PIC 9(10) OCCURS 12.
WORKING-STORAGE SECTION.
01 FLG PIC 9 VALUE 0.
01 I PIC 9(2).
PROCEDUREDIVISION.
OPEN INPUT URIAGE-MOKUHYOU
OPEN OUTPUT N-URIAGE-MOKUHYOU
PERFORM UNTIL FLG = 1
READ URIAGE-MOKUHYOU NEXT
AT END
MOVE 1 TO FLG
NOT AT END
MOVE UM-SHITEN-CODE TO NUM-SHITEN-CODE
MOVE UM-SHITEN-MEI TO NUM-SHITEN-MEI
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10
MOVE UM-KINGAKU(I) TO NUM-KINGAKU(I)
END-PERFORM
MOVE UM-REC TO NUM-REC
REWRITE NUM-REC
END-READ
END-PERFORM
CLOSE URIAGE-MOKUHYOU
CLOSE N-URIAGE-MOKUHYOU
STOP RUN.

お礼日時:2007/05/25 15:18

まず、mokuhyou.datを作成する際に「ACCESS MODE IS DYNAMIC」で「OPEN OUTPUT」して、データファイルとキーファイルを作成しておく事。



正しく作成されればmokuhyou.datとmokuhyou.idxの2つのファイルが出来上がる筈。拡張子.idxのファイルは「キーファイル」で、これを元に「キーでの検索」が行なわれる。

てゆ~か、ファイルを作成してるプログラムは、元々「ACCESS MODE IS DYNAMIC」でアクセスしてた筈。それを「ACCESS MODE IS RANDOM」でアクセスしようとするから、実行時にオープン文でエラーが起きてる訳で。

で、特定のキーで特定のレコードを読みたいなら「ACCESS MODE IS DYNAMIC」で、キー付きファイルをオープンする事。

×ACCESS MODE IS RANDOM
○ACCESS MODE IS DYNAMIC

実際、特定のキーで特定のレコードを読む場合は、レコードキーに「欲しいレコードのキー値」をセットしておいてから「READ」を行なう。

×  OPEN INPUT URIAGE-MOKUHYOU
×  READ URIAGE-MOKUHYOU
○  OPEN INPUT URIAGE-MOKUHYOU
○  MOVE WK-SHITEN-CODE TO UM-SHITEN-CODE
○  READ URIAGE-MOKUHYOU

レコードが無ければ「INVALID KEY」節が実行され、あれば「NOT INVALID KEY」節が実行される。
    • good
    • 0
この回答へのお礼

すみません。基本的な質問で恐縮ですが、mokuhyou.datのファイルは自分がテストデータをエディタで編集し、mokuhyou.datの名前で保存しただけなのですが、そうではなく、mokuhyou.datは別プログラムから作成すべきということなのでしょうか?

お礼日時:2007/05/25 09:42

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QCOBOL

COBOLでファイルが終わるまで繰り返す命令はどう書くのですか。

PERFORMを使うと思うのですが分かりません。

AT ENDが何処の来るのかも分かりません教えてください。

Aベストアンサー

一つの例です。

MOVE SPACE  TO FLG-END.
PERFORM UNTIL FLG-END = "END"
  READ A-FILE
   AT END
    MOVE "END"  TO FLG-END
  END-READ
END-PERFORM.

FLG-ENDが"END"になるまでA-FILEの読込を行います。
FLG-ENDはファイル終了を検知した時に"END"がセットされます。

前回もあなたのCOBOLの質問に対して回答させていただいた者ですが、質問しっぱなしは宜しくないと思いますよ。前回の質問疑問が片付いたのなら締め切りましょうね。

QCOBOLの改行

COBOLでWRITEを使って<1>のように出力したいのですがAFTER(もしくはBEFORE) 1 LINE と指定すると<2>のように一行空いて出力されてしまうのはなぜなのでしょう。
ちなみにAFTERを指定しないと<3>のように改行が入らず出力されます。

<1>
AAAAAAAAAA
BBBBBBBBBB
CCCCCCCCCC

<2>
AAAAAAAAAA

BBBBBBBBBB

CCCCCCCCCC

<3>
AAAAAAAAAABBBBBBBBBBCCCCCCCCCC

Aベストアンサー

どんなOSのどんなCOBOLでしょうか?

ファイル出力のレコード記述は、どのようになっていますか?

私は長年、汎用機のCOBOL85を経験していますが、プリンタ制御文字に「空白」を指定する方法で、こういったトラブルには無縁でした。

FD LIST-FILE.
01 LIST-REC.
03 FILLER PIC X.
03 LIST=FLD PIC X(132).


MOVE SPACE TO LIST-REC.
→先頭1文字に空白を入れることで、出力毎に1行改行

QCOBOLの計算方法

COBOLの計算方法について解らない事があり、
質問させて頂きます。

例えば、
111.112÷3=37.03733・・・
の計算で小数点第4位の切捨てまたは、切上をしたい場合、
どのようなコーディングをすればよろしいでしょうか?

Aベストアンサー

01 WORK-AREA.
03 WK-ANS PIC S9(09)V9(04).
03 WK-WK PIC S9(09)V9(04).
03 WK-SUTE PIC S9(09)V9(03).
********************
PROSEDURE DIVISION.
********************
* 切り上げ
COMPUTE WK-WK = 111.112 / 3.
ADD 0.0009 TO WK-WK.
MOVE WK-WK TO WK-ANS. *> 切り上げ
* 四捨五入
COMPUTE WK-ANS ROUNDED = 111.112 / 3.
* 切捨て
COMPUTE WK-SUTE = 111.112 / 3.

何も意識しなければ切捨てになります。
四捨五入はROUNDEDか、0.0005を足してもOK。
切り上げは0.0009する。

こんな感じで如何ですか!

QCOBOLのCALL文がいまいちつかめません。

いつもお世話になっています。
WINDOWSでCOBOL85を使いながら、COBOLの勉強をしています。
JAVAを基本情報試験のために勉強したくらいの初心者です。
シーケンシャルファイルでマッチング処理を行う、
小さなプログラムを課題としている途中、
CALL文を使ってサブプログラムを作ってみてくださいと言われました。

そこで質問なのですが、
メインプログラムの集団項目をUSING指定で引数として、
サブプログラムで受け取り、処理をするまではいいのですが、
戻り値をどのようにして受け取ればいいのかが
イメージがつかめません。
・戻り値を受け取るための命令
・戻り値は1つだと思うのですが、どの変数?に返ってくるのか
(集団項目ごと返ってくる?)
など、何かあればご助言をいただけないでしょうか?

ソースは次の通りです。
よろしくお願いいたします。

■メイン
IDENTIFICATIONDIVISION.
PROGRAM-ID.MACHING_TEST.
(省略)
WORKING-STORAGESECTION.
  01 JUDGE_F.
   03 KEY_F    PIC 9(01).
   03 CHANGE_F    PIC X(06).
   03 EXCEP_M    PIC 9(01).
(省略)
CALL "JUDGE_FEMALE" USING JUDGE_F
ON EXCEPTION
  DISPLAY N"エラーです。プログラムを終了します"
  STOP RUN

  NOT ON EXCEPTION
   IF EXCEP_M = 9
THEN
MOVE"ERRER!"TO FEMALE_OUT
ELSE
 IF EXCEP_M = 1
THEN
MOVE CHANGE_F TO FEMALE_OUT
 END-IF
   END-IF
   END-CALL.
(以下略)

■サブ
IDENTIFICATIONDIVISION.
PROGRAM-ID.JUDGE_FEMALE.

DATADIVISION.
LINKAGESECTION.
01 JUDGE_F.
 03 KEY_FPIC 9(01).
 03 CHANGE_FPIC X(06).
 03 EXCEP_MPIC 9(01).

PROCEDUREDIVISIONUSINGJUDGE_F.

IF KEY_F = 1
 THEN
  MOVE "オトコ" TO CHANGE_F
  MOVE 1 TO EXCEP_M
 ELSE
  IF KEY_F = 2
THEN
 MOVE "オンナ" TO CHANGE_F
 MOVE 1 TO EXCEP_M
ELSE
 MOVE 9 TO EXCEP_M
END-IF
END-IF.
PROGRAM-END.
 STOP RUN.

いつもお世話になっています。
WINDOWSでCOBOL85を使いながら、COBOLの勉強をしています。
JAVAを基本情報試験のために勉強したくらいの初心者です。
シーケンシャルファイルでマッチング処理を行う、
小さなプログラムを課題としている途中、
CALL文を使ってサブプログラムを作ってみてくださいと言われました。

そこで質問なのですが、
メインプログラムの集団項目をUSING指定で引数として、
サブプログラムで受け取り、処理をするまではいいのですが、
戻り値をどのようにして受け取ればいいのかが
...続きを読む

Aベストアンサー

メインからは
CALL "JUDGE_FEMALE" USING JUDGE_F
とJUDGE_Fいう項目を使ってサブをコールしてます。
質問文では書かれてませんが、CALLする前に、KEY-Fに1、2、もしくはそれ以外がセットされてるんだと思います。
つまり、8バイトの頭1バイトだけセットしてコールするわけです。
  01 JUDGE_F.
   03 KEY_F     PIC 9(01).
   03 CHANGE_F     PIC X(06).
   03 EXCEP_M     PIC 9(01).

サブの側ではコール元のプログラムが、KEY-Fに何をセットしてきたかを判定して、CHANGE-FとEXCEP-Mにデータをセットしています。

メインはサブから返されたJUDGE-Fを使って引き続き処理を行います。集団項目で渡して集団項目で帰ってくるだけです。この場合、CHANGE-FとEXCEP-Mをセットするためのサブプログラムですが、作りようによって何項目でも返せます。(必要なだけ定義して集団項目にすればよいです)

メインからは
CALL "JUDGE_FEMALE" USING JUDGE_F
とJUDGE_Fいう項目を使ってサブをコールしてます。
質問文では書かれてませんが、CALLする前に、KEY-Fに1、2、もしくはそれ以外がセットされてるんだと思います。
つまり、8バイトの頭1バイトだけセットしてコールするわけです。
  01 JUDGE_F.
   03 KEY_F     PIC 9(01).
   03 CHANGE_F     PIC X(06).
   03 EXCEP_M     PIC 9(01).

サブの側ではコール元のプログラムが、KEY-Fに何をセットしてきたかを...続きを読む

QCOBOLで文字タイプを数字タイプに変換する方法

すいませんコボル初心者の者です。周りに聞く人がいずに困っています。
アドバイスよろしくおねがします。

例えば、IN-SUNPO PIC X(7)に "0.25"や"0.025"と値が入っているとします。
この項目を OUT-SUNPO PIC 9(4)V9(3)にセットして出力したいのですが
いい方法が考えつきません。
どのようにすれば実現するのでしょうか。
また、IN-TANAK PIC 9(8)をOUT-TANKA PIC X(10)に左詰でセットするために
入力項目の頭のゼロをどう処理していいかもわかりません。
考えても結論がでませんでしたので、投稿しました。
宜しくお願いします。

Aベストアンサー

★ひとつ目の質問。
いろいろと特殊命令を使いますが簡単にコーディングできますし、覚えておくと便利です。

01 wk-seisu.
 03 wk-seisu9 pic 9(4).
01 wk-syosu.
 03 wk-syosu9 pic 9(3).

*<< in-sunpo の空白を0に置き換える >>
inspect in-sunpo replacing all " " by "0".

*<< 「.」で判断して整数と少数に分ける >>
unstring in-sunpo delimited by all "." into wk-seisu wk-syousu.

*<< 分けた数字を合わせる >>
compute in-sunpo = wk-seisu9 + (wk-syosu9 / 1000).



★ふたつ目は他の方が回答されているのと同じです。

*<< 符号(-)があるとき >>
01 wk-tanka.
 03 wk-kanka9  pic -------9.
*<< 符号(-)がないならこれでもいいです >>
01 wk-tanka.
 03 wk-tanka9  pic zzzzzzz9.

move in-tanta to wk-tanka9.
move wk-tanka to out-tanka.



お役に立つかちょっと不安ですが(^^;)
コボル言語は他の言語と違って、ある程度法則を覚えると簡単です。
頑張ってくださいね。

★ひとつ目の質問。
いろいろと特殊命令を使いますが簡単にコーディングできますし、覚えておくと便利です。

01 wk-seisu.
 03 wk-seisu9 pic 9(4).
01 wk-syosu.
 03 wk-syosu9 pic 9(3).

*<< in-sunpo の空白を0に置き換える >>
inspect in-sunpo replacing all " " by "0".

*<< 「.」で判断して整数と少数に分ける >>
unstring in-sunpo delimited by all "." into wk-seisu wk-syousu.

*<< 分けた数字を合わせる >>
compute in-sunpo = wk-seisu9 + (wk-syosu9...続きを読む

QCOBOL数値転記の仕様

このたび、まったくの未経験のCOBOLをやることになりました。
で、数値データの表し方になんやかやとやたら方法があるようなのですが、それらを互いに「転記」したときに、どういう結果になるものか、皆目わからないんです(環境はCOBOL85でWindows上での開発です)。
テクニックとしては基本だと思うのですが、それでいてどこにも説明されていな~い!フリーのCOBOLツールは見つけてきましたが、使い方が???なもので…。
 たとえば、

 01 X1 PIC XX (数値が入ってるとします)
 01 N1 PIC 99
 01 D1 PIC 99 COMP
 01 B1 PIC 1(16) BIT

な場合、X1とN1は直接
 MOVE N1 TO X1
などとやってもデータは失われないと思うんですが、他の形式での操作は(桁あふれとか無視して)ちゃんと転記できるのでしょうか。

いま特に、D1からX1へというパターンが多いです。1バイトの2進データを、数値の文字列として使おう、というんです。いわば、1バイトを3バイトに展開してやるんです。何も考えずに書けば、
 01 D2 PIC 9(4) COMP VALUE 97
 01 X2 PIC X(3)
 MOVE D2 TO X2
でしょうけど、たぶん'a△△'になるだけのような気がします…。
 それとも、
 01 N2 PIC 9(4)
 MOVE D2 TO N2
 MOVE N2 TO X2
などとやっていけたりするのでしょうか。

いったいどうなるのでしょう、いろいろ書いちゃいましたけど、各々の転記の仕組みを教えてください。

また、COBOLの(お堅い規格を書き写しただけでない)解説のサイトなどあれば、ご紹介いただけますでしょうか。

このたび、まったくの未経験のCOBOLをやることになりました。
で、数値データの表し方になんやかやとやたら方法があるようなのですが、それらを互いに「転記」したときに、どういう結果になるものか、皆目わからないんです(環境はCOBOL85でWindows上での開発です)。
テクニックとしては基本だと思うのですが、それでいてどこにも説明されていな~い!フリーのCOBOLツールは見つけてきましたが、使い方が???なもので…。
 たとえば、

 01 X1 PIC XX (数値が入ってるとしま...続きを読む

Aベストアンサー

ShiozawanoYukiさんはCOBOL未経験とのことですが
ご質問のような数値と文字との間の転記はCOBOL上規約はありますが実際には例外的にしか行われないでしょう。

COBOLコードの厳しい社内ルールを定めてる会社では数値と文字との間の転記は禁止されています。
(桁あふれ、計算時に不能や範囲外の値になったり、ひどいとエラー終了になるか引き起こしたりするからです。)
転記する場合は同じ桁数同士のみで行う社内ルールを決めているところもあります。
(桁あるれ対策です。)

*数値と文字との間の転記はデータの定義で対処します。

COBOLのデータは構造体になっています。
(ご質問のようなデータ構造はフラグ、繰り返しや一時的な変数などには使用しますが普通はレベルを使用したデータ構造で定義します。)

>MOVE N1 TO X1
のコードのデータは

 01 X.
  02 X1 PIC 99.
 01 N1 PIC 99.

などと定義し転記後に文字で使用する場合は”X”(2桁)を使用します。
しかし、ただ”N1”を文字として使用するだけである場合は

 01 NX.
  02 N1 PIC 99.

と定義し、”NX”(2桁)を文字として使用する方法もあります。
(これは9タイプとXタイプの内容が同じため利用できますがバイナリなどでは転記してから利用します。)


逆に数値から文字に転記する場合は

 01 D2 PIC 9(4) COMP VALUE 97.
 01 X2.
  02 X9 PIC 9(4).
 01 XR REDEFINES X2.
  02 XR1 PIC X(02).
  02 XR2 PIC X(02).

   MOVE D2 TO X9.

となり文字として使用する場合は”X2”(4桁)を使用します。
”X2”は数字から転記されたので”0097”が入っています。

”X2”を”△△97”にする場合は”X9”を”ZZZ9”または”ZZZZ”(”Z(04)”)の編集項目で定義すれば実現できます。
(”0”(”0000”)を転記した場合に”ZZZ9”は”△△△0”、”ZZZZ”は”△△△△”になります。)

4桁を上2桁と下2桁で使用する場合は上記のように”X2”を再定義(REDEFINES)し”XR1”、”XR2”を使用します。
(個人的には最上位レベルでの再定義は避けるようにしています。)

*実は転記を悩まずに行うには、実は上の厳しい社内ルールと記した”同じ項目種類、桁数でのみ転記”を行い、項目種類の変換はデータ定義で行うのがポイントです。


*COBOLを理解するためにはデータ構造を理解することが良いと思います。
 (命令は他の言語より少なく対応が容易です。ただ、少ない分、自分でコード作成が必要です。ここが他の言語しか知らないプログラマには大変かもしれません。)

後、ピリオドを付けないとのルールがないなら、命令の最後にはピリオドを付けましょう。
(IF文の中では逆に付けません。そのため逆にピリオドがトラブルの原因ともなり、モジュールの最後だけに付けるとの社内ルールを決めているところもあります。)

>また、COBOLの(お堅い規格を書き写しただけでない)解説のサイトなどあれば、ご紹介いただけますでしょうか。

残念ですがCOBOLは他の言語と違い歴史がある割りには定番類があまりありません。

最新のCOBOLは他の言語のように色々な命令が追加されているようですが、本来は当時のプログラミングの専門家以外でもプログラムを作成することを目標に設計されています。
(当時といっても、もう半世紀も前の話ですが・・・)
そのため、元は限られた命令と定義されたデータ構造だけでプログラムが作成できます。
(バッチであればファイル処理と帳票処理を中心に憶えれば良いと思います。問題はオンラインとWebの場合ですが真似からなれるしかないかもしれません。)


参考になるでしょうか?

ShiozawanoYukiさんはCOBOL未経験とのことですが
ご質問のような数値と文字との間の転記はCOBOL上規約はありますが実際には例外的にしか行われないでしょう。

COBOLコードの厳しい社内ルールを定めてる会社では数値と文字との間の転記は禁止されています。
(桁あふれ、計算時に不能や範囲外の値になったり、ひどいとエラー終了になるか引き起こしたりするからです。)
転記する場合は同じ桁数同士のみで行う社内ルールを決めているところもあります。
(桁あるれ対策です。)

*数値と...続きを読む

QCOBOLのファイル出力

初歩の初歩だと思うのですが、3つ質問があります。
1.出力ファイルを新規作成したい場合(物理ファイルが存在していない場合)、コーディングで作成する方法
2.出力ファイルにすでにデータがある場合、後ろに追加する方法
3.出力ファイルにすでにデータがある場合、指定した位置にデータを追加する方法
2,3は順編成ではできないでしょうか?VSAMならできますか?
1はコーディングではできないとしたら、JCLを使用しますか?

ご教授、よろしくお願い致します。

Aベストアンサー

最近はデータベース・コーディングが多いですが

1.OPEN OUTPUT...
実行時に、ファイルが作成されます。(CLOSEが成功したとき)

2.OPEN EXTEND...
レコードが最後に書かれたと思います。
準編成ファイルです。

3.任意の位置に追加する。(VSAM)
1).KDDS
VSAMのKSDS(キー順データセット)でしたら、キーで追加可能です。

2).RSDS
VSAMのRSDS(相対順データセット)でしたら、相対番号で追加可能です。
相対番号で処理する為、滅多に使用しません。

キー(文字コード等)から、ユーザー・ランダマイズ・ルーチンを使用して相対番号を求めてアクセスする事があります。

ユーザー・ランダマイズ・ルーチンは、独自に作成する必要があります。

3).ESDS(エントリー順データセット)
追加できません。

JCLでは、既存のデータセットを削除する、これから作成するデータセットを割り当てる、事ができます。

QCOBOL、項目末尾に空白がある場合削除の方法その他

汎用でCOBOL85で開発しています。

入力Fは固定長、
出力Fは可変長のCSV形式ファイルです。

質問なのは、
値と値の間にカンマを入れる(値がなくても必ず固定数入れる)にはどうすればいいか。
項目の末尾に半角空白が入っていた場合削除するにはどうすればよいか。
項目ごとにMOVE文を書くのではなく、LOOPさせるようにする(項目が多いので)

の書き方です。
半角空白は確か、項目の後ろから1バイトずつ数えて値があった時点で編集するというような
プログラムを見た記憶があるのですが、詳しい書き方がわかりません。
どなたか少しでもお分かりになりましたら教えてもらえないでしょうか。

Aベストアンサー

コンパイル結果のリストで、コンパイラオプションの「STANDARD=(-A)」を確認してください。「-A」が、「アドレス操作を抑止しない」という意味です。

入力ファイルの項目数が四個の場合で、例題を作ってみました。

【コーディング例】デバッグ用のDISPLAY文が入っています。
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE1.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE ASSIGN INFILE.
SELECT OUT-FILE ASSIGN OUTFILE.
DATA DIVISION.
FILE SECTION.
FD IN-FILE LABEL RECORD STANDARD.
01 IN-REC.
03 ITEM1 PIC X(10).
03 ITEM2 PIC X(1).
03 ITEM3 PIC X(5).
03 ITEM4 PIC X(15).
03 FILLER PIC X(41).
03 FILLER PIC X(8).
FD OUT-FILE LABEL RECORD STANDARD
RECORDING MODE V
RECORD VARYING
DEPENDING REC-LEN
BLOCK 10 RECORDS.
01 OUT-REC.
03 FILLER PIC X(500).
WORKING-STORAGE SECTION.
77 I PIC S9(4) COMP.
01 FILLER.
03 REC-LEN PIC S9(4) COMP.
03 DATA-LEN PIC S9(4) COMP.
03 DATA-POS PIC S9(4) COMP.
01 DATA-AREA ADDRESSED BY DATA-PTR.
03 FILLER PIC X
OCCURS 1 TO 500
DEPENDING DATA-LEN.
PROCEDURE DIVISION.
HAJIME.
OPEN INPUT IN-FILE.
OPEN OUTPUT OUT-FILE.
YOMIKOMI.
READ IN-FILE
AT END GO TO OWARI.
MOVE 500 TO REC-LEN.
MOVE 1 TO DATA-POS.
*
COMPUTE DATA-PTR = FUNCTION ADDR(ITEM1).
COMPUTE DATA-LEN = FUNCTION LENGTH(ITEM1).
PERFORM DATA-EXTRACT.
*
COMPUTE DATA-PTR = FUNCTION ADDR(ITEM2).
COMPUTE DATA-LEN = FUNCTION LENGTH(ITEM2).
PERFORM DATA-EXTRACT.
*
COMPUTE DATA-PTR = FUNCTION ADDR(ITEM3).
COMPUTE DATA-LEN = FUNCTION LENGTH(ITEM3).
PERFORM DATA-EXTRACT.
*
COMPUTE DATA-PTR = FUNCTION ADDR(ITEM4).
COMPUTE DATA-LEN = FUNCTION LENGTH(ITEM4).
PERFORM DATA-EXTRACT.
*
COMPUTE REC-LEN = DATA-POS - 2.
DISPLAY 'REC-LEN=' REC-LEN.
DISPLAY 'OUT-REC=(' OUT-REC(1:REC-LEN) ')'.
WRITE OUT-REC.
GO TO YOMIKOMI.
OWARI.
CLOSE IN-FILE OUT-FILE.
GOBACK.
DATA-EXTRACT.
DISPLAY 'EXTRACT STA'.
DISPLAY 'REC-LEN =' REC-LEN.
DISPLAY 'DATA-LEN=' DATA-LEN.
DISPLAY 'DATA-POS=' DATA-POS.
DISPLAY 'DATA-AREA=(' DATA-AREA ')'.
IF DATA-AREA NOT = ' '
PERFORM TEST BEFORE
VARYING I
FROM DATA-LEN BY -1
UNTIL (I < 1) OR (DATA-AREA(I:1) NOT = ' ')
CONTINUE
END-PERFORM
MOVE I TO DATA-LEN
STRING DATA-AREA ','
DELIMITED SIZE
INTO OUT-REC
WITH POINTER DATA-POS
END-STRING
ELSE
STRING ','
DELIMITED SIZE
INTO OUT-REC
WITH POINTER DATA-POS
END-STRING
END-IF.
DISPLAY 'EXTRACT END'.
DISPLAY 'REC-LEN =' REC-LEN.
DISPLAY 'DATA-LEN=' DATA-LEN.
DISPLAY 'DATA-POS=' DATA-POS.

コンパイル結果のリストで、コンパイラオプションの「STANDARD=(-A)」を確認してください。「-A」が、「アドレス操作を抑止しない」という意味です。

入力ファイルの項目数が四個の場合で、例題を作ってみました。

【コーディング例】デバッグ用のDISPLAY文が入っています。
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE1.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION. ...続きを読む

QCOBOL OCCURSで指定したデータの参照の仕方

IBM COBOL でプログラムを作成しています。
初歩的な質問で恥ずかしいのですが、どなたか教えていただけますか。

まず、以下のようなTABLEを定義しました。

01 A-TABLE.
03 B OCCURS 100.
05 C PIC X(08) VALUE SPACE.
05 D PIC X(02) VALUE SPACE.
05 E PIC X(08) VALUE SPACE.
05 F PIC X(05) VALUE SPACE.
05 G PIC X(05) VALUE SPACE.
05 H PIC X(05) VALUE SPACE.


その後に、INPUTファイルからREADしたデータのうち、必要な部分だけを
該当のTABLEに添え字を使用して代入していく処理を作成したいと思っています。

その場合に、上記の「C」~「H」に代入するにはどうすればよいでしょうか?
また後続の処理で直接その値を参照したいのですが、どうすれば良いでしょうか?

私の考えられる範囲で以下のようにプログラムしましたが、
実行時に「OUTSIDE THE REGION OF THE TABLE.」というようなエラーが出力されてしまいました。


MOVE I TO C(IDX1)
MOVE J TO D(IDX1)
MOVE K TO E(IDX1)
MOVE L TO F(IDX1)
MOVE M TO G(IDX1)
MOVE N TO H(IDX1)


どなたかよろしくお願いします。

IBM COBOL でプログラムを作成しています。
初歩的な質問で恥ずかしいのですが、どなたか教えていただけますか。

まず、以下のようなTABLEを定義しました。

01 A-TABLE.
03 B OCCURS 100.
05 C PIC X(08) VALUE SPACE.
05 D PIC X(02) VALUE SPACE.
05 E PIC X(08) VALUE SPACE.
05 F PIC X(05) VALUE SPACE.
05 G PIC X(05) VALUE SPACE.
05 H PIC X(05) VALUE SPACE.


そ...続きを読む

Aベストアンサー

>実行時に「OUTSIDE THE REGION OF THE TABLE.」というようなエラーが出力されてしまいました。

「テーブルの範囲外」を参照しているというエラーのようですから、添字に 1~100以外の値が入っている可能性が大です。

一般的には、以下の部分の再確認となります。
1. 添字の設定前にテーブルを参照、操作していないか。
2. テーブルの上限を超えた場合を考慮しているか。
3. テーブルの上限を超えた場合の処理に誤りはないか。

また、見落としがちなミスとしては、添字の有効桁数不足(今回の場合だと添字を 9(2)で定義していて、99+1で 0になっていた)等もあります。

なお、単純な増減であれば、指標でSET命令(UP BY、DOWN BY)でも可能ですし、今回のように1つの添字(指標)で参照するデータが多いテーブルだと指標を利用する方が処理効率がいい可能性もあります。(コンパイラ次第だとは思いますが)

QCOBOLについて

COBOL初心者なのですが。
COBOLで

01 A.
  03 B PIC 9(02).
  03 C PIC X(02).
MOVE  SPACE  TO  A.

とした時、基本項目であるBには何が入っているのでしょうか?
数字項目にSPACEというのはありえないですよね。
どなたかわかる方、教えていただけませんか?

Aベストアンサー

試してみるのが一番ですが

結果としてはAの集団項目は半角文字項目として
判断されるのでB、Cにスペースが入ります。

ただしBは数字項目なので単独でBの値使おうとすると
数字項目に文字が入っているというエラーがでて
プログラムが異常終了すると思います。

一括で初期化したいのであれば
INITIALIZE A 
とすればBにはゼロ、Cにはスペースが入りますよ。

いろいろ実験してみると覚えも早いと思います。
がんばってください。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング