どうしても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だけど実証済のようだ。