シートの内容を UTF-8 の CSV で出力する(BOM の有無を選ぶ)

公開日:2026年10月4日 執筆:Takuya カテゴリ:ファイル・CSV

シートのデータを UTF-8 の CSV ファイルとして書き出すマクロです。取り込み先のシステムに合わせて BOM あり・なしを選べるようにし、カンマを含む値の囲み方も解説します。

どんな場面で使うか

Excel で作ったデータを、別のシステムや Web サービスに CSV で取り込む場面です。「名前を付けて保存」で CSV にすると文字コードが Shift_JIS になる場合や、取り込み先が「BOM なしの UTF-8」しか受け付けない場合に、マクロで出力すると確実です。

BOM とは

BOM は、UTF-8 のファイルの先頭に付く3バイトの目印です。Excel は BOM がある UTF-8 の CSV を正しく開けますが、システムによっては BOM を余計な文字として読み込み、1列目の見出しが一致しなくなるエラーを起こします。取り込み先の仕様を確認して、どちらで出力するかを決めます。

コード

シートの使用範囲をすべて CSV にします。値にカンマや改行、ダブルクォーテーションが含まれる場合は、値全体をダブルクォーテーションで囲み、中のダブルクォーテーションは2つ重ねます(CSV の一般的な決まりです)。

Function CsvField(ByVal v As Variant) As String
    Dim s As String
    s = CStr(v)
    If InStr(s, ",") > 0 Or InStr(s, """") > 0 Or InStr(s, vbLf) > 0 Then
        s = """" & Replace(s, """", """""") & """"
    End If
    CsvField = s
End Function

Sub ExportCsv(Optional ByVal withBom As Boolean = False)
    Dim ws As Worksheet, data As Variant, i As Long, j As Long
    Dim rowText As String, st As Object, bin As Object, path As String

    Set ws = ThisWorkbook.Worksheets("出力")
    data = ws.UsedRange.Value
    path = ThisWorkbook.Path & "\export_" & Format(Now, "yyyymmdd_hhnnss") & ".csv"

    Set st = CreateObject("ADODB.Stream")
    st.Type = 2: st.Charset = "UTF-8": st.Open
    For i = 1 To UBound(data, 1)
        rowText = ""
        For j = 1 To UBound(data, 2)
            If j > 1 Then rowText = rowText & ","
            rowText = rowText & CsvField(data(i, j))
        Next j
        st.WriteText rowText & vbCrLf
    Next i

    If withBom Then
        st.SaveToFile path, 2
    Else
        st.Position = 3                         ' 先頭の BOM(3バイト)を飛ばす
        Set bin = CreateObject("ADODB.Stream")
        bin.Type = 1: bin.Open
        st.CopyTo bin
        bin.SaveToFile path, 2
        bin.Close
    End If
    st.Close
    MsgBox "出力しました:" & path
End Sub

コードのポイント

ADODB.Stream で UTF-8 を指定して書き込むと、自動的に先頭に BOM が付きます。BOM なしで出力したいときは、Position を 3 にして先頭の3バイトを飛ばし、残りをバイナリのストリームにコピーして保存しています。

ファイル名に日時を付けているのは、前回の出力ファイルを上書きしないためです。毎回同じ名前で出力する必要がある場合は、SaveToFile の第2引数の 2(上書き)がそのまま使えます。

出力前に確認したいこと

UsedRange を使っているので、過去に使ったセルの書式が残っていると、空の行や列まで出力されます。出力用シートは毎回中身を消してから作るか、最終行・最終列を End で求めて範囲を指定してください。また、日付や金額は、セルの表示どおりではなく内部の値で出力されることがあるため、必要に応じて Format 関数で文字列にしてから出力します。

  • 取り込み先が求める文字コードと BOM の有無を確認する
  • 改行コード(CRLF か LF か)も仕様を確認する
  • 日付・数値の表記を Format でそろえる

※取り込み先システムの仕様は、システムの管理者やマニュアルで必ず確認してください。

ほかの記事