COBOLプログラムのパターンを学ぼう!「キーブレイクとデータ集計」 | 応用ガイド

COBOL(コボル)言語でよく使われるキーブレイクとデータ集計とは?

応用-キーブレイク-イメージ

COBOL(コボル)言語の「キーブレイク処理」とは?

COBOL(コボル)プログラムの処理パターンの1つであるキーブレイク処理(コントロールブレイク処理)は、ソート済みのレコードを順に読み込み、レコードをあるキー項目ごとにグループ分けして処理を行うことを意味します。

グループ分けする単位は業務要件等により変わってきますが、グループ単位で情報を集計して結果を導き出すため、ちょうど表計算ソフトEXCELのピボットテーブルに似た使い方になります。

COBOL(コボル)言語の「キーブレイクとデータ集計」の処理構成

実際にキーブレイクとデータ集計の基本的な処理構成について見ていきましょう。この処理構成を理解する事が今回の処理の理解につながります。

[基本的な処理構成]

1.初期処理、2.主処理、3.終了処理

各処理で実施する処理内容は以下の通りです。

※処理はファイルのレコードがキー順にソートされている事が前提です。

1.初期処理 ファイルオープン処理を行います。
さらに1件目のファイル読み込み処理を行います。
最初にファイルを読み込むのは、この後にキー項目ごとにグループ分けして処理を行 うためです。
2.主処理 ファイル読み込み処理、キーブレイク・データ集計処理を行います。
ファイル読み込み処理を再度実施し、初期処理のレコードと比較します。
さらに、キー項目が変わるタイミングでファイル出力処理を行います。
3.終了処理 ファイルクローズ処理を行います。

基本的な処理構成を見ていただければおわかりになるかと思いますが、1.初期処理、3.終了処理はファイル操作の共通の処理になり、2.主処理のキーブレイク処理、データ集計処理を業務要件に合わせて記述する事で、様々な処理要件に対応する事ができます。では基本的な処理構成について記述したサンプルプログラム(使用例1)を用意しましたので、その書き方について見ていきましょう。

使用例1:

応用-キーブレイク-使用例1

応用-キーブレイク-使用例

使用例1は、ファイルを読み込み、キー項目が同じ間は数字項目を加算し、キー項目が違う場合はキー項目及び、加算していた数字項目の結果をOUT01ファイルに出力するというプログラムになります。入力ファイル、出力ファイルを見ていただくと、キー項目(年)単位に数字が集計されている事がおわかりいただけるかと思います。

入力ファイル(in01.txt):

応用-キーブレイク-入力ファイル

実行結果:

応用-キーブレイク-実行結果

出力ファイル(out01.txt):

応用-キーブレイク-出力ファイル

COBOL(コボル)言語の「キーブレイクとデータ集計」の応用的な使い方

キーブレイクとデータ集計の基本的な処理構成と書き方について理解いただけたでしょうか。今度は、応用的な使い方について考えていきましょう。

キーブレイクとしてグループ分けする単位は1つのキー項目である必要はありません。例えばAグループ、さらにAグループの中でもグループ分けして処理を行う、というような使い方もできます。では、具体的なサンプルプログラム(使用例2)を用意しましたので、しっかり内容を理解して実際のプログラム作成に活用いただければと思います。

グループ分けする単位が多くなると処理が複雑になり理解しづらくなりますので、その点は注意して活用しましょう。

