導入:なぜNATIONAL項目の扱いが重要なのか
COBOLの世界では、長年「1バイト=1文字」という考え方が主流でした。しかし、現代のシステムでは多言語対応が必須であり、UTF-16を扱う「NATIONAL項目」の利用が増えています。初心者の方が特に混乱しやすいのが、「部分参照(データの切り出し)」です。従来の英数字項目(DISPLAY)と同じ感覚でバイト数を意識して計算すると、文字化けやプログラムの暴走を招く原因となります。今回は、モダンCOBOL(2002以降)で採用されている「文字単位」の安全な処理方法を解説します。
基礎知識:NATIONAL項目と部分参照のルール
NATIONAL項目は、1文字を2バイト(UTF-16)として保持します。ここで重要なのは、部分参照 `(開始位置:長さ)` を指定する際、COBOLが自動的に「バイト数」ではなく「文字数(2バイト単位)」を基準にカウントしてくれる点です。
例えば、`WS-DATA(2:3)` と記述した場合、プログラムは「2バイト目から3バイト分」ではなく「2文字目から3文字分(=6バイト分)」を取り出そうとします。この「文字単位で計算できる」という仕様こそが、モダンCOBOLがUnicodeを安全に扱うための強力な武器なのです。
実装:部分参照の論理的な手順
1. データ定義(PICTURE N句)で項目を宣言します。
2. 切り出したい開始位置と長さを確認します。
3. `項目名(開始:長さ)` の形式で記述します。
ここでの「開始」と「長さ」は、常に「文字数」として指定してください。
サンプルプログラム:文字単位の部分参照を体験しよう
以下のコードは、NATIONAL項目から特定の範囲を切り出す実例です。環境(コンパイラ)がCOBOL 2002以降に対応しているか確認してから実行してください。
IDENTIFICATION DIVISION.
PROGRAM-ID. NAT-SAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
- NATIONAL項目を定義(Nは文字数を示す)
01 WS-NAT-DATA PIC N(10) VALUE “あいうえおかきくけこ”.
01 WS-RESULT PIC N(3).
PROCEDURE DIVISION.
MAIN-LOGIC.
- 2文字目から3文字分(い・う・え)を取り出す
- 部分参照は「バイト」ではなく「文字数」で指定する
MOVE WS-NAT-DATA(2:3) TO WS-RESULT.
DISPLAY “切り出し結果: ” WS-RESULT.
STOP RUN.
応用・注意点:現場で陥りやすい罠
現場で最も多いミスは、「DISPLAY項目(英数字)とNATIONAL項目(日本語)を混同して計算すること」です。
1. 混在時の注意:英数字項目(X)とNATIONAL項目(N)をMOVEなどでやり取りする場合、暗黙の変換が行われます。この際、文字エンコーディングの違いで予期せぬ挙動をすることがあるため、可能な限りNATIONAL項目同士で処理を完結させるのが安全です。
2. サロゲートペアの壁:UTF-16には、1文字を4バイト(サロゲートペア)で表現する特殊な文字(一部の絵文字や稀な漢字)があります。今回の「文字単位」の計算でも、これらは「2文字」としてカウントされる場合があります。厳密に文字数を管理する必要がある場合は、文字列の長さを取得する組み込み関数(LENGTH関数など)と組み合わせて動的に長さを計算する習慣をつけましょう。
モダンCOBOLの仕様を正しく理解すれば、Unicodeデータも怖くありません。ぜひこの「文字単位」の考え方を身につけて、堅牢なプログラム作成に役立ててください。

コメント