基本情報技術者 2009年 春期 午後 問10
次のCOBOLプログラムの説明及びプログラムを読んで、設問1,2に答えよ。
〔プログラムの説明〕
売上ファイルを読み込み、販売店コード別に売上集計を行い、売上分析表を印刷する副プログラムである。
(1) 売上ファイルSALES-Fは順ファイルである。
(2) 売上ファイルのレコード様式を図1に示す。

① 売上金額はゼロより大きいものとする。
② すべてのレコードの売上金額を合計しても10けたを超えないものとする。
③ 売上ファイルのデータに誤りはないものとする。
(3) 販売店コードで集計して印刷した売上分析表の例を図2に示す。

① 売上分析表の見出しは印刷済とする。
② 売上分析表は、集計された売上金額の多い順に整列し、印刷する。
③ 累積比率は、当該販売店から上位順位店すべての売上金額の累積を売上金額の総合計で割った比率(%)の小数第2位を切り捨てたものである。
④ 文字“*”の並びは、この累積比率の整数部分の値mをm個の“*”で示したものである。

設問1:
問題文を見る プログラム中のに入れる正しい答えを、解答群の中から選べ。
a, bに関する解答群
ア:ASCENDING KEY SORT-CD
イ:ASCENDING KEY SORT-SALES
ウ:DESCENDING KEY SORT-SALES
エ:DESCENDING KEY TEMP-CD
c〜eに関する解答群
ア:ADD TEMP-SALES TO GROSS-SUM
イ:ADD TEMP-SALES TO INTERIM-SUM
ウ:ADD TEMP-SALES TO SORT-SALES
エ:MOVE TEMP-SALES TO GROSS-SUM
オ:MOVE TEMP-SALES TO INTERIM-SUM
カ:MOVE TEMP-SALES TO SORT-SALES
模範解答
a:ア、b:ウ、c:カ、d:ウ、e:ア
解説
解答の導き方
このプログラムは、売上ファイルを販売店コードごとにまとめ、販売店ごとの売上金額が多い順に印刷します。処理は、販売店コード順に並べる段階と、販売店ごとの合計を売上金額順に並べる段階に分かれています。
COBOL(Common Business-Oriented Language:事務処理向けのプログラミング言語)のSORT文は、指定したキーの順にレコードを並べ替える処理です。SORT文にあるRELEASEは並べ替え対象のレコードを渡す操作、RETURNは並べ替え後のレコードを受け取る操作です。
-
最初の並べ替えでは、販売店コードを昇順にします。1回目のSORT文は、入力した売上レコードを並べ替えてTEMP-Fに渡します。プログラムでは、売上レコードをSORT-Rに移してからRELEASEしています。図1の売上ファイルでは、先頭の項目が販売店コードです。また、SORT-Rの先頭項目はSORT-CDです。そのため、SORT-CDは販売店コードに当たります。次の処理では、同じ販売店コードのレコードを続けて読めるよう、販売店コードを昇順に並べる必要があります。よって、aには「ASCENDING KEY SORT-CD」が入ります。
-
並べ替えた売上レコードを、販売店ごとに合計します。2回目の入力処理では、販売店コード順になったTEMP-Fを読み込みます。コードが同じレコードは連続するため、現在の販売店コードが前のレコードと同じかどうかで、合計の処理を分けられます。・最初のレコードではGROSS-SUMが0です。販売店コードをW-SORT-CDに記録し、現在のレコードの売上金額をSORT-SALESに入れます。したがって、cは「MOVE TEMP-SALES TO SORT-SALES」です。・同じ販売店コードのレコードを読んだときは、その売上金額を既にある販売店別合計に加えます。したがって、dは「ADD TEMP-SALES TO SORT-SALES」です。・販売店コードが変わったときは、それまでの販売店別合計をRELEASEしてから、新しい販売店の合計を始めます。新しい販売店の売上金額をSORT-SALESに入れることで、前の販売店の合計を引き継がずに済みます。このように、cは新しい販売店の合計を始める処理、dは同じ販売店の売上金額を合計に加える処理です。
-
すべての売上金額をGROSS-SUMに加えます。eはIF文の外側にあります。そのため、販売店コードが同じ場合も変わった場合も、読み込んだ売上金額をGROSS-SUMに加えます。GROSS-SUMは販売店別の合計ではなく、売上全体の合計です。よって、eには「ADD TEMP-SALES TO GROSS-SUM」が入ります。売上金額は0より大きいという条件があるため、最初のレコードを処理した後はGROSS-SUMが0ではなくなります。この性質を使い、GROSS-SUMが0かどうかで最初の販売店かを判定しています。また、販売店の切替時にGROSS-SUMを0に戻さないため、全販売店の合計を保てます。最後の販売店については、次の販売店コードを読んで切替を検出する機会がありません。そのため、ループ終了後にGROSS-SUMが0でないことを確認して、最後の販売店別合計をRELEASEします。
-
販売店別合計を売上金額の降順にします。2回目のSORT文では、販売店ごとに合計したSORT-SALESをキーにして、並べ替えたレコードをRETURNで受け取ります。売上金額が多い販売店から印刷するので、キーは降順です。したがって、bには「DESCENDING KEY SORT-SALES」が入ります。
-
累積比率は、並べ替え後の売上金額を順に足して計算します。出力処理では、各販売店のSORT-SALESをINTERIM-SUMに順に加えます。その後、プログラムは「INTERIM-SUM × 100 ÷ GROSS-SUM」を計算します。INTERIM-SUMは、売上金額の多い順に見たときの累積額です。これを全体の売上金額で割るため、売上分析表の累積比率になります。P-RATIOには小数第1位までの比率を入れ、W-RATIOにはその整数部分を入れます。P-ASTERにはW-RATIOの数だけ「*」を並べます。これは、図2の累積比率の表示に対応しています。
誤りやすいポイント
- 最初の並べ替えと2回目の並べ替えの目的を混同しないようにします。最初は販売店コードを昇順にして同じ販売店をまとめやすくし、2回目は販売店別の売上金額を降順にします。
- cとdの違いは、新しい販売店の合計を始めるのか、同じ販売店の合計に加えるのかです。新しい販売店ではMOVE、同じ販売店ではADDを使います。
- GROSS-SUMは販売店別の金額ではなく、全レコードの売上金額の合計です。販売店が変わるたびに初期化するものではありません。
- eは販売店コードを比較するIF文の外側にあるので、販売店コードが変わったときだけでなく、すべてのレコードで実行されます。
- 最後の販売店別合計は、次の販売店への切替がないため、ループの後にRELEASEする必要があります。
FAQ
Q: なぜ最初の販売店をGROSS-SUMが0かどうかで判断できるのですか?
A: GROSS-SUMは最初に0に設定されます。また、売上金額は0より大きいので、1件でも読み込むとGROSS-SUMは0ではなくなります。このため、0かどうかで最初のレコードを処理する前かを判定できます。
A: GROSS-SUMは最初に0に設定されます。また、売上金額は0より大きいので、1件でも読み込むとGROSS-SUMは0ではなくなります。このため、0かどうかで最初のレコードを処理する前かを判定できます。
Q: 販売店別合計を、次の販売店のレコードを読むまでRELEASEしないのはなぜですか?
A: 販売店コード順に並んでいても、何件目でその販売店のレコードが終わるかは先に分かりません。次のレコードでコードが変わったと分かった時点で、それまでの合計が完成したと判断してRELEASEします。
A: 販売店コード順に並んでいても、何件目でその販売店のレコードが終わるかは先に分かりません。次のレコードでコードが変わったと分かった時点で、それまでの合計が完成したと判断してRELEASEします。
Q: INTERIM-SUMとGROSS-SUMは何が違いますか?
A: GROSS-SUMは全販売店の売上金額の合計です。INTERIM-SUMは、売上金額の多い順に出力した販売店について、そこまでの売上金額を累積した値です。累積比率はINTERIM-SUMをGROSS-SUMで割って求めます。
A: GROSS-SUMは全販売店の売上金額の合計です。INTERIM-SUMは、売上金額の多い順に出力した販売店について、そこまでの売上金額を累積した値です。累積比率はINTERIM-SUMをGROSS-SUMで割って求めます。
関連キーワード: 順ファイル、キー順ソート、グループ集計、累積比率、降順ソート
設問2:
問題文を見る この副プログラムを、商品コード、顧客コードでの集計にも使えるように変更する。パラメタの値が、1のときは販売店コード、2のときは商品コード、3のときは顧客コードによる集計となるようにする。表中のに入れる正しい答えを、解答群の中から選べ。

fに関する解答群
ア:S-CD PIC X(10)
イ:S-CD PIC X(10) OCCURS 3
ウ:S-CD PIC X(10) OCCURS 3 INDEXED BY SUM-CD
エ:S-CD PIC X(20)
オ:S-CD PIC X(30)
gに関する解答群
ア:行番号50と51の間
イ:行番号51と52の間
ウ:行番号66と67の間
エ:行番号78と79の間
模範解答
f:イ、g:イ
解説
解答の導き方
この問題では、パラメタ(呼出し元から渡される値)が1、2、3のどれかによって、集計に使うコードを切り替えます。問題文では、1は販売店コード、2は商品コード、3は顧客コードと指定されています。
まず、コードを切り替えるためのデータの持ち方を考えます。
図1の売上ファイルのレコードには、販売店コード、商品コード、顧客コードがそれぞれ10けたで並び、その後に売上金額が並びます。つまり、先頭から10けたずつ、集計対象になり得るコードが3つあります。
そこで、同じ形式の値を複数個まとめ、番号で選べる配列として扱います。COBOL(Common Business-Oriented Language:事務処理向けのプログラミング言語)では、OCCURS句を使うと、同じ項目を指定した個数分並べられます。ここではコードが3つあり、それぞれ10文字なので、fには「S-CD PIC X(10) OCCURS 3」を指定します。PIC X(10)は10文字分の項目を表します。
この配列に入る値は、次の対応になります。
したがって、fには「イ」を選びます。S-CD PIC X(10)だけでは1項目しかなく、PIC X(20)やPIC X(30)ではコードをひとまとまりの文字列として扱うことになり、番号で個別のコードを選べません。
次に、gを入れる位置を考えます。
売上ファイルを読み込む処理では、行番号51で「MOVE SALES-R TO SORT-R」として、読み込んだレコードを並べ替え用のレコードにコピーします。その直後に、集計対象として選ばれたコードをSORT-CDに設定し、行番号52のRELEASEで並べ替え処理に渡す必要があります。
追加する処理は、次のとおりです。
MOVE S-CD(SUM-CD) TO SORT-CD
ここでS-CD(SUM-CD)は、パラメタSUM-CDの値に応じてS-CD(1)、S-CD(2)、S-CD(3)のいずれかを選びます。そして、選んだコードをSORT-CDに入れます。
この処理を行番号51と52の間に置けば、行番号51でレコードをコピーした後、行番号52で並べ替え処理に渡す前に、SORT-CDを選択したコードに置き換えられます。この順序なら、販売店コード、商品コード、顧客コードのどれを集計に使う場合も、そのコードを基準に並べ替えられます。
行番号50と51の間に置くと、その後の行番号51のコピーでSORT-CDが上書きされる可能性があります。一方、行番号52の後では、レコードはすでに並べ替え処理に渡されています。後からSORT-CDを変えても、並べ替えには反映されません。
また、後続の処理では、TEMP-Fから読んだレコードのコードが前のレコードと同じかを調べ、同じコードの売上金額を合計します。そのため、集計対象のコードを使って先に並べ替えておく必要があります。以上から、gは「イ」、つまり行番号51と52の間です。
誤りやすいポイント
- OCCURS 3を付けずにS-CDを1項目だけ定義すると、パラメタの値によって3種類のコードを選べません。
- 「S-CD PIC X(30)」は3つのコードをつないだ30文字の項目です。3つを個別に選ぶ配列ではありません。
- 「INDEXED BY」は、配列の要素を選ぶための添字SUM-CDをそのまま使う指定ではありません。この問題では、1、2、3の値を持つパラメタSUM-CDで要素を選ぶため、OCCURS 3で配列を定義します。
- gを行番号52の後に置くと、選んだコードを設定する前にレコードが並べ替え処理へ渡されてしまいます。SORT-CDの設定は、並べ替え処理に渡す前に行います。
FAQ
Q: SUM-CDが2のとき、どのコードが選ばれますか。
A: S-CD(SUM-CD)はS-CD(2)となるため、商品コードが選ばれます。
A: S-CD(SUM-CD)はS-CD(2)となるため、商品コードが選ばれます。
Q: 売上金額も配列にする必要がありますか。
A: 必要ありません。切り替えるのは集計に使うコードです。売上金額は、既存のレコード項目から並べ替え用のレコードに引き継がれます。
A: 必要ありません。切り替えるのは集計に使うコードです。売上金額は、既存のレコード項目から並べ替え用のレコードに引き継がれます。
Q: なぜ選んだコードで先に並べ替えるのですか。
A: 同じコードのレコードを連続させるためです。連続していれば、前のレコードとコードを比べながら同じコードの売上を合計できます。
A: 同じコードのレコードを連続させるためです。連続していれば、前のレコードとコードを比べながら同じコードの売上を合計できます。
関連キーワード: COBOL、OCCURS句、配列、添字、順ファイル、整列処理



