0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

COBOLのCOPY句をExcelの表にする①

Last updated at Posted at 2026-01-13

目次(リンク)

COBOLのCOPY句をExcelの表にする②
COBOLのCOPY句をExcelの表にする③
COBOLのCOPY句をExcelの表にする④

はじめに

ツールを作った当初の目的

COBOLのCOPY句をExcelの表に展開し、桁位置を編集する方法を考えてみる。

今から約25年くらい前にExcel VBAで作ったツールで、COPY句を汎用機からテキストファイルとしてダウンロードし、それをExcelで読み込んでExcelの表に展開する、というのがある。これがかなり役に立っている。

作成した当時は、設計書の添付資料としての意図で作成し、データベースやトランザクションファイルの編集仕様を定義し、とても重宝していた。

現在は大活躍

時は流れ、最近では汎用機COBOLシステムをサーバJavaシステムへ移管する動きに伴い、「当方のシステムではこの電文レイアウト以外は受け付けられないですよ」という意思表示を相手側システムへ示すために使うようになった。

相手側システムはXMLやjson形式のデータ、こちらのシステムはCOBOLで扱うフラットデータであるため、「桁位置」がとても重要になってくる。

COBOLシステムでは1バイトずれていると全く動かなくなる(どの言語でも同じか?)ので、汎用機・サーバいずれの場合もCOBOLシステムが提示する「桁位置」はかなり大切だ。

COPY句サンプル

COBOLのCOPY句はデータレイアウトを示していて、以下のようなコードであらわされる。
(ざっと手で作成したので項目名とかデータの並びにはあまり意味がない。私が普段使っている富士通汎用機の日本語COBOLを意識して作った。)

COPY0001.txt
000000*  レコード名:サンプルレコード
000000*
000000 01  XXサンプルレコード.
000000   03  XX集団項目01.
000000     05  XX項目01                      PIC  9(02).
000000     05  XX項目02.
000000       07  XX項目02A                  PIC  X(05).
000000       07  XX項目02B                  PIC  X(05).
000000     05  XX項目02-1                  REDEFINES XX項目02.
000000       07  XX項目02-1-1            PIC  X(02).
000000       07  XX項目02-1-2            PIC  9(03).
000000       07  XX項目02-1-3            PIC  X(04).
000000       07  XX項目02-1-4            PIC  9(01).
000000     05  XX項目02-2                  REDEFINES XX項目02.
000000       07  XX項目02-2-1            PIC  9(07).
000000       07  XX項目02-2-2            PIC  9(02).
000000   03  FILLER                              PIC  X(07).
000000   03  XX項目03年月日.
000000     05  XX項目03年                    PIC  9(04).
000000     05  XX項目03月                    PIC  9(02).
000000     05  XX項目03日                    PIC  9(02).
000000   03  XX項目04.
000000     05  XX項目04A                    OCCURS 2.
000000       07  XX項目04B                  OCCURS 3 TIMES.
000000         09  XX項目04C                OCCURS 4 TIMES.
000000           11  XX売上金額
000000                                           PIC  S9(10) COMP-3.
000000           11  XX売上数
000000                                           PIC  S9(09) COMP-3.
000000           11  XX利益額
000000                                           PIC  S9(10) COMP-3.
000000   03  XX項目05                        PIC  X(02) OCCURS 5.
000000   03  XX項目05R                      PIC  9(03)
000000                                           OCCURS 3 TIMES REDEFINES XX項目05.
000000   03  FILLER                              PIC  X(15).

Excel表イメージ

上記のコピー句テキストファイルを読み込んで、Excel VBAで表にする。
表のイメージは以下のとおり。
COPY句レイアウト表イメージ01.png

Excel表の作成ポイント

ポイントは以下の6つ

  1. 左の数字6桁(実際は連番)は無視する。
  2. 開始LEVELからピリオドまで、2行に分かれて定義される場合もある。
  3. レベル(2桁の数字、01や03など)に合わせて項目名を段下げする。COBOLのデータ定義には「集団項目」という考え方があり、集団項目単位で項目を転送(MOVE)したり、IF文の判定に使ったりもできるため、どの集団項目に属する項目なのか?が視覚で分かるのはとても重要である。
  4. OCCURS句は「TIMES」があってもなくてもいい。
  5. OCCURS句とREDEFINES句は同時に定義してあってもいい。
  6. 「S9(10) COMP-3」は「S9(10)COMP-3」として一つの項目として扱う。ちなみに「COMP-3」とは「パック十進数」といい、COBOL言語の独特のデータ格納方式で、数値項目が圧縮されて格納される。例えば「S9(10)COMP-3」は「6バイト」に格納が可能。

COBOLのマニュアルを見ると、他にもいろいろ定義の仕方はあるのだが、私が勤務する職場で実際に使用されるのは主に上記コピー句に記載した内容である。

おそらくExcel VBAを使える人にとっては、COPY句テキストファイルを読み込んでExcelの表にするのは、そんなに難しくはないはずだ。文字列の編集機能を駆使すれば可能である。

桁位置の編集、それが意外と難しい

