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無しにする方法が分からず、引き続き調査中。