基本情報技術者 2019年 秋期 午後 問10
次のCOBOLプログラムの説明及びプログラムを読んで、設問1,2に答えよ。
〔プログラムの説明〕
ある地域で5店舗のスーパーマーケットを展開するW社では、全店舗で弁当を販売している。どの店舗も、1日に仕入れる弁当の個数は、一つの種類について50個以内である。売れ残ってしまう弁当を減らす目的で、18時以降は正価の20%引きで、19時以降は正価の50%引きで販売している。閉店後は売れ残った弁当を廃棄し、販売状況を分析して、翌営業日の仕入れの参考にしている。
このプログラムは、販売ファイルに格納された弁当の販売データを読み込み、店舗ごとに集計して、販売リストに印字する。
(1) 販売ファイルSAL-FILEは、図1に示すレコード様式の順ファイルであり、全5店舗で1日に販売又は廃棄した弁当のデータが格納されている。弁当1個に対して1レコードが作成される。

① 店舗番号には、店舗の番号が01~05で格納されている。
② 弁当種別には、弁当の種類ごとに一意に割り振られた番号が格納されている。
③ 値引率には、正価で販売した場合は000が、20%引きで販売した場合は020が、50%引きで販売した場合は050が、廃棄した場合は100が格納されている。
(2) 販売リストの印字様式を、図2に示す。見出しは印刷済みとする。

① 販売個数には、販売した弁当の個数を印字する。廃棄した分は含めない。
② 平均値引率には、弁当種別ごとに、販売した弁当の値引率の平均を印字する。廃棄した分は含めない。全ての弁当を廃棄した場合は、0を印字する。
③ 販売リストには、図3の印字例のように、店舗番号及び弁当種別の昇順に印字する。


