VBAでUTF-8(BOMなし)でファイル保存する方法

VBAUTF-8でのファイルを扱うためにADODB.Streamを使用する際に、BOMなしで保存する場合に必要な処理。

前提条件

  • Microsoft Office (Excel 2010)
    • 2010以外でも同じ
  • 処理簡略化のため参照設定で「Microsoft AxtiveX Data Object 6.1 Library」を追加していること

処理内容

ADODB.Streamを使ってデータを追加するところまでは同じ。

Dim myStream As ADODB.Stream
Set myStream = New ADODB.Stream

myStream.Type = adTypeText
myStream.Charset = "UTF-8"
myStream.Open

myStream.WriteText "ほげほげ", adWriteLine
myStream.WriteText "もげもげ", adWriteLine
myStream.WriteText "そげそげ", adWriteLine

ファイルを保存する直前にBOMを削除する処理を追加。

Dim byteData() As Byte
myStream.Position = 0
myStream.Type = adTypeBinary
myStream.Position = 3
byteData = myStream.Read
myStream.Close
myStream.Open
myStream.Write byteData

簡単に仕組みを説明すると次のようなイメージ。

  1. バイナリデータを保持するバイト配列を用意する
  2. ストリームのカーソル位置を0バイト目(先頭)にする
  3. ストリームのデータタイプをバイナリに変更する
  4. ストリームのカーソル位置を3バイト目に変更する(BOMは先頭3バイトのデータなのでそれを飛ばす)
  5. 現在のカーソル位置以降のデータをすべてバイト配列に保持する
  6. 一旦ストリームを閉じる
  7. 再度ストリームを開く
  8. BOMを読み飛ばしたバイトデータをストリームに書き込む

あとは保存するなり好きにすればOK

myStream.SaveToFile "C:\Temp\myStream.dat", adSaveCreateOverWrite

SaveToFileの第2パラメーターは上書きするかどうかの指定。

adSaveCreateOverWrite 上書き保存(強制上書き)
adSaveCreateNotExist ファイルがなければ作成

上書き確認は別途Dir関数等でファイル有無をチェックしてください。

なお、adXXXX系の定数はVBEditorで参照設定をしないと調べるのもだるいので
参照設定をしておくことをオススメします。
(他の実行環境でも追加する必要があるかは別途検証します)