1. 導入:日本語データの定義、これで安心!
ベテランCOBOLエンジニアの皆さん、そしてこれからCOBOLを学ぶ皆さん、こんにちは!
COBOLでシステム開発をする上で、避けて通れないのが「日本語」の扱いです。例えば、顧客名や商品名など、画面に表示したりファイルに出力したりするデータには、当然ながら日本語が含まれますよね。
そんな時、「え、この項目、何バイトで定義すればいいんだ?」と迷ったことはありませんか?特に、英数字項目である `PIC X` で日本語を扱う際、その桁数指定の「`n`」が「文字数」なのか「バイト数」なのか、混乱しがちです。ここを間違えると、データが途中で切れてしまったり、最悪文字化けの原因になったりすることも。
今回は、COBOLの基本である `USAGE IS DISPLAY` (通常は`PIC X`に暗黙的に適用されます)の項目で日本語を安全に扱うための、「バイト数」の考え方を徹底的に解説します。これを読めば、もう日本語データの定義で悩むことはありません!
2. 基礎知識:PIC Xと日本語、そしてバイト数の関係
まずは、基本となる用語と仕組みを理解しましょう。
- USAGE IS DISPLAYとは?
COBOLのデータ項目には、そのデータがどのように内部で表現されるかを示す `USAGE` 句があります。`USAGE IS DISPLAY` は、「人間が読める文字形式(ディスプレイ表示可能な文字)でデータを格納する」ことを意味します。通常、`PIC X` を使った英数字項目では、この `USAGE IS DISPLAY` が省略されていても暗黙的に適用されます。つまり、`PIC X` の項目はバイト単位で文字が格納される箱、と覚えてください。
- PIC X(n)とは?
`PIC X` は英数字項目を定義するための句です。括弧内の `n` は、その項目が確保する領域の「バイト数」を指定します。例えば `PIC X(10)` であれば、「10バイト分の領域を確保する」という意味になります。
- 日本語(マルチバイト文字)の表現
ここが一番のポイントです。多くの日本のCOBOL環境(特にレガシーシステム)では、シフトJISやEUC-JPといった文字コードが使われています。これらの文字コードでは、
- 半角文字(英数字、記号など)は、1文字あたり1バイト
- 全角文字(漢字、ひらがな、カタカナなど)は、1文字あたり2バイト
で表現されます。
つまり、`PIC X(10)` の領域には、半角文字なら10文字入りますが、全角文字なら5文字しか入らない、ということになります。この「バイト数」と「文字数」の違いをしっかり理解することが、日本語データを正しく扱う第一歩です。
3. 実装/解決策:日本語データ定義の鉄則
`PIC X` で日本語を格納する項目を定義する際は、「格納したい全角文字数 × 2」のバイト数を基準に考えましょう。
例えば、「氏名」の項目に全角漢字で最大10文字を格納したい場合:
- 必要なバイト数 = 10文字 × 2バイト/文字 = 20バイト
- したがって、データ定義は `05 WS-SHIMEI PIC X(20).` となります。
半角文字と全角文字が混在する可能性がある場合は、最もバイト数を消費するケース(例:すべて全角文字が入る場合)を想定して、余裕を持ったバイト数で定義するのが安全です。
4. サンプルプログラム:実際に動かして確認!
それでは、具体的なCOBOLコードで、`PIC X` と日本語のバイト数の関係を見てみましょう。このプログラムをコピー&ペーストして、ご自身の環境で実行してみてください。
IDENTIFICATION DIVISION.
PROGRAM-ID. JPNDISPLAY.
AUTHOR. COBOL-VETERAN.
DATA DIVISION.
WORKING-STORAGE SECTION.
- —————————————————-
- PIC X と日本語のデータ定義と属性の確認
- 日本語 (全角文字) は、多くの場合1文字2バイトで表現されます。
- —————————————————-
- 例1: 全角5文字を格納するのに十分な領域 (5文字 2バイト = 10バイト)
- 「COBOLです」は全角5文字なので10バイト必要です。
05 WS-KANJI-OK PIC X(10) VALUE “COBOLです”.
- 例2: 全角5文字に対して領域が不足しているケース (10バイト必要だが8バイトしかない)
- 後ろの2バイト (1文字分) が切り詰められます。
05 WS-KANJI-NG PIC X(08) VALUE “COBOLです”.
- 例3: 全角文字と半角文字が混在するケース
- 「COBOL 」(全角5文字+半角スペース1文字) は 52+1=11バイト必要。
- ここでは余裕を持って15バイト確保しています。
05 WS-MIX-OK PIC X(15) VALUE “COBOL です”.
- —————————————————-
- LENGTH関数でバイト数を取得する例
- LENGTH関数は、データ項目が占める「バイト数」を返します。
- 環境によってはVALUE句で設定した文字列の実際のバイト数を返す場合もあります。
- —————————————————-
05 WS-LENGTH-KANJI PIC 9(02).
05 WS-LENGTH-MIX PIC 9(02).
05 WS-LENGTH-FIXED PIC 9(02).
PROCEDURE DIVISION.
MAIN-PARA.
DISPLAY “— USAGE IS DISPLAY と日本語 —”
DISPLAY ” ”
- 例1の表示
DISPLAY “例1: 十分な領域がある場合”
DISPLAY ” 定義: 05 WS-KANJI-OK PIC X(10)”
DISPLAY ” 格納: [” WS-KANJI-OK “]”
DISPLAY ” 期待通り、全角5文字が格納されています。”
DISPLAY ” ”
- 例2の表示
DISPLAY “例2: 領域が不足している場合”
DISPLAY ” 定義: 05 WS-KANJI-NG PIC X(08)”
DISPLAY ” 格納: [” WS-KANJI-NG “]”
DISPLAY ” ↑定義が8バイトなので、後ろの「です」の「す」が入りきらず切り詰められています。”
DISPLAY ” このように、データ欠損が発生しますので注意が必要です。”
DISPLAY ” ”
- 例3の表示
DISPLAY “例3: 全角と半角が混在する場合”
DISPLAY ” 定義: 05 WS-MIX-OK PIC X(15)”
DISPLAY ” 格納: [” WS-MIX-OK “]”
DISPLAY ” ↑全角5文字と半角スペース1文字が正しく格納されています。”
DISPLAY ” ”
- LENGTH関数でのバイト数確認
DISPLAY “— LENGTH関数によるバイト数確認 —”
COMPUTE WS-LENGTH-KANJI = LENGTH OF WS-KANJI-OK
DISPLAY ” WS-KANJI-OK (PIC X(10)) のLENGTH: ” WS-LENGTH-KANJI
COMPUTE WS-LENGTH-MIX = LENGTH OF WS-MIX-OK
DISPLAY ” WS-MIX-OK (PIC X(15)) のLENGTH : ” WS-LENGTH-MIX
COMPUTE WS-LENGTH-FIXED = LENGTH OF “日本語テスト” > リテラルのバイト数
DISPLAY ” リテラル「日本語テスト」のLENGTH: ” WS-LENGTH-FIXED
DISPLAY ” ↑LENGTH関数は、項目が確保しているバイト数や、リテラルのバイト数を返します。”
DISPLAY ” これで、定義したバイト数と実際のデータ格納状況を把握できますね。”
DISPLAY ” ”
GOBACK.
5. 応用・注意点:現場で役立つ補足情報
- 文字コードを必ず確認する!
今回説明した「全角1文字=2バイト」は、シフトJISやEUC-JPが使われている環境での話です。近年増えているUTF-8環境では、日本語1文字が3バイト以上になることもあります。システムで使われている文字コードを必ず確認し、それに合わせてバイト数を計算するようにしましょう。
- 文字列操作での注意
`MOVE`、`STRING`、`UNSTRING` などの文字列操作を行う際も、常にバイト数を意識してください。例えば、`MOVE` でバイト数の小さい項目に日本語データを移動すると、今回見たようにデータが途中で切れてしまいます。文字コードの異なるデータ間で変換を行う場合は、さらに注意が必要です。
- LENGTH関数と文字数
COBOLの `LENGTH` 関数は、通常、データ項目が定義している「バイト数」を返します。実際にデータとして格納されている「文字数」を知りたい場合は、環境依存の関数を使うか、ご自身で文字コードを判別しながらカウントするロジックを実装する必要があります。
- 項目名やコメントで明示する
`PIC X` で日本語を扱う項目には、後から見た人が分かりやすいように、コメントで「全角〇文字分」といった補足を加えるか、項目名自体に `WS-NAME-BYTES-20` のようにバイト数を明示するなどの工夫をすると良いでしょう。
- 国別文字項目 (PIC N) も視野に
最新のCOBOL規格には、Unicode(UTF-16など)を扱うための `PIC N` (USAGE IS NATIONAL) という項目タイプもあります。これは文字数を意識して桁数を指定できることが多いですが、既存のレガシーシステムでは `PIC X` が主流です。まずは `PIC X` での日本語の扱いに慣れてから、新しい機能も学ぶと良いでしょう。
今回の記事で、`PIC X` での日本語データの定義と、その裏にある「バイト数」の考え方がスッキリ理解できたでしょうか。COBOLは奥が深いですが、一つ一つの基本をしっかり押さえれば、どんなシステムでも自信を持って開発できるようになりますよ!

コメント