設問1:
問題文を見る プログラム中のに入れる正しい答えを、解答群の中から選べ。
aに関する解答群
ア:SRT-STOR = CR-STOR AND SRT-CODE = CR-CODE
イ:SRT-STOR = CR-STOR OR SRT-CODE = CR-CODE
ウ:SRT-STOR NOT = CR-STOR AND SRT-CODE NOT = CR-CODE
エ:SRT-STOR NOT = CR-STOR OR SRT-CODE NOT = CR-CODE
bに関する解答群
ア:CR-STOR CR-CODE
イ:PRT-SALNO PRT-DSPNO
ウ:PRT-STOR PRT-CODE
エ:W-DSCT
オ:W-SALNO W-DSPNO W-TOTAL
cに関する解答群
ア:ADD 1 TO W-TOTAL
イ:ADD SRT-DSCT TO W-TOTAL
ウ:MOVE SRT-DSCT TO W-TOTAL
エ:MOVE ZERO TO SRT-DSCT
オ:MOVE ZERO TO W-DSPNO
dに関する解答群
ア:CR-STOR = ZERO
イ:CR-STOR NOT = ZERO
ウ:NOT SRT-EOF
エ:SRT-EOF
模範解答
a:エ、b:オ、c:イ、d:イ
解説
解答の導き方
このプログラムは、弁当1個ごとの販売データを読み込み、店舗番号と弁当種別の組合せごとに、販売個数・平均値引率・廃棄個数を集計します。レコードは、ファイルにある1件分のデータです。
まず、ファイルの並び方を確認します。本文には、販売リストを「店舗番号及び弁当種別の昇順に印字する」とあります。プログラムでも、33行目で SRT-STOR、SRT-CODE の順に昇順で並べ替えています。そのため、同じ店舗番号・弁当種別のデータは続けて処理されます。
たとえば、同じ組合せのデータを読んでいる間は個数などを加算し、その組合せが変わったところで、それまでの集計結果を印字します。
-
a:集計対象の組合せが変わったかどうか集計の区切りは、店舗番号と弁当種別の両方が同じかどうかで判断します。どちらか一方でも前の値と異なれば、別の組合せです。したがって、条件は「店舗番号が異なる、または弁当種別が異なる」です。選択肢では、両方の「異なる」条件を OR で結んだエが当てはまります。
- アのように、両方が同じときに条件を満たす形では、集計の区切りになりません。
- ウのように、両方が異なることを求めると、店舗番号だけが変わった場合や弁当種別だけが変わった場合を見落とします。
-
b:新しい組合せのためにゼロに戻す値組合せが変わったときは、前の組合せの結果をまず印字します。その後、次の組合せの集計を始めるため、前の組合せのカウンタをゼロに戻します。集計する値は次の3つです。
- W-SALNO:販売した個数
- W-DSPNO:廃棄した個数
- W-TOTAL:販売した弁当の値引率の合計
これらはすべて組合せごとの集計値なので、まとめて初期化する必要があります。したがって、bにはオが入ります。処理の順番も大切です。先にゼロにすると、直前の組合せの集計結果が失われます。プログラムは、印字してからカウンタをゼロに戻しています。 -
c:値引率の合計を作る処理販売個数は、すでに W-SALNO に加算されています。平均値引率を計算するには、販売した弁当の値引率を合計し、その合計を販売個数で割ります。たとえば、販売した2個の値引率が000と020なら、合計は20、販売個数は2です。平均値引率は、 になります。そのため、販売データの値引率 SRT-DSCT を W-TOTAL に加算します。cにはイが入ります。値引率100は廃棄を表すので、52行目の条件によってこの加算処理には進みません。これにより、廃棄した弁当は販売個数にも平均値引率にも含まれません。
-
d:集計結果を印字する条件PRT-PROC は、組合せが変わったときだけでなく、すべてのレコードを読み終えた後にも呼び出されます。読み終えた時点で最後の組合せを印字するためです。一方、最初のレコードを処理するときにも、組合せが変わったと判断され、PRT-PROC が呼び出されます。しかし、その時点ではまだ印字できる集計結果がありません。CR-STOR は最初にゼロで初期化されており、実際の店舗番号は01~05だからです。そこで、CR-STOR がゼロでないときだけ印字します。これなら、最初の空の集計結果は印字せず、最後の組合せも印字できます。dにはイが入ります。
処理の流れをまとめると、次のようになります。
誤りやすいポイント
- 店舗番号か弁当種別のどちらか一方が変わったときも、集計の区切りです。「両方が変わったとき」と考えると、区切りを見落とします。
- 平均値引率の計算では、販売個数だけでなく、販売した弁当の値引率の合計も必要です。値引率を加算せず、販売個数だけを数えても平均は求められません。
- 値引率100は廃棄を表します。廃棄個数には加えますが、販売個数や値引率の合計には加えません。
- 最後の組合せは、次の組合せが現れないため、通常の「組合せが変わったとき」の処理だけでは印字できません。読込み後に PRT-PROC を呼び出す処理も必要です。
FAQ
Q:なぜ店舗番号と弁当種別の順に並べ替えるのですか?
A:同じ組合せのデータを続けて処理できるようにするためです。続けて処理できれば、組合せが変わったときに前の集計を印字するだけで、店舗ごと・弁当種別ごとの結果を作れます。
A:同じ組合せのデータを続けて処理できるようにするためです。続けて処理できれば、組合せが変わったときに前の集計を印字するだけで、店舗ごと・弁当種別ごとの結果を作れます。
Q:販売個数がゼロのとき、なぜ平均値引率を計算しないのですか?
A:販売個数を分母にして平均を求めるため、販売個数がゼロだと割り算ができません。プログラムは W-SALNO がゼロでない場合だけ計算します。すべて廃棄した場合の平均値引率は、問題文の指定どおり0として扱います。
A:販売個数を分母にして平均を求めるため、販売個数がゼロだと割り算ができません。プログラムは W-SALNO がゼロでない場合だけ計算します。すべて廃棄した場合の平均値引率は、問題文の指定どおり0として扱います。
Q:廃棄個数も、販売個数と同じように数えるのですか?
A:数えますが、別のカウンタ W-DSPNO に加算します。販売個数と廃棄個数を分けることで、売れた数と廃棄した数の両方を印字できます。
A:数えますが、別のカウンタ W-DSPNO に加算します。販売個数と廃棄個数を分けることで、売れた数と廃棄した数の両方を印字できます。
関連キーワード: COBOL(Common Business-Oriented Language:事務処理向けのプログラミング言語)、順ファイル、ソート、集計処理、条件分岐、初期化
設問2:
問題文を見る 図4に示すとおり、販売リストに販売グラフを追加して印字するようにプログラムを変更する。表1中のに入れる正しい答えを、解答群の中から選べ。