さて、問題は「桁位置」である。
COBOLのCOPY句の各項目の開始桁位置の算出は、実はかなり難しい。
なぜかというと、REDEFINES句という再定義機能と、OCCURS句という繰り返し機能が存在するためだ。
例えば、上記コピー句を途中まで手動で桁位置を編集すると以下のようになる。(OCCURS句部分は繰り返しを手動で計算するのが面倒なので最下層を1つまで計算する)
COPY句レイアウト表イメージ02.png

桁位置部分の計算は、Excelで項目追加した場合用に「再計算」機能を追加したかったため、表の作成とは別に「桁位置の算出」機能を搭載することとした。

REDEFINES句(再定義)という問題

REDEFINES句が意味すること

COBOLシステムに携わっていると「REDEFINES句」というのは良くある話なのであまり違和感がない。しかし、COBOLシステムに携わっていない技術者にとって(最初は)何のことやら理解できないらしい。「ある項目を再定義して別の項目として使用する」という考え方はCOBOL言語特有なのだと考えられる。

再定義をする場合、同じ領域を同時に使用することは当然できないため、どちらかの定義項目を何かの区分で判断して使用することになる。要するに9(05)の項目に「11122」と編集されていて、これを9(03)項目と9(02)項目で再定義したとすると、9(03)は「111」で9(02)は「22」でしかない。見方が変わるだけだ。理解すれば大した話ではない。しかし、桁位置を埋めていく場合はこれが厄介になる。

REDEFINES句 桁位置の手計算方法

COPY句をExcelの表にする場合、当然REDEFINES句を考慮して桁位置を計算しなければならない。同じ領域を再定義しているので開始位置は「再定義元の項目」と同じになる。
COPY句レイアウト表イメージ03.png
上に掲載した表で見てみると「XX項目02R」は「XX項目名02」の再定義なので、開始桁位置は「XX項目名02」と同じ「3」となる。さらに面倒なことに、再定義項目が集団項目で、その配下に別の項目が定義されている場合、その定義内で桁位置が増えていく。ただし、定義元項目名の桁数を超えることはない。つまり、「XX項目名02」がX(10)で10桁の場合、その再定義集団項目「XX項目02-1」や「XX項目02-2」は、合計10桁以内で定義されていなければならない。再定義項目の合計桁数が定義元項目の桁数を超える場合は、コンパイルエラーが発生する。
また、再定義元の桁数を「超えなければ良い」ので、9桁や8桁で再定義しても問題ない。例えば、「XX項目02-2」は「XX項目02」10桁の再定義であるが、合計9桁しかない。この定義は問題なくコンパイル可能だ。

COPY句をExcelの表にして桁位置を編集する場合、その桁位置を間違いのないように編集しなければならない。

OCCURS句(配列)の考え方

OCCURS句は多次元配列

OCCURS句は他の言語でいうところの配列を表す。考え方は同じで多次元配列が可能だ。

COBOL言語は多次元配列が可能である。しかし、長年COBOLシステムに携わってきたが、2次元配列までしか見たことがない。新人に多次元配列の説明をすると3次元までは理解できるようだが、4次元以降は思考が付いていかないらしい。これはおそらく3次元を立体で想像しているので4次元になったとたんに想像できなくなってしまうからだ。
多次元配列のイメージは、どこまでも「2次元」で考えるのがポイントだ。今回例で掲載している3次元配列のイメージは以下のように考えると良い(と新人の時に先輩から教わった)。
多次元配列イメージ.png
この考え方であれば10次元だろうが20次元だろうが問題なく考えることができる。
ちなみに、ある程度経験年数を経た技術者でも多次元配列が苦手な人もいる。

COPY句レイアウト表イメージ04.png
上記表の3次元配列「XX売上金額」のコードの表現としては「XX売上金額(1,2,3)」となる。他言語でも似たような表現になるはず。

さて、このOCCURS句の桁位置の算出方法だが、上記表のように単純にコピー句読み込んだ状態で表現する場合はそんなに難しくはない。最初の配列(1)しか桁位置が表現できないためだ。しかし、その後に配列項目が続くので繰り返した桁数は算出しないとならない。手作業で桁位置を埋めるのは考えただけでもうんざりする。

後ほど、OCCURS句を展開したCOPY句レイアウト表の作成方法も投稿する予定だが、以下の画像のような表にひたすら桁位置を埋め込んでいくだけだ。(間違ってなければいいが...)
COPY句レイアウト表イメージ05.png
OCCURS句を展開してもしなくても、結局桁位置を地道に算出することには変わりはない。

OCCURS句を展開したExcel表は、電文の受け渡し用レイアウトの提示に必須であり、これを提示するたびに「ツール作っておいて良かった」と思う。

昔、COBOLシステムでデータ送受信を行う場合、以下のようなデータフォーマットが提示されたことがあり、実際にシステム改変で受信側システムを担当したことがある。その時はなんと手書きだった!
レコードデータフォーマット.png
(上記画像はネットに落ちていたヤツを切り取ったものだ。COPY句を元に上記のデータフォーマットを作成するExcelツールで作成したものらしい。すごい!)

視覚的には理解しやすく、作るもの100バイト程度のデータであればギリこれでイケるかもしれない。しかし、現在携わっているいるjavaシステムとのデータ連携は30000バイトを超える送受信が発生している。それをこのデータフォーマットで書くとなると至難の業だ。途中に項目追加が発生すると全て書き直しになる。

文字数がだいぶ多くなってきたので次の記事へ記載する。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?