基本情報技術者 2016年 秋期 午後 問10
次のCOBOLプログラムの説明及びプログラムを読んで、設問1,2に答えよ。
〔プログラムの説明〕
Z社では、毎年実施している従業員の健康診断を今年も実施した。健康診断の結果は、過去10回分が健康診断マスタファイルに記録されている。このプログラムは、今回の健康診断の結果が記録された結果ファイルを読み込み、健康診断マスタファイルに反映する。
(1) 健康診断マスタファイルは、図1に示すレコード様式の順ファイルである。

① 全ての従業員に対するレコードが、従業員番号の昇順に格納される。
② 結果履歴には、当該従業員の過去10回分の健康診断の結果が、受診日の降順に格納される。受診回数が10回に満たない場合、残りの結果履歴には全てゼロが設定される。
③ 受診日には、年、月、日が、それぞれ4桁、2桁、2桁の西暦で格納される。
④ 身長(cm)、体重(kg)、最高血圧(mmHg)、最低血圧(mmHg)には、それぞれの数値が格納される。身長と体重は小数点以下1桁までが格納される。胸部X線には、所見がない場合は0が、所見がある場合は1が格納される。
(2) 結果ファイルは、図2に示すレコード様式の順ファイルである。
① 結果ファイルの先頭レコードとして、様式1のレコードが1件だけ格納される。受診日には、年、月、日が、それぞれ4桁、2桁、2桁の西暦で格納される。受診日は、健康診断マスタファイルに記録されているどの受診日よりも新しい。
② 2件目以降のレコードとして、受診した従業員の様式2のレコードが順不同で格納される。受診していない従業員に対するレコードは存在しない。

① 結果ファイルの先頭レコードとして、様式1のレコードが1件だけ格納される。受診日には、年、月、日が、それぞれ4桁、2桁、2桁の西暦で格納される。受診日は、健康診断マスタファイルに記録されているどの受診日よりも新しい。
② 2件目以降のレコードとして、受診した従業員の様式2のレコードが順不同で格納される。受診していない従業員に対するレコードは存在しない。

