Excel VBAでUTF-8のテキストファイルを扱う(ADODB.Stream)

自分にとっての覚書です。

Excel VBAでテキストファイルを書き出すために、こんなマクロを組んでいました。

Dim n As Long
n = FreeFile
Open "C:\sample.html" For Output As #n
Print #n, "テキスト"
Close #n

けれど、この方法だと、できあがったテキストファイルの文字コードはShift-JISになります。
Excelのデータから大量にHTMLを生成するVBAを組もうと思っていたのですが、今回作成したいファイルの文字コードUTF-8
テキストファイルを作成した後に、文字コードを変換するという手も考えましたが、ひと手間増えてしまいます。どうにかならんかと検索してみたところ、VBA文字コードを指定してテキストファイルを読み書きするにはADODB.Streamを使えばよいということが分かりました。


[参考にしたサイト]

Stream オブジェクト
http://msdn.microsoft.com/ja-jp/library/cc364272.aspx#

ADODB.Streamでファイル読み込み@Excel マクロ・VBA
http://www.cocoaliz.com/excelVBA/index/41/

いろんな文字コードでファイルを読み書きするにはADODB.Stream
http://d.hatena.ne.jp/nacookan/20080222/1203689686



[実際に書いてみた]
まずは参照設定で「Microsoft ActiveX Data Objects」というものにチェックを入れておきます。
以下は、VBA初心者の自分が、テキストファイルを1行ずつ読み込んで配列に格納し、それをさらに別のテキストファイルに格納するコードを作ってみた例です。


ファイルの読み込み

'ファイルを読み込むための配列
Dim Arr()
ReDim Preserve Arr(0)

'オブジェクトを作成
Dim txt As Object
Set txt = CreateObject("ADODB.Stream")

'オブジェクトに保存するデータの種類を文字列型に指定する
txt.Type = adTypeText
'文字列型のオブジェクトの文字コードを指定する
txt.Charset = "UTF-8"

'オブジェクトのインスタンスを作成
txt.Open

'ファイルからデータを読み込む
txt.LoadFromFile ("c:\sample.html")

'最終行までループする
Do While Not txt.EOS
    '次の行を読み取る
    Arr(UBound(Arr)) = txt.ReadText(adReadLine)
    ReDim Preserve Arr(UBound(Arr) + 1)
Loop

'オブジェクトを閉じる
txt.Close

'メモリからオブジェクトを削除する
Set txt = Nothing


ファイルの書き込み

'オブジェクトを作成
Dim txt2 As Object
Set txt2 = CreateObject("ADODB.Stream")

'オブジェクトに保存するデータの種類を文字列型に指定する
txt2.Type = adTypeText
'文字列型のオブジェクトの文字コードを指定する
txt2.Charset = "UTF-8"

'オブジェクトのインスタンスを作成
txt2.Open

'配列をオブジェクトに書き込む
For Each sample In Arr
    '1行ずつ書き込む
    txt2.WriteText sample, adWriteLine
Next

'オブジェクトの内容をファイルに保存
txt2.SaveToFile ("c:\sample2.html"), adSaveCreateOverWrite

'オブジェクトを閉じる
txt2.Close

'メモリからオブジェクトを削除する
Set txt2 = Nothing


[ADODB.Streamのつたない解説]
(1)Typeプロパティ

'オブジェクトに保存するデータの種類を文字列型に指定する
txt.Type = adTypeText

Typeプロパティに、テキストデータを指定します。
adTypeTextはテキストデータで、バイナリはadTypeBinaryのようです。


(2)Chasetプロパティ

'文字列型のオブジェクトの文字コードを指定する
txt.Charset = "UTF-8"

Chasetプロパティに、UTF-8を指定します。
使用できる文字コードですが、MSDNには、利用できる値は、インターネット文字セット文字列としてインターフェイスで渡すことのできる通常の文字列です ("iso-8859-1"、"Windows-1252" など)。 とあります。
http://msdn.microsoft.com/ja-jp/library/cc364313.aspx


(3)Openメソッド

'オブジェクトのインスタンスを作成
txt.Open

オブジェクト.Open Source
SourceにVariant型の値を指定して開くようですが、Sourceを省略すると、メモリ内でオブジェクトのインスタンスが作成され、WriteTextメソッドやLoadFromFileメソッドを使用して動的にデータを追加することができるそうです。
・・・とMSDNに書いてあります。実はいまいち意味がつかめてないです・・・。
http://msdn.microsoft.com/ja-jp/library/cc364198.aspx


(4)LoadFromFileメソッド

'ファイルからデータを読み込む
txt.LoadFromFile ("c:\sample.html")

読み込むファイルを指定します。


(5)EOSプロパティ
(6)ReadTextメソッド

'最終行までループする
Do While Not txt.EOS
    '次の行を読み取る
    Arr(UBound(Arr)) = txt.ReadText(adReadLine)
    ReDim Preserve Arr(UBound(Arr) + 1)
Loop

EOSプロパティは、現在の位置がファイルの末尾であればTrue、そうでなければFalseを返します。
ReadText(読み取る文字数)でデータを読み取ります。
読み取る文字数は、Long型の値のほかに、以下が指定できます。

  • adReadLine・・・1行ずつ
  • adReadAll・・・すべて


(7)WriteTextメソッド

'配列をオブジェクトに書き込む
For Each sample In Arr
    '1行ずつ書き込む
    txt2.WriteText sample, adWriteLine
Next

オブジェクト.WriteText 文字列,オプション
文字列を書き込みます。
オプションは以下が指定できます。

  • adWriteChar・・・改行なし
  • adWriteLine・・・改行あり(LineSeparatorプロパティで設定、デフォルトはCRLF)


(8)SaveToFileメソッド

'オブジェクトの内容をファイルに保存
txt2.SaveToFile ("c:\sample2.html"), adSaveCreateOverWrite

書き込むファイルを指定します。オプションは以下が指定できます。
(実はこのオプションもよく理解できていない・・・)

  • adSaveCreateNotExist・・・ファイルがない場合に新規作成
  • adSaveCreateOverWrite・・・ファイルがある場合に上書き保存


(9)Closeメソッド

'オブジェクトを閉じる
txt.Close

オブジェクトを閉じます。


[まだ困ってること]
いろいろ調べていたのですがUTF-8をBOM無しにする方法が分からず、引き続き調査中。