Think Twice
IT技術メモ | VBAのメモ
Created: 2021-06-24 / Updated: 2021-06-24

VBAでテキストファイルをUTF-8(BOMなし)で書き出す


目次


ADODB.Streamを利用して普通にやるとUTF-8(BOM付き)になってしまう

ADODB.Streamでは、Charsetプロパティで文字コードを指定できるのですが、これをUTF-8と指定してもUTF-8 BOM付きとなってしまいます。
以下はUTF-8 BOM付きで書き出されてしまうサンプルコードです。

UTF-8(BOM付き)で書き出されてしまう
Copy
Sub output_utf8_1()
    ' [参照設定] Microsoft ActiveX Data Objects 6.1 Library
    Dim p_stream As ADODB.Stream
    Set p_stream = New ADODB.Stream
    
    ' 初期設定
    With p_stream
        .Charset = "UTF-8" ' これだけだと UTF-8BOM付き になる…
        .Type = ADODB.StreamTypeEnum.adTypeText
        .LineSeparator = LineSeparatorEnum.adLF
    End With
    
    ' 書き込み
    With p_stream
        .Open
        .WriteText "abc", ADODB.StreamWriteEnum.adWriteLine
        .WriteText "1234", ADODB.StreamWriteEnum.adWriteLine
        .WriteText "あいうえお", ADODB.StreamWriteEnum.adWriteLine
        .SaveToFile "C:\temp\UTF-8BOM付き.txt", ADODB.SaveOptionsEnum.adSaveCreateOverWrite
        .Close
    End With
End Sub

出力結果

ADODB.Streamを利用してUTF-8(BOMなし)で書き出す

UTF-8BOM0xEF,0xBB,0xBFという3バイトの並びがファイルの先頭に付いているものなので、これを除去できればBOMなしにできます。
ということで、基本的には、UTF-8 BOM付きで出力する内容の書き込みをする部分まで行った後に、
先頭のBOM部分の3バイトを除去する処理を追加することで、UTF-8 BOMなしで書き出すことを実現しています。

UTF-8(BOMなし)で書き出す
Copy
Sub output_utf8_2()
    ' [参照設定] Microsoft ActiveX Data Objects 6.1 Library
    Dim p_stream As ADODB.Stream
    Set p_stream = New ADODB.Stream
    
    ' 初期設定
    With p_stream
        .Charset = "UTF-8" ' これだけだと UTF-8BOM付き になる…
        .Type = ADODB.StreamTypeEnum.adTypeText
        .LineSeparator = LineSeparatorEnum.adLF
    End With
    
    ' 書き込み
    With p_stream
        .Open
        .WriteText "abc", ADODB.StreamWriteEnum.adWriteLine
        .WriteText "1234", ADODB.StreamWriteEnum.adWriteLine
        .WriteText "あいうえお", ADODB.StreamWriteEnum.adWriteLine

        ' ---------- ここから ----------

        ' タイプをバイナリにして、先頭の3バイトをスキップ
        .Position = 0
        .Type = ADODB.StreamTypeEnum.adTypeBinary ' タイプ変更するにはPosition = 0である必要がある
        .Position = 3
        ' 一時格納用
        Dim p_byteData() As Byte
        p_byteData = .Read
        .Close ' 一旦閉じて
        .Open ' 再度開いて
        .Write p_byteData ' ストリームに書き込む

        ' ---------- ここまで を追加 ----------
        
        .SaveToFile "C:\temp\UTF-8BOMなし.txt", ADODB.SaveOptionsEnum.adSaveCreateOverWrite
        .Close
    End With
End Sub

出力結果


参考

参考

ソース