お疲れさまです、みやもとです。
先日参加したLTイベントでCOBOLの思い出話をした際、参加者の方からCOBOLのコンバートツールがあることを教えていただきました。
1日あたり最大5回まで無料で使用可能だそう。
IBMがAIを使ったCOBOL-Javaのコンバートツールを作っていることは聞いていましたが、Web上にもあるとは知りませんでした。
COBOLシステムの移管については長らく問題と言われながらもなかなか進んでいないと聞きます。
こういうコンバートツールが手軽に使えるようになれば希望があるのでは。
せっかく見つけたからには試してみたいということで、簡単なCOBOLのコードをコンバートしてみることにしました。
みやもとが最後にCOBOLやってから5年以上経過しており結構うろ覚えになっているので、間違いがあればそっと教えていただけると幸いです。
変換元のコードを作る
今回はベースとなるコードをClaudeに作ってもらって、細かいところをちょろっと直したものを使います。
手打ちで命令文は何桁目…とかDivisionの定義はこの順番…とかやっていくのも復習としてはいいかと思いましたが、コードを書くこと自体よりコンバートツールを試してみるのがメイン目的なので楽できるところは楽することにしました。
IDENTIFICATION DIVISION.
PROGRAM-ID. DATA-AGGREGATION.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE ASSIGN TO INFILE
ORGANIZATION IS LINE SEQUENTIAL.
SELECT OUTPUT-FILE ASSIGN TO OUTFILE
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD INPUT-FILE.
01 INPUT-RECORD.
05 INPUT-ID PIC 9(10).
05 INPUT-NAME PIC G(10) USAGE DISPLAY-1.
05 INPUT-DATE.
07 INPUT-YEAR PIC 9(04).
07 INPUT-MONTH PIC 9(02).
07 INPUT-DAY PIC 9(02).
05 INPUT-AMOUNT PIC S9(13) USAGE COMP-3.
FD OUTPUT-FILE.
01 OUTPUT-RECORD.
05 OUTPUT-ID PIC 9(10).
05 OUTPUT-YEAR PIC 9(4).
05 OUTPUT-TOTAL-AMOUNT PIC S9(15) USAGE COMP-3.
WORKING-STORAGE SECTION.
01 WS-EOF PIC X VALUE 'N'.
01 WS-CURRENT-ID PIC 9(10) VALUE ZERO.
01 WS-CURRENT-YEAR PIC 9(4) VALUE ZERO.
01 WS-TOTAL-AMOUNT PIC S9(15) USAGE COMP-3 VALUE ZERO.
01 WS-FIRST-RECORD PIC X VALUE 'Y'.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
PERFORM INITIALIZE-PROCESS
PERFORM PROCESS-FILE
PERFORM CLOSE-FILES
STOP RUN.
INITIALIZE-PROCESS.
OPEN INPUT INPUT-FILE
OUTPUT OUTPUT-FILE.
PROCESS-FILE.
PERFORM READ-RECORDS.
PERFORM WRITE-FINAL-OUTPUT.
CLOSE-FILES.
CLOSE INPUT-FILE
OUTPUT-FILE.
READ-RECORDS.
PERFORM UNTIL WS-EOF = 'Y'
READ INPUT-FILE
AT END
MOVE 'Y' TO WS-EOF
NOT AT END
PERFORM PROCESS-RECORD
END-READ
END-PERFORM.
PROCESS-RECORD.
IF WS-FIRST-RECORD = 'Y'
MOVE 'N' TO WS-FIRST-RECORD
MOVE INPUT-ID TO WS-CURRENT-ID
MOVE INPUT-YEAR TO WS-CURRENT-YEAR
END-IF.
IF WS-CURRENT-ID NOT EQUAL INPUT-ID OR
WS-CURRENT-YEAR NOT EQUAL INPUT-YEAR
PERFORM WRITE-OUTPUT
MOVE INPUT-ID TO WS-CURRENT-ID
MOVE INPUT-YEAR TO WS-CURRENT-YEAR
MOVE ZERO TO WS-TOTAL-AMOUNT
END-IF.
ADD INPUT-AMOUNT TO WS-TOTAL-AMOUNT.
WRITE-OUTPUT.
IF WS-TOTAL-AMOUNT NOT EQUAL ZERO
MOVE WS-CURRENT-ID TO OUTPUT-ID
MOVE WS-CURRENT-YEAR TO OUTPUT-YEAR
MOVE WS-TOTAL-AMOUNT TO OUTPUT-TOTAL-AMOUNT
WRITE OUTPUT-RECORD
END-IF.
WRITE-FINAL-OUTPUT.
PERFORM WRITE-OUTPUT.
IDと年で集計して出力する処理にしています。
データ型は過去の現場で実際に見た(ような記憶がある)DISPLAY-1とかCOMP-3とかを使ってどう変換されるのかを見てみることにしました。
ではさっそく使ってみましょう。
コンバートできる言語が多い
ここでConvert code from COBOLのサイトを見てみます。
種類が多い!
画像に収まっていませんが、ほかにもVB.NETとかありました。
とりあえず今日は私がCOBOL以外に仕事で使っている言語ということで、Javaにしてみようと思います。
Javaのアイコンをクリックしてコードを貼り付けます。
Convertをクリックしてしばらく待つと…
ちゃんと処理が出力されました。
コンバート後のコードについて
では、実際に出力されたコードを見ていきます。
(生成されたコードについてはどこまで載せてOKなのかがちょっとよくわからなかったので、全体を見た感想と気になった点を一部抜粋して書かせていただきます。)
コンバート後のコードについては、ファイルのオープン・クローズ等の一部処理は空になっていました。
このへんは実際の環境に合わせて書いてね、ということでしょう。
一部追加で書かないといけない処理があるとはいえ、ざっくり読んだ感じ処理の流れは合っていました。
コンバートにかかる時間も体感1十数秒程度で、直接COBOLを書き換える手間を考えればすごくお手軽。
ただ、主に項目定義とか出力形式とかがちょこちょこ気になる…。
コンマ区切り前提
COBOL側の項目定義部分に戻ります。
01 INPUT-RECORD.
05 INPUT-ID PIC 9(10).
05 INPUT-NAME PIC G(10) USAGE DISPLAY-1.
05 INPUT-DATE.
07 INPUT-YEAR PIC 9(04).
07 INPUT-MONTH PIC 9(02).
07 INPUT-DAY PIC 9(02).
05 INPUT-AMOUNT PIC S9(13) USAGE COMP-3.
私が現場で見たプログラムの多くは固定長データを扱うものでした。
項目も桁数(バイト数)で区切られていて、項目と項目の間に区切り文字が入っているのは稀だったと記憶しています。
しかし、コンバート後のコードではコンマで区切られている前提で変数に格納していました。
private static void readRecords(String line) {
// Assuming line is formatted correctly
String[] fields = line.split(",");
int inputID = Integer.parseInt(fields[0].trim());
int inputYear = Integer.parseInt(fields[1].trim());
long inputAmount = Long.parseLong(fields[2].trim());
processRecord(inputID, inputYear, inputAmount);
}
処理の流れとしては同じなのですが、同じ形式のデータを処理するプログラムになっているかというと違うような…。
パック10進数
COMP-3で定義しているのはパック10進数という形式です。
1桁1バイト(8ビット)で数字を表すゾーン10進数に対して、1桁を4ビットで数字を表すためデータ容量を少なくすることができます。
金融系等大きな金額をデータとして扱うことが多い場合に重宝したのか、金額項目はたいていCOMP-3が切られていました。
パック10進数がJavaでどういうふうに置き換えられるのかちょっと興味深かったのですが、コンバート先では単にparseLongで処理されていました。
やっぱりCOBOLと同じデータを使って処理することは想定されていないようです。
どのみち私の過去の現場は基本的にネット環境に接続されていなかったので、環境が変わっていない限りは使おうにも使えませんが…。
使った感想
コンバートツールと聞いて「コンバート元の処理をそのまま置き換えて同じインプットデータを処理できるコードにする」というイメージだったのですが2、CodeConvertAIはあくまで同じ処理をする別言語のプログラムを作るツールのようでした。
習得済み言語で書いたコードを置き換えて、勉強したい言語のイメージをつかむとかに使うと良さそうかなと思いました。