私が、会社の仕事を効率化するツールを書こうと思って帰ってきた週末のことです。異動になった元パートナーへの引継書も書かなければならないので忙しくなりそうです。そんな時のお話です。
ニョーボが、偉そうに聞いてきました。「ISAMってなあに」。
初級シスアドは通っているはずのニョーボなので当然知っているだろうと思い、ドラム缶の絵を描いて、索引域/データ域/あふれ域と輪切りにした説明をしました。
ああ、あれか、とすぐに納得しましたが様子が変です。「実は、いままで意識していなかったシステムでね、2000年対応が必要そうなのが見つかったの。誰が作ったかも良く分からないんだけどね、データはISAMで作ってあるってドキュメントにはあるの。全部打ち込み直すのも大変だからね、なんとか移行できないかねえ。」
そんなんISAMの仕様がわかんなければ出来るわけがない。第一、データだけ取り出してもプログラムどうすんのよ、と思いましたがこの辺のことは、全てその後の食糧事情に反映するので、夏ばて解消にお肉が食べたいなと思った以上仕方がありません。
だいたい、もらったファイルフォーマットを見ると日付は西暦4桁。2000年問題で移行すること無いんじゃないか。とはいうもののやはり問題がありそう。ソースプログラムは見せてもらえませんでしたが、使用機種と拡張子が".bas"らしいということからこれはQuickBasicで作られていると判断できます。Microsoftのホームページを見ると案の定「サポート対象外」。ならまあ対応の必要はありそうです。データ抽出くらいはなんとかやってやらないとだめかな。とはいうもののまず、ISAMの中身がわからなければ何もできません。バイナリエディタで開いて悩むこと数十分。どうやら、ファイルの後半の方にベタ打ちイメージでデータが並んでいるようです。制御文字等はありません。これならなんとかなりそうです。(はっきりいってあまりできのよいISAMの設計ではないと思います。)もっともデータがどこから始まっているかの判断をプログラムにやらせるのは大変そうです。ファイルを開けば一目瞭然ですがね。
ニョーボに「この手のファイルいくつあるの?」と聞くと「5つ」。じゃあ、手で分離したところで大したことはなさそうだ。このファイルの場合は日本語がないのでバイナリエディタが使える。
定番フリーウェアのBzエディタで(作者のc.mosさんありがとう)、元ファイルを読み込んで、終わりの方のデータ部分を選択した後、クリップボードにCopy。Bzをもう一つ立ち上げて新規ファイルにペースト。Saveすればおしまい。注意すべきことは、ペーストを普通のテキストエディタで行っても駄目だ(必ずバイナリエディタ上で行う)ということくらいかな。ここでできたベタ打ち固定長ファイルに改行コードを入れれば、私の使命は終わりです。おいしいご飯が待っています。しかし、次に来る要望はきまっています。「ねえ、これをCSVファイルにできない?」さらに来る要望もわかりきっています。「ねえ、あと4ファイルあるんだけど…。」かくして最初から汎用性を持たせたツールをつくることにしました。「ベタ打ち固定長ファイルを、任意の項目でCSVファイルに変換するプログラム」です。
ふんふん、指定したバイト数ごとにTStringListの生成、廃棄を繰り返し、項目ごとにADDして、Commatextで書き出す、Delphi使えばそんなに苦労せずに済みそうだな、と昼寝をしながらロジックを考えていましたが、目が覚めてからちょっと悩む。どんなデータが入っているかもわからない。元ファイルがテキストファイルと仮定するのは止めよう。かくして、バイナリで読み込んでバイナリファイルのまま改行コードを付加して、カンマで区切って、という仕様にしました。バイナリフィールドをCSVにしてどんな意味があるかというのは多少疑問の余地がありますが、少なくとも自分で作成したプログラムのなかで落ちることはありません。
しかし、この責任逃れのためにいろいろと苦労する羽目に陥りました。最初はTMemoryStreamを使ってパフォーマンスを稼ごうとしましたが、どうもうまくいかない。仕方なく使い慣れたBlockRead/Writeで書き直しましたが、区切りの","や改行コードを上手く書き出すことが出来ない。
やがて気がつきました。バイナリで書き出すはずのところ、ここだけキャラクタで書きだそうとしているのが間違っている。で、Byte型にASCII文字コードを代入してBlockWrite。これでよし。夕食は、ニンニクをたっぷりきかせた豚肉でした。