VBAのメモ(未検証)~VBでJavaでも読めるUTF-8のファイルを作るには~

どうしてもVBAでUTF8のテキストを作る場合は、ADODB.Streamオブジェクトを利用すると良いらしい。
EXCELシートになってる仕様書からデータを抜いて、Linux系のサーバーにCSVファイルをアップしなければならない場合には便利かもしれない。
なお、こんな面倒なことをするよりは、EXCEL君にはWindows用にシフトJISでCSVファイルを作ってもらい、LinuxサーバーにPHPでテキストをアップするutf-8のコードページのHTMLからアップすればブラウザがコードページを都合良く変換してくれるので汎用で便利なことは云うまでもないし、FFFTPが使えるなら、コードページと改行コードをちゃんと変換してくれそうだが、最近はFTPで接続できないケースが普通なので、FFFTPっぽいPHPのページを作るのが一番だろう。

あると便利な定数

LineSeparator用のLineSeparatorsEnum

定数 説明
adCR 13 改行復帰を示します。
adCRLF -1 既定値です。改行復帰行送りを示します。
adLF 10 行送りを示します。

Typeプロパティ用のStreamTypeEnum

定数 説明
adTypeBinary 1 バイナリ データを表します。
adTypeText 2 既定値です。Charset で指定された文字セットにあるテキスト データを表します。

Openメソッド用のStreamOpenOptionsEnum

定数 説明
adOpenStreamAsync 1 非同期モードで Stream オブジェクトを開きます。
adOpenStreamFromRecord 4 Source パラメータの内容を、既に開かれている Record オブジェクトとして識別します。既定動作では、Source は、ツリー構造のノードを直接指定する URL として処理します。このノードに関連付けられた既定ストリームが開かれます。
adOpenStreamUnspecified -1 既定値です。既定オプションで Stream オブジェクトを開くことを指定します。

textWrite用のStreamWriteEnum 値

定数 説明
adWriteChar 0 既定値です。Stream オブジェクトに対して、Data パラメータで指定したテキスト文字列を書き込みます。
adWriteLine 1 Stream オブジェクトに、テキスト文字列と行区切り文字を書き込みます。LineSeparator プロパティが定義されていない場合は、実行時エラーを返します。

SaveToFile用のSaveOptionsEnum

定数 説明
adSaveCreateNotExist 1 既定値です。FileName パラメータで指定したファイルがない場合は新しいファイルが作成されます。
adSaveCreateOverWrite 2 FileName パラメータで指定したファイルがある場合は、現在開かれている Stream オブジェクトのデータでファイルが上書きされます。

使い方

Dim outStream As Object

Set  outStream = CreateObject(“ADODB.Stream”)

outStream.Type = adTypeText

outStream.charset = “utf-8″  ’規定値は”Unicode” すなわちJavaやJavaScriptと同じUnicode(16ビット)である。

outStream.LineSeparator = adLF ‘LinuxではLFのみがデフォ。

outStream.textWrite   <UTF-8で書き込みたいテキスト>, adWriteLine

outStream.SaveToFile  <ファイル名>, adSaveCreateOverWrite

outStream.Close

※注意

このままではファイルの先頭にUnicodeのテキストを意味する3バイトのBOMコードが付いてしまうので、Javaで読むと痛い目に逢う。

もしサクラエディタを使っているなら作ったファイルを開くと画面右下に「UTF-8 BOM付」と表記されているハズ。

「名前を変えて保存」することでBOMコードは勝手に消えるが、毎回それをやるのも面倒なので・・・
同じことをやればいい。(ハズ 未検証!

outStream.Open       ’SaveToFile で設定した内容を再利用可?

‘バイナリーモードに変え、

outStream.Type = adTypeBinary

‘ファイルの先頭から3バイトのBOMコ-ドを読み飛ばし、

outStream.position(3)

‘中身(UTF-8になっているテキストをバイナリ形式で)を吸い上げる。

Dim binaryData As Variant

binaryData = outStream.read

そして

outStream.Close

もう一度開き直す。

outStream.Open

outStream.Type = adTypeBinary

outStream.Write(binaryData)

outStream.SaveToFile, adSaveCreateOverWrite ’※これが余計な3バイトを消す。ハズ?

outStream.Close

とする。
一抹の不安は、本当にbinaryDataが文字化けしないのか?だが、これはやってみないと判らない(笑
なお、Openメソッドの説明文を読むとCloseしてもプロパティ設定を変更してもう一度開くことができます。と書いてあるのでOpenはオプションなしでOK。
adSaveCreateOverWrite がトランケートしてくれるのか心配なら、Closeした後に一旦ファイルを消すといい。
なお、元ネタはこっちのページ JavaScriptだけど実証済のようだ。




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA