平成11年春
問8 次の COBOLプログラムの説明及びプログラムを読んで、設問に答えよ。
〔プログラムの説明〕
ある会社の支店ごとの月別売上目標ファイルと、商品売上記録ファイルを読んで、指定された月の支店別の目標と実績の売上比較リストを印字する。実績は、指定された月の売上金額を商品売上記録ファイルから取り出し、支店別に集計することによって求める。
(1) 月別売上目標ファイルは、支店コードをキーとする索引ファイルで、そのレコ
ード様式は次のとおりである。
(2) 商品売上記録ファイルは、支店コードの昇順に並べた順ファイルで、そのレコード様式は次のとおりである。
(3) 目標と実績の売上比較リストの印字様式は、次のとおりである。
@表題及びけい線は、あらかじめ用紙に印字されている。
A目標達成率の計算方法は、実績の目標に対する百分率とする。
B目標達成率が 1000%以上のときは、 999%と印字する。
C指定された月に売上実績のない支店は、印字しない。
D商品売上記録ファイルの支店コードが月別売上目標ファイルに存在しない場合は、エラーメッセージを表示する。
(4) 月の指定は、01〜 12のいずれかが正しく入力されるものとする。
〔プログラム〕←クリック
【設問】プログラム中のに入れる正しい答えを、解答群の中から選べ。
a,bに関する解答群 ア not uk-eof イ uk-eof ウ uk-eof = space エ uk-eof not = space オ uk-shiten-code = wk-shiten-code カ uk-shiten-code not = wk-shiten-code
cに関する解答群 ア move loop-exit to loop イ set loop to false ウ set loop to true エ set loop-exit to false オ set space to loop
dに関する解答群 ア uk-kingaku * 100 / wk-mokuhyou イ uk-kingaku / wk-mokuhyou ウ wk-kingaku * 100 / pr-mokuhyou エ wk-kingaku * 100 / wk-mokuhyou オ wk-kingaku / pr-mokuhyou カ wk-kingaku / wk-mokuhyou
さあて久しぶりに解説でも書きましょう。まずこの問題はどんなことをするのか一度おさらいしてみましょう。利用するファイルは2つ。ひとつは支店コードがキーの索引ファイル、もうひとつが商品の売上記録である順編成ファイルです。これらのファイルを利用し、指定(タイプイン)した月ごとの各支店の目標と実績、そして達成率を印字するプログラムを作ることです。ちなみに、仕事上で同じようなリストプログラムをCOBOLで組むケースは非常に多いです。逆にCOBOLで飯を食ってる者なら、この程度のプログラムが解けないのであれば転職を考えた方がいいです。
ここで私からの質問。この2つのファイル、どっちがメインで読むべきファイルなのか解かりますか?
正解は(売上)記録ファイルの方です。(売上)目標ファイルは索引ファイル、つまり参照するファイルです。まずは記録ファイルをガーッと読んで金額の集計だけおこない、記録ファイルの支店コードが変わったら初めて支店コードをキーに目標ファイルを一回だけ読む(検索する)、という流れです。わかるかな?
じゃあ設問に行きましょう。まずは「a」の解答から。プログラムを見ると、最初に月を入力するaccept命令があり、続いてファイルのopen、それからyomuルーチンへジャンプしてreadの順です。そしてif文(設問a)があり、支店コードをワークへ格納している、と。そして続くのはperform until 命令で、uk-eofになる、つまり記録ファイルが無くなるまで以下を繰り返すことになります。
まずこの問題を解く場合、設問aまでしか見ないで解くのは無理です。それ以下のプログラムが理解できないと無理。よく見て下さい。この設問aはプログラム構造上、一回しか通りません。ということは、設問aのif文中の命令は、以下の処理内でも同じことをやってるはずなんです。…ほら、12行ぐらい下にあるでしょ?じゃあ12行下の部分を通る時は、どんな時か考えるわけです。
ヒントはすぐ上のperform printですね。printという名前から察する通り、ここでwrite(印字)をしています。印字が終わったら次の印字準備のために支店コードをセットする、という流れですね。言い替えれば、支店コードの初期セットをやってるわけです。
長くなりましたが、話を設問aに戻しましょう。一体何が入るのか。まずオ(uk-shiten-code = wk-shiten-code)、カ(uk-shiten-code not = wk-shiten-code)は論外です。何故なら初回read直後にわざわざif文で書く必要がないんだから。残りの3つは全てuk-eofが絡んでます。じゃあどれでしょうか?
素朴な疑問として、uk-eofというのは何でしょう?ukというからには売上記録ファイルの頭文字(Uriage Kiroku)だろうとは予想がつきますね。eofは多分ですがEnd Of Fileの略だと思います。つまり記録ファイル終了フラグと判明しました。さてさて。こっからが説明難しい。このuk-eofを実際に見てみましょう。「88 uk-eof value "e".」となっています。88って何でしょうか?これはバリュー値(別の呼び名があるかもしれません)を利用しているだけです。本当の項目は「01 uk-eof-ind pic x value space.」になります。
実は88で指定した項目は真偽(true,false)で判定できるのです。逆に中身がspaceか否かという判断は出来ません。
ということは…設問aの答えとして残るのはア、イのみとなります。そして支店コードを格納する命令がif文内にあるのを考えれば、正解はアの「not uk-eof」になるわけです。イだったらファイルが終了したら〜という反対の条件になるのはおわかりですよね。
ふー、既に疲れました。。さてじゃあ設問bにいきます。設問bのすぐ下で金額の集計をやってますね。ということは、今度はさっき消去したオ、カのどっちかってことです。加算するのは同じ支店の場合だけですから、ここの答えは自ずとオの「uk-shiten-code = wk-shiten-code」になりますね。
次にいきます。設問c。yomuルーチンの頭です。さっきのuk-eofと同じように、loop-indという項目を、loopとloop-exitの2つで利用しています。プログラム全体を見れば一目瞭然ですが、loopという単語は、main以降、ココにしか登場しません。ということはloop-indの中身はyomuルーチンへジャンプした時には不確定だということです。実際にreadしているトコはperform until loop-exit 以降であるため、まずココ(設問c)で初期値セットが必要になります。バリュー項目(uk-eof,loop,loop-exit)にはmove命令ではなく、set命令を用います。またloopとloop-exitは実際には同じ項目のため、初期値をセットするのは正常時であるloopの方になります。そしてこのyomuルーチンを抜ける時に初めてloop-exitにtrueをセットするわけです。(逆にloopはfalseになります。)というわけで、設問cはウの「set loop to true」が正解。
最後です。設問d。えっとこれはただの算数クイズじゃないのかな。ちょっとアホらしいけど、uk-xxxxという名前が出てくる解答は最初から無視していいです。今まで集計してたのはなんだったんだって話になります。残りはウ〜カですね。続いて注目したいのはpr-mokuhyouとwk-mokuhyouです。pr-mokuhyouって印字用のz,zzz,zzz,zz9という項目です。えっとCOBOLでは印字用項目で計算をおこなえません!従って、ウとオは残念ながらここで敗退。残すはエとカですが、カは100倍していないので%計算できません。よって正解はエの「wk-kingaku * 100 / wk-mokuhyou」が正解になりますね。
ヤッター!書いたぞ−!スッゲー疲れたけど書いたぞー!