
■ 文字列の追加
本来、COBOLで開発をするようなシステムの場合、文字列の結合を行うことは少ないと思います。しかし、CSV形式でのテキストファイル作成とか、複雑なSQL文の作成をCOBOLで行おうとすると、どうしても文字列編集をしたくなります。
COBOLの場合、変数は最初からサイズを決めて宣言するので文字列の操作や編集を行うのは工夫が必要です。
■ STRING文
やりかたは幾らでもあると思いますが、個人的なお気に入りはSTRING文を使う方法です。前の文字列結合の記事(NetCOBOLで文字を結合してみた(STRING文))でも使った機能ですが、このSTRING文には受取側の文字位置を指定することが出来ます。
下記は、文字変数「WK-STRING」に文字列を追加するサンプルです。
IDENTIFICATION DIVISION.
PROGRAM-ID. TESTC999.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
*
01 WK-AREA.
03 WK-STRING PIC X(10).
03 WK-POINTER PIC 9(10).
*
PROCEDURE DIVISION.
*
* ワークエリアの初期化
INITIALIZE WK-AREA.
*
* 出力位置を初期設定
COMPUTE WK-POINTER = 1.
*
* 文字列「ABC」をWK-STRINGに追加
STRING
"ABC" DELIMITED BY SIZE
INTO WK-STRING WITH POINTER WK-POINTER
END-STRING.
*
* 文字列「DEF」をWK-STRINGに追加
STRING
"DEF" DELIMITED BY SIZE
INTO WK-STRING WITH POINTER WK-POINTER
END-STRING.
*
* 文字列「GHI」をWK-STRINGに追加
STRING
"GHI" DELIMITED BY SIZE
INTO WK-STRING WITH POINTER WK-POINTER
END-STRING.
*
* WK-STRING をコンソールに表示
DISPLAY "[" WK-STRING "]".
*
EXIT PROGRAM.
上記を実行すると、コンソールには下記の通りに表示されます。
[ABCDEFGHI ]
肝は「 WITH POINTER WK-POINTER 」です。これを指定することで、WK-POINTERに指定した文字位置から転記が開始されます。STRING文の実行によってWK-POINTERの値が自動的に増加するので、毎回追加位置を指定する必要はありません。
注意点は「WK-POINTER」の初期値を1にしておくことと、「WK-POINTER」をWORKING-STORAGEで宣言しておくこと。もちろん、名称は「WK-POINTER」でなくても良いです。
■ STRING文の実験
「WK-POINTER」の初期値を1と書きましたが、0のままだとどうなるか実験してみます。
上記ソースのWK-POINTERの初期化部分を1からZEROに変更します。
* 出力位置を初期設定
COMPUTE WK-POINTER = ZERO.
結果は、ご覧の有様です。
[ ]
開始位置をありえない位置にすると、転記そのものが失敗するようです。
なお、「WK-POINTER」の部分で変数を使わずに直接数値(1とか4とか)にすると、コンパイルが通りません。
■ STORED-CHAR-LENGTH関数
ここまでの方法でも良いのですが、個人的には気に入りません。追加と言っても送り出し側と受取り側が同じなだけで「文字列の結合」であることに変わりはない。なのに、わざわざ専用の変数を用意するのが嫌です。
そこで、STORED-CHAR-LENGTH関数という文字項目の有効文字数を取得する関数を使用して、受取り項目から既に設定済みの部分を抜き出してSTRING文で結合してやります。
プログラムを、下記の通りに書き換えます。
IDENTIFICATION DIVISION.
PROGRAM-ID. TESTC999.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
*
01 WK-AREA.
03 WK-STRING PIC X(10).
*
PROCEDURE DIVISION.
*
* ワークエリアの初期化
INITIALIZE WK-AREA.
*
* 文字列「ABC」をWK-STRINGに追加
STRING
WK-STRING(1:FUNCTION STORED-CHAR-LENGTH(WK-STRING))
DELIMITED BY SIZE
"ABC" DELIMITED BY SIZE
INTO WK-STRING
END-STRING.
*
* 文字列「DEF」をWK-STRINGに追加
STRING
WK-STRING(1:FUNCTION STORED-CHAR-LENGTH(WK-STRING))
DELIMITED BY SIZE
"DEF" DELIMITED BY SIZE
INTO WK-STRING
END-STRING.
*
* 文字列「GHI」をWK-STRINGに追加
STRING
WK-STRING(1:FUNCTION STORED-CHAR-LENGTH(WK-STRING))
DELIMITED BY SIZE
"GHI" DELIMITED BY SIZE
INTO WK-STRING
END-STRING.
*
* WK-STRING をコンソールに表示
DISPLAY "[" WK-STRING "]".
*
EXIT PROGRAM.
これでも結果は、変わりません。
[ABCDEFGHI ]
ロジック部分だけを見るとさっきよりも見づらくなっていますが、後でプログラムを追う時には変数を意識しないで良いので、こっちの方が追いやすいと思います。
STORED-CHAR-LENGTH関数はCOBOLの標準でなく、独自拡張だった筈なので使える環境(私はNetCOBOL)が限定されると思いますが、使えるものは使いましょう。
■ MOVE文
身も蓋もない話ですが、追加したい文字の長さがはっきりとわかっているなら、MOVE文でも同じことが出来ます。
* 文字列「ABC」をWK-STRINGに追加
MOVE "ABC" TO WK-STRING(1:3).
*
* 文字列「DEF」をWK-STRINGに追加
MOVE "DEF" TO WK-STRING(4:3).
*
* 文字列「GHI」をWK-STRINGに追加
MOVE "GHI" TO WK-STRING(7:3).
■ 後書き
COBOLに限った話ではありませんが、私がプログラムを組む時は出来るだけ変数を使わないように工夫します。
新規にプログラムを作っている時は、変数を多用しても頭の中にロジックが入っているので問題ないのですが、作ってから数年後にそれを見ると、変数の遷移を追うための手間が増えてしまいます。
というか、変数を多用するプログラマーが書いたプログラムは、高い確率でスパゲティプログラムになっている気がします。
投稿記事の一覧:http://harikofu.web.fc2.com/
--- blog end ---
スポンサードリンク