使用例2:

  1. IDENTIFICATION DIVISION.
  2. PROGRAM-ID. SUM_SAMPLE02.
  3. ENVIRONMENT DIVISION.
  4. INPUT-OUTPUT SECTION.
  5. FILE-CONTROL.
  6. SELECT IN01-FILE
  7. ASSIGN TO "in01.txt"
  8. ORGANIZATION IS LINE SEQUENTIAL
  9. FILE STATUS IS IN-FILE-STATUS.
  10. SELECT OUT01-FILE
  11. ASSIGN TO "out01.txt"
  12. ORGANIZATION IS LINE SEQUENTIAL.
  13. DATA DIVISION.
  14. FILE SECTION.
  15. FD IN01-FILE.
  16. 01 IN01.
  17. 03 IN01-YEAR PIC X(04).
  18. 03 IN01-MONTH PIC X(02).
  19. 03 IN01-SUJI PIC 99.
  20. FD OUT01-FILE.
  21. 01 OUT01.
  22. 03 OUT01-YEAR PIC X(04).
  23. 03 OUT01-MONTH PIC X(02).
  24. 03 OUT01-SUJI PIC 999.
  25. 03 OUT01-SUJI-ALL PIC 999.
  26. WORKING-STORAGE SECTION.
  27. 01 IN-FILE-STATUS PIC XX.
  28. 01 WK-KEY-AREA.
  29. 03 WK-KEY-OLD.
  30. 05 WK-KEY-OLD-YEAR PIC X(04).
  31. 05 WK-KEY-OLD-MONTH PIC X(02).
  32. 03 WK-KEY-NEW.
  33. 05 WK-KEY-NEW-YEAR PIC X(04).
  34. 05 WK-KEY-NEW-MONTH PIC X(02).
  35. 01 WK-SUM-AREA.
  36. 03 WK-SUM-SUJI PIC 999.
  37. 03 WK-SUM-SUJI-ALL PIC 999.
  38. PROCEDURE DIVISION.
  39. *> 1.初期処理(ファイルオープン)
  40. OPEN INPUT IN01-FILE.
  41. OPEN OUTPUT OUT01-FILE.
  42. READ IN01-FILE
  43. AT END
  44. DISPLAY "READ END"
  45. NOT AT END
  46. MOVE IN01-YEAR TO WK-KEY-NEW-YEAR
  47. WK-KEY-OLD-YEAR
  48. MOVE IN01-MONTH TO WK-KEY-NEW-MONTH
  49. WK-KEY-OLD-MONTH
  50. MOVE IN01-SUJI TO WK-SUM-SUJI
  51. MOVE IN01-SUJI TO WK-SUM-SUJI-ALL
  52. END-READ
  53. *> 2.主処理(キーブレイク処理、データ集計処理)
  54. PERFORM UNTIL IN-FILE-STATUS NOT = "00"
  55. READ IN01-FILE
  56. AT END
  57. DISPLAY "READ END"
  58. MOVE WK-KEY-OLD-YEAR TO OUT01-YEAR
  59. MOVE WK-KEY-OLD-MONTH TO OUT01-MONTH
  60. MOVE WK-SUM-SUJI TO OUT01-SUJI
  61. MOVE WK-SUM-SUJI-ALL TO OUT01-SUJI-ALL
  62. WRITE OUT01
  63. NOT AT END
  64. MOVE IN01-YEAR TO WK-KEY-NEW-YEAR
  65. MOVE IN01-MONTH TO WK-KEY-NEW-MONTH
  66. *> キーブレイク1
  67. IF WK-KEY-NEW-YEAR = WK-KEY-OLD-YEAR
  68. *> データ集計
  69. THEN
  70. *> キーブレイク2
  71. IF WK-KEY-NEW = WK-KEY-OLD
  72. THEN
  73. COMPUTE WK-SUM-SUJI = WK-SUM-SUJI + IN01-SUJI
  74. COMPUTE WK-SUM-SUJI-ALL = WK-SUM-SUJI-ALL + IN01-SUJI
  75. ELSE
  76. *> ファイル出力
  77. MOVE WK-KEY-OLD-YEAR TO OUT01-YEAR
  78. MOVE WK-KEY-OLD-MONTH TO OUT01-MONTH
  79. MOVE WK-SUM-SUJI TO OUT01-SUJI
  80. MOVE WK-SUM-SUJI-ALL TO OUT01-SUJI-ALL
  81. WRITE OUT01
  82. *> 次のキーをセット
  83. MOVE WK-KEY-NEW TO WK-KEY-OLD
  84. MOVE IN01-SUJI TO WK-SUM-SUJI
  85. COMPUTE WK-SUM-SUJI-ALL = WK-SUM-SUJI-ALL + IN01-SUJI
  86. END-IF
  87. ELSE
  88. *> ファイル出力
  89. MOVE WK-KEY-OLD-YEAR TO OUT01-YEAR
  90. MOVE WK-KEY-OLD-MONTH TO OUT01-MONTH
  91. MOVE WK-SUM-SUJI TO OUT01-SUJI
  92. MOVE WK-SUM-SUJI-ALL TO OUT01-SUJI-ALL
  93. WRITE OUT01
  94. *> 次のキーをセット
  95. MOVE WK-KEY-NEW TO WK-KEY-OLD
  96. MOVE IN01-SUJI TO WK-SUM-SUJI
  97. MOVE IN01-SUJI TO WK-SUM-SUJI-ALL
  98. END-IF
  99. END-READ
  100. END-PERFORM.
  101. *> 3.終了処理(ファイルクローズ)
  102. CLOSE IN01-FILE.
  103. CLOSE OUT01-FILE.
  104. STOP RUN.
  105. END PROGRAM SUM_SAMPLE02.

使用例2は、使用例1とほとんど同じような処理の流れになっていますが、比較するキー項目が年、年月と2つ存在しています。キー項目を2つ作る事で2つのグループ単位に数字を集計する事ができます。

処理については、まずファイルを読み込み、キー項目1(年)が同じ場合、キー項目2(年月)の比較を行います。キー項目2も同じ場合は数字項目を加算し、キー項目2が違う場合はキー項目及び、加算していた数字項目の結果をOUT01ファイルに出力します。この時キー項目2(年月)単位に集計した数字とキー項目1(年)単位に集計した数字を出力しているところがポイントです。キー項目1(年)が違う場合は、キー項目及び、加算していた数字項目(年月、年)の結果をOUT01ファイルに出力し、加算していた数字項目(年月、年)をクリアします。

入力ファイル、出力ファイルを見ていただくと、キー項目(年月、年)単位に数字が集計されている事がおわかりいただけるかと思います。

入力ファイル(in01.txt):

応用-キーブレイク-入力ファイル

実行結果:

応用-キーブレイク-実行結果

出力ファイル(out01.txt):

応用-キーブレイク-出力ファイル

練習問題

最後に練習問題にチャレンジしてみましょう。

問)

先ほどまでのサンプルプログラムはデータ集計するグループの単位として、使用例1では年単位、使用例2では年及び年月単位にしました。では、使用例1を年月日単位にデータ集計するためには、どのようにプログラムを修正しないといけないでしょうか?

答え)

以下のような処理を追加します。

まずは、グループ分けしているキー項目(WK-KEY-OLD、WK-KEY-NEW)を年月日(8桁)に変更します。これは入力するデータのキー項目(IN01-YEAR)及び出力するデータのキー項目(OUT01-YEAR)も同様です。後の処理はキー項目のデータ長に関わらずそのままで使用できます(IN01-YEAR、OUT01-YEARの名称は必要に応じて変更してください)。

注意点としては、用意する入力データも年月日単位にしておく必要がある点です。

この記事を読んだ人は、こちらの記事も読んでいます

【未経験者歓迎】COBOLプログラマー・システムエンジニアの募集

株式会社COBOLの求人・転職・募集情報を見る

COBOL入門のカテゴリー

取引企業様 募集中
COBOL技術者 募集
COBOL魂
読者採用
COBOL入門