設問1:
問題文を見る プログラム中のに入れる正しい答えを、解答群の中から選べ。
a, bに関する解答群
ア:MOVE RSLT-DATE TO NEW-DATE
イ:MOVE ZERO TO CNT
ウ:MOVE ZERO TO NEW-DATE
エ:PERFORM RET-PROC
オ:RELEASE SORT-REC
カ:RELEASE SORT-REC FROM RSLT-REC
cに関する解答群
ア:MST-NO = SORT-NO
イ:MST-NO < SORT-NO
ウ:MST-NO > SORT-NO
エ:MST-NO NOT = SORT-NO
dに関する解答群
ア:FROM 0 BY 1
イ:FROM 9 BY -1
ウ:FROM 10 BY -1
エ:FROM CNT BY 1
模範解答
a:ア、b:カ、c:ア、d:イ
解説
解答の導き方
まず、プログラムが扱う二つのファイルの役割を整理します。COBOL(Common Business-Oriented Language:事務処理向けのプログラミング言語)でいうレコードは、ひとまとまりのデータです。順ファイルは、レコードを並んだ順に読み書きするファイルです。
図1の健康診断マスタファイルでは、従業員番号の昇順にレコードが並び、各従業員の結果履歴は10回分あります。図2の結果ファイルでは、先頭レコードに今回の受診日があり、2件目以降に従業員ごとの検査結果があります。
a:先頭レコードから受診日を保存します。
33行目のREAD RSLT-FILEで、結果ファイルの先頭レコードを読み込みます。このレコードに入っている受診日は、後で健康診断マスタファイルへ書き込む必要があります。60行目ではNEW-DATEをMST-DATE(1)へ移しているため、先頭レコードからRSLT-DATEをNEW-DATEへ保存します。したがって、aには「MOVE RSLT-DATE TO NEW-DATE」が入ります。
b:検査結果のレコードを並べ替えの対象にします。
先頭レコードを読み終えた後、REL-PROCでは結果ファイルの残りのレコードを読み込みます。SORT文は、入力手続で集めたデータをSORT-NOの昇順に並べ替えます。
ここで、RSLT-RECは従業員番号6桁と検査結果15桁で、合計21桁です。SORT-RECもSORT-NOが6桁、SORT-ELMが15桁なので、同じ並びのデータを持てます。そこで、RSLT-RECの内容をSORT-RECへ移してから並べ替え対象にする「RELEASE SORT-REC FROM RSLT-REC」を選びます。FROM RSLT-RECがない選択肢では、読み込んだ検査結果をSORT-RECへ渡せません。
なお、先頭レコードは受診日を記録するためのものです。従業員番号や検査結果を含む2件目以降のレコードとは役割が異なるので、並べ替えの対象にはしません。
c:従業員番号が一致するまでマスタファイルを読み進めます。
並べ替え後の結果レコードは、従業員番号の昇順でRETURNされます。健康診断マスタファイルも従業員番号の昇順です。そのため、マスタファイルを先頭から順に読み、結果レコードの従業員番号と一致する場所まで進めれば、対応する従業員を見つけられます。
MATCHING-PROCでは、まずREAD MST-FILEでマスタファイルのレコードを読みます。その後のPERFORM TEST BEFORE UNTILは、指定した条件が成り立つまで処理を繰り返す書き方です。従業員番号が一致しない間は次のマスタレコードを読み、一致したところで繰り返しを終える必要があります。したがって、cには「MST-NO = SORT-NO」が入ります。
d:古い履歴を一つ後ろへずらし、先頭を空けます。
新しい健康診断結果は、受診日の降順で履歴の1番目に入れます。その前に、現在の履歴を一つ後ろへずらします。MST-HISTORYは、OCCURS 10によって10回分を番号で指定できる繰返し項目です。
MOVE MST-HISTORY(CNT) TO MST-HISTORY(CNT + 1)は、CNT番目の履歴を、その次の位置へ移します。CNTを9から1まで減らしながら繰り返せば、古い履歴を上書きせずに後ろへずらせます。
CNTを10から始めると移動先がMST-HISTORY(11)となり、10回分の範囲を超えてしまいます。よって、CNTを9から1ずつ減らす指定が必要です。PERFORM TEST BEFOREでは処理を始める前にも条件を調べるため、CNTが0になった時点で繰り返しを終えます。したがって、dには「FROM 9 BY -1」が入ります。
ずらした後、60行目と61行目で今回の受診日と検査結果を履歴の1番目に入れます。履歴の10番目にあった最も古い結果は、後ろへ移す対象にならないため、ここで置き換えられます。
誤りやすいポイント
- 結果ファイルの先頭レコードは、従業員ごとの検査結果ではなく、今回の受診日を持つレコードです。検査結果と一緒に並べ替えようとしないようにします。
- RELEASE SORT-RECだけでは、RSLT-RECに読み込んだデータをSORT-RECへ渡せません。読み込んだレコードを渡すためにFROM RSLT-RECが必要です。
- 並べ替えのキーはSORT-NOで、マスタファイル側の比較対象はMST-NOです。番号が一致する場所を探すので、比較条件は等しいことを表します。
- 履歴の移動は後ろから前へではなく、CNTを9から減らして後ろ向きに行います。前から移すと、まだ移していない古い履歴を上書きしてしまいます。
FAQ
Q: なぜ結果ファイルを従業員番号順に並べ替えるのですか?
A: 結果ファイルの従業員レコードは順不同ですが、健康診断マスタファイルは従業員番号順です。結果側も同じ順にすれば、マスタファイルを順に読み進めて対応するレコードを探せます。
A: 結果ファイルの従業員レコードは順不同ですが、健康診断マスタファイルは従業員番号順です。結果側も同じ順にすれば、マスタファイルを順に読み進めて対応するレコードを探せます。
Q: 今回の受診日を各従業員のレコードに保存するのはなぜですか?
A: 結果ファイルの先頭レコードにある受診日は、今回の健康診断に共通する日付です。検査結果を反映するときにNEW-DATEから各従業員の履歴へ移します。
A: 結果ファイルの先頭レコードにある受診日は、今回の健康診断に共通する日付です。検査結果を反映するときにNEW-DATEから各従業員の履歴へ移します。
Q: MST-HISTORY(10)の内容はどうなりますか?
A: 今回の結果を入れるために履歴を一つずつ後ろへずらす際、10番目の内容は11番目へ移せません。そのため、最も古い履歴は残らず、新しい履歴から10回分が保持されます。
A: 今回の結果を入れるために履歴を一つずつ後ろへずらす際、10番目の内容は11番目へ移せません。そのため、最も古い履歴は残らず、新しい履歴から10回分が保持されます。
関連キーワード: 順ファイル、レコード、キーによる並べ替え、順次探索、配列、ファイル終端
設問2:
問題文を見る プログラムを変更して、健康診断の結果を健康診断マスタファイルに反映するときに、全ての従業員の確認結果を図3に示すように表示する。表1中のに入れる正しい答えを、解答群の中から選べ。

〔確認結果の表示についての説明〕
次に該当する従業員は、従業員番号に続けて該当する文字列を表示する。
なお、複数該当する場合は、その全てを表示する。
① 今回受診していない場合はNO-DATA
② 今回と前回の体重を比較して、4kg以上の増減がある場合はWEIGHT
③ 今回の最高血圧が140mmHg以上(高血圧症状)、又は90mmHg以下(低血圧症状)である場合はBLOOD-PRESSURE
④ 今回の胸部X線の診断で所見がある場合はXRAY

eに関する解答群
ア:行番号34と35の間
イ:行番号45と46の間
ウ:行番号51と52の間
エ:行番号52と53の間
fに関する解答群
ア:MOVE 1 TO CNT
イ:MOVE 10 TO CNT
ウ:MOVE MST-DATE(1) TO NEW-DATE
エ:MOVE ZERO TO NEW-DATE
gに関する解答群
ア:MST-WEIGHT(1) >= MST-WEIGHT(2) + 4 OR MST-WEIGHT(1) <= MST-WEIGHT(2) - 4
イ:MST-WEIGHT(1) >= MST-WEIGHT(CNT) + 4 OR MST-WEIGHT(1) <= MST-WEIGHT(CNT) - 4
ウ:MST-WEIGHT(10) >= MST-WEIGHT(9) + 4 OR MST-WEIGHT(10) <= MST-WEIGHT(9) - 4
エ:MST-WEIGHT(10) >= MST-WEIGHT(CNT) + 4 OR MST-WEIGHT(10) <= MST-WEIGHT(CNT) - 4
模範解答
e:ウ、f:ア、g:ア
解説
解答の導き方
この問題では、全従業員の確認結果を表示する位置、表示文字列を作る位置、体重を比較する項目を考えます。
まず、健康診断マスタファイルは「従業員番号の昇順」に並んでいます。一方、結果ファイルの従業員レコードは順不同なので、プログラムでは従業員番号でソート(並べ替え)してからマスタと照合します。これにより、マスタと結果をそれぞれ順に読み進めて、対象の従業員を探せます。
e:未受診者を表示する位置
照合中、結果ファイルに該当する従業員が見つかるまでのマスタレコードは、今回受診していない従業員のものです。そのため、行番号54と55の間に追加される処理で、その従業員番号と「NO-DATA」を表示します。
ただし、全ての結果レコードを処理し終えたあとにも、まだ読んでいないマスタレコードが残ることがあります。その従業員も今回受診していないので、残りを表示する処理は、結果レコードを処理するループの後に置く必要があります。
行番号51のループが終わった後、行番号52の「MATCHING-PROC.」が始まる前なら、結果レコードの処理後に残りのマスタレコードを表示できます。したがって、eはウです。
f:表示文字列の開始位置
新しい健康診断の結果は、行番号60と61で履歴の先頭に設定されます。その後に体重や血圧などの確認結果を、DISP-WKに順に追加します。
追加する位置は、DISP-WK(CNT:)で指定されています。CNTは履歴の番号ではなく、文字列を追加する位置です。従業員ごとに文字列の先頭から作り始めるため、CNTを1に設定します。したがって、fはアです。
g:今回と前回の体重を比べる項目
健康診断マスタファイルの履歴は「受診日の降順」です。さらに、行番号57から59で過去の履歴を後ろへずらし、新しい結果を履歴の1番目に格納します。このため、結果を格納した後は、次のようになります。
「MST-DATE(2) NOT = ZERO」は、前回の受診記録があるかを確認しています。前回の記録がある場合に、今回の体重であるMST-WEIGHT(1)と、前回の体重であるMST-WEIGHT(2)を比べます。
今回の体重が前回より4kg以上重い場合は、MST-WEIGHT(1)がMST-WEIGHT(2) + 4以上です。今回の体重が前回より4kg以上軽い場合は、MST-WEIGHT(1)がMST-WEIGHT(2) - 4以下です。この2つの条件を満たす選択肢はアです。
誤りやすいポイント
- eを結果レコードの処理前に置くと、後で健康診断の結果がある従業員まで「NO-DATA」と表示してしまいます。残りの未処理レコードを表示するので、結果レコードの処理後に置きます。
- CNTは、健康診断履歴の位置ではありません。DISP-WKに文字列を追加する位置です。履歴の位置と混同しないようにします。
- MST-WEIGHT(10)は履歴の中で最も古い側の体重です。今回と前回の比較には、今回の値が入るMST-WEIGHT(1)と、その前の記録であるMST-WEIGHT(2)を使います。
- 体重を比べる処理は、今回の結果を履歴の1番目に移した後に行います。履歴をずらす前の位置で比べると、今回と前回の値を正しく取り出せません。
FAQ
Q: なぜ結果ファイルを従業員番号順に並べ替えるのですか?
A: 健康診断マスタファイルも従業員番号順に並んでいるからです。順番をそろえると、両方のファイルを先頭から順に読みながら照合できます。
A: 健康診断マスタファイルも従業員番号順に並んでいるからです。順番をそろえると、両方のファイルを先頭から順に読みながら照合できます。
Q: 「MST-DATE(2) NOT = ZERO」はなぜ必要ですか?
A: 前回の受診記録がない場合、前回の体重と今回の体重を比較できないためです。履歴の2番目に受診日が記録されているかを確かめています。
A: 前回の受診記録がない場合、前回の体重と今回の体重を比較できないためです。履歴の2番目に受診日が記録されているかを確かめています。
Q: CNTを従業員ごとに1に戻すのはなぜですか?
A: 確認結果の文字列を、従業員ごとにDISP-WKの先頭から作るためです。前の従業員の続きに文字列を追加しないよう、開始位置を初期化します。
A: 確認結果の文字列を、従業員ごとにDISP-WKの先頭から作るためです。前の従業員の続きに文字列を追加しないよう、開始位置を初期化します。
関連キーワード: 順ファイル、ソート、逐次処理、配列、条件判定