〔販売グラフの説明〕
弁当を正価で販売した場合は“0”を、20%引きで販売した場合は“o”を、50%引きで販売した場合は“-”を、廃棄した場合は“*”を、該当する個数だけ、この順で印字する。

eに関する解答群
ア:行番号50と51の間
イ:行番号53と54の間
ウ:行番号56と57の間
エ:行番号59と60の間
fに関する解答群
ア:1
イ:W-DSCT
ウ:W-DSPNO
エ:W-SALNO
オ:W-TOTAL
模範解答
e:ウ、f:ア
解説
解答の導き方
販売グラフでは、弁当の値引率ごとに販売した個数を数え、その個数分の記号を印字します。正価で販売した個数は「0」、20%引きで販売した個数は「o」、50%引きで販売した個数は「-」で表します。廃棄した個数は、すでにW-DSPNOで数えています。
まず、値引率ごとの個数を数える処理をどこに置くか考えます。
販売データは「弁当1個に対して1レコード」です。そのため、レコードを1件処理するたびに、その値引率に対応する個数を1増やせば、値引率ごとの販売個数を数えられます。
CAL-PROCでは、値引率が100なら廃棄個数W-DSPNOを増やし、それ以外なら販売個数W-SALNOを増やします。値引率ごとの個数を数える処理は、廃棄した弁当ではなく、販売した弁当だけを対象にする必要があります。したがって、販売個数を増やす処理と同じELSE側に置きます。
表1のEVALUATEは、SRT-DSCTの値に応じて処理を選ぶ命令です。値が0、20、50のとき、それぞれ対応するカウンタを増やします。この処理をELSE側に入れる位置は、行番号56と57の間です。
次に、各カウンタに何を加えるかを考えます。1レコードは弁当1個を表すので、値引率に対応する個数は、そのたびに1だけ増えます。例えば、SRT-DSCTが20のレコードを処理したら、W-DSCT20に1を加えます。したがって、ADDで加える値は1です。
W-SALNOは販売した弁当の合計個数、W-TOTALは値引率の合計、W-DSCTは平均値引率を入れる変数です。これらを値引率別の個数カウンタに加えると、数えたい個数とは異なる値になります。
誤りやすいポイント
- 廃棄を販売個数に含めない点に注意してください。値引率が100のレコードはW-DSPNOで数え、値引率別の販売個数には加えません。
- 「値引率の値」と「その値引率で販売した個数」を混同しないようにしましょう。値引率が20でも、個数カウンタに加えるのは20ではなく1です。
- EVALUATEの位置を、出力処理の中にしないようにしましょう。値引率別の個数は、販売データを1レコードずつ処理するたびに数える必要があります。出力時に数えると、各レコードの個数を正しく集計できません。
- 値引率ごとのカウンタは、店舗番号と弁当種別が切り替わるときに初期化されます。そのため、各カウンタには現在集計している弁当種別の個数が入ります。
FAQ
Q: 値引率が100のとき、EVALUATEでどのカウンタも増やさないのはなぜですか?
A: 値引率が100は廃棄を表すためです。廃棄個数はW-DSPNOで別に集計し、販売グラフの「*」もW-DSPNOを使って印字します。
A: 値引率が100は廃棄を表すためです。廃棄個数はW-DSPNOで別に集計し、販売グラフの「*」もW-DSPNOを使って印字します。
Q: W-SALNOを値引率別のカウンタに加えてはいけないのですか?
A: W-SALNOは、値引率に関係なく販売した弁当の合計個数です。値引率別に数えるには、各レコードを処理するたびに該当するカウンタを1増やします。
A: W-SALNOは、値引率に関係なく販売した弁当の合計個数です。値引率別に数えるには、各レコードを処理するたびに該当するカウンタを1増やします。
Q: 販売グラフでは、記号をどの順番で並べますか?
A: 問題文の説明どおり、正価販売の「0」、20%引きの「o」、50%引きの「-」、廃棄の「*」の順です。
A: 問題文の説明どおり、正価販売の「0」、20%引きの「o」、50%引きの「-」、廃棄の「*」の順です。
関連キーワード: COBOL、順ファイル、ソート、カウンタ、条件分岐



