MENU
\ お問い合わせはこちら! /

【Excel VBA】CSV出力する方法|シート全体・範囲指定・文字コード設定まで解説

  • VBAでExcelのデータをCSVに出力したい
  • 特定の範囲だけCSVに書き出したい
  • 文字化けせずにCSVを出力したい

このような疑問にお答えします。

VBAでは、シート全体の出力から特定範囲の指定出力まで、柔軟にCSVファイルを作成できます。

本記事では基本のシート全体出力 → 範囲指定出力 → 文字コード設定の順に解説します。

まずは自分の用途に合ったコードを見つけてください。

シート全体をCSV出力する(基本)

まず最もシンプルな方法として、アクティブシート全体をCSV出力するコードを紹介します。

VB
Public Sub ExportSheetToCSV()
    Dim ws As Worksheet
    Dim outputPath As String
    Dim fileNum As Integer
    Dim i As Long, j As Long
    Dim lastRow As Long, lastCol As Long
    Dim outputLine As String
    Dim cellValue As String

    Set ws = ThisWorkbook.ActiveSheet

    ' 最終行・最終列を取得
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column

    ' 出力先パスを設定(Excelファイルと同じフォルダ)
    outputPath = ThisWorkbook.Path & "\output.csv"

    fileNum = FreeFile
    Open outputPath For Output As #fileNum

    For i = 1 To lastRow
        outputLine = ""
        For j = 1 To lastCol
            cellValue = CStr(ws.Cells(i, j).Value)

            ' カンマ・ダブルクォートを含む場合はダブルクォートで囲む
            If InStr(cellValue, ",") > 0 Or InStr(cellValue, """") > 0 Then
                cellValue = """" & Replace(cellValue, """", """""") & """"
            End If

            outputLine = outputLine & cellValue
            If j < lastCol Then outputLine = outputLine & ","
        Next j
        Print #fileNum, outputLine
    Next i

    Close #fileNum
    MsgBox "CSV出力が完了しました。", vbInformation
End Sub

ポイント:

  • ActiveSheet を対象にしているので、どのシートでも使いまわせる
  • End(xlUp) / End(xlToLeft) でデータのある最終行・最終列を自動取得
  • カンマやダブルクォートを含むセルは自動でダブルクォートで囲む(CSV形式のルール)

特定のセルの範囲を読み込み、CSV出力する

シート全体ではなく、特定の範囲だけを出力したい場合は配列を使った方法が処理速度の面で優れています。

以下が結論となるコードです。

VB
Public Sub ExportRangeToCSV()
    On Error GoTo ErrorHandler

    Dim ws As Worksheet
    Dim outputPath As String
    Dim fileNum As Integer
    Dim i As Long, j As Long
    Dim dataArray As Variant
    Dim outputLine As String
    Dim cellValue As String

    ' 配列にデータを格納
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    dataArray = ws.Range("A1:C10").Value  ' 例: A1:C10 の範囲を出力

    ' 出力ファイルのパスを設定
    outputPath = ThisWorkbook.Path & "\output.csv"

    ' ファイルを開く
    fileNum = FreeFile
    Open outputPath For Output As #fileNum

    ' データを CSV 形式で書き込む
    For i = LBound(dataArray, 1) To UBound(dataArray, 1)
        outputLine = ""
        For j = LBound(dataArray, 2) To UBound(dataArray, 2)
            cellValue = CStr(dataArray(i, j))

            ' カンマを含む場合、ダブルクォートで囲む
            If InStr(cellValue, ",") > 0 Or InStr(cellValue, """") > 0 Then
                cellValue = """" & Replace(cellValue, """", """""") & """"
            End If

            ' 値を出力行に追加
            outputLine = outputLine & cellValue

            ' 最後の列以外はカンマを付ける
            If j < UBound(dataArray, 2) Then
                outputLine = outputLine & ","
            End If
        Next j

        ' 行を書き込む
        Print #fileNum, outputLine
    Next i

    ' ファイルを閉じる
    Close #fileNum

    MsgBox "CSV ファイルが正常に出力されました。", vbInformation
    Exit Sub

ErrorHandler:
    Dim err_message As String

    Select Case Err.Number
        Case 70
            err_message = "ファイルへのアクセス権限がありません。ファイルが他のプログラムで開かれていないか確認してください。"
        Case 75
            err_message = "指定されたファイルパスが無効です。パスの長さや形式を確認してください。"
        Case 76
            err_message = "指定されたパスが見つかりません。保存先のフォルダが存在するか確認してください。"
        Case 6
            err_message = "ファイルサイズが大きすぎる可能性があります。データ量を減らすか、分割して保存してください。"
        Case Else
            err_message = "予期せぬエラーが発生しました。" & vbNewLine & _
                          "エラー番号: " & Err.Number & vbNewLine & _
                          "エラーの説明: " & Err.Description
    End Select

    MsgBox err_message, vbCritical, "エラー"

    ' ファイルが開いている場合は閉じる
    On Error Resume Next
    Close #fileNum
    On Error GoTo 0
End Sub

1. 対象のセル情報を配列で取得

VB
dataArray = ws.Range("A1:C10").Value

セルの値を一度に配列へ格納します。セルを1つずつ読み込む方法より大幅に処理が速いのが特徴です。

出力範囲を変えたい場合は "A1:C10" の部分を書き換えてください。

2. 出力CSVパスを設定

VB
outputPath = ThisWorkbook.Path & "\output.csv"

ThisWorkbook.Path はExcelファイルが保存されているフォルダのパスを返します。

この書き方にしておくと、Excelファイルと同じ場所にCSVが出力されます。

3. CSVファイル形式で出力

3-1. ファイルを開く

VB
fileNum = FreeFile
Open outputPath For Output As #fileNum

FreeFile で未使用のファイル番号を取得してからファイルを開きます。

3-2. データをCSV形式で書き込む

2重ループで行・列を順番に処理します。

3-3. ループ処理

VB
For i = LBound(dataArray, 1) To UBound(dataArray, 1)
    For j = LBound(dataArray, 2) To UBound(dataArray, 2)

LBound / UBound で配列の開始・終了インデックスを取得しています。

3-4. セルの内容を型変換

VB
cellValue = CStr(dataArray(i, j))

配列の要素はVariant型なので、CStr() で文字列に変換します。

3-5. 「CSVファイルのお作法」に合わせる処理

VB
If InStr(cellValue, ",") > 0 Or InStr(cellValue, """") > 0 Then
    cellValue = """" & Replace(cellValue, """", """""") & """"
End If

セルの値にカンマやダブルクォートが含まれる場合、そのままCSVに書くとデータが壊れます。ダブルクォートで囲む処理を入れることで正しいCSV形式を保てます。

3-6. CSVファイルに書き出す

VB
Print #fileNum, outputLine

1行分のデータをまとめてファイルに書き込みます。

3-7. ファイルを閉じる

VB
Close #fileNum

処理が終わったら必ずファイルを閉じます。閉じ忘れるとファイルがロックされたままになります。

4. エラーハンドリング

アクセス権限エラー(70)・パス無効(75)・パス未発見(76)・サイズ超過(6)の4パターンに対応したメッセージを表示します。

エラー発生時はファイルを確実に閉じる処理も入れています。

文字コード(Shift-JIS / UTF-8)を指定してCSV出力する

VBAの標準的なファイル出力(Open ... For Output)はWindowsのデフォルト文字コードであるShift-JISでCSVを作成します。

Excelで開くだけなら問題ありませんが、Pythonや他のシステムに取り込む場合はUTF-8が求められることが多いです。

Shift-JIS で出力する(デフォルト)

Open outputPath For Output As #fileNum の標準コードがShift-JIS出力になります。

追加の設定は不要です。

UTF-8 で出力する(ADODB.Streamを使う)

UTF-8で出力したい場合は ADODB.Stream を使います。

VB
Public Sub ExportToCSV_UTF8()
    Dim ws As Worksheet
    Dim stream As Object
    Dim i As Long, j As Long
    Dim lastRow As Long, lastCol As Long
    Dim outputLine As String
    Dim cellValue As String
    Dim outputPath As String

    Set ws = ThisWorkbook.ActiveSheet
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
    outputPath = ThisWorkbook.Path & "\output_utf8.csv"

    ' ADODB.Streamを使ってUTF-8で書き込む
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 2           ' テキストモード
    stream.Charset = "UTF-8"
    stream.Open

    For i = 1 To lastRow
        outputLine = ""
        For j = 1 To lastCol
            cellValue = CStr(ws.Cells(i, j).Value)
            If InStr(cellValue, ",") > 0 Or InStr(cellValue, """") > 0 Then
                cellValue = """" & Replace(cellValue, """", """""") & """"
            End If
            outputLine = outputLine & cellValue
            If j < lastCol Then outputLine = outputLine & ","
        Next j
        stream.WriteText outputLine & vbCrLf
    Next i

    stream.SaveToFile outputPath, 2  ' 2 = 上書き保存
    stream.Close

    MsgBox "UTF-8でCSV出力しました。", vbInformation
End Sub

ポイント:

  • stream.Charset = "UTF-8" で文字コードを指定
  • BOM(バイト順マーク)なしのUTF-8で出力される
  • Excelで直接開くと文字化けする場合があるが、テキストエディタやPythonでは正常に読める

保存先をダイアログで指定する

出力先を毎回ダイアログで選びたい場合は Application.GetSaveAsFilename を使います。

VB
Public Sub ExportCSV_WithDialog()
    Dim outputPath As Variant
    Dim ws As Worksheet
    Dim fileNum As Integer
    Dim i As Long, j As Long
    Dim lastRow As Long, lastCol As Long
    Dim outputLine As String
    Dim cellValue As String

    ' 保存ダイアログを表示
    outputPath = Application.GetSaveAsFilename( _
        InitialFileName:="output.csv", _
        FileFilter:="CSVファイル (*.csv), *.csv", _
        Title:="CSV出力先を選択してください")

    ' キャンセル時は終了
    If outputPath = False Then
        MsgBox "キャンセルされました。", vbInformation
        Exit Sub
    End If

    Set ws = ThisWorkbook.ActiveSheet
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column

    fileNum = FreeFile
    Open outputPath For Output As #fileNum

    For i = 1 To lastRow
        outputLine = ""
        For j = 1 To lastCol
            cellValue = CStr(ws.Cells(i, j).Value)
            If InStr(cellValue, ",") > 0 Or InStr(cellValue, """") > 0 Then
                cellValue = """" & Replace(cellValue, """", """""") & """"
            End If
            outputLine = outputLine & cellValue
            If j < lastCol Then outputLine = outputLine & ","
        Next j
        Print #fileNum, outputLine
    Next i

    Close #fileNum
    MsgBox "CSV出力が完了しました。", vbInformation
End Sub

ユーザーが自由に保存先・ファイル名を決めたいケースに便利です。

まとめ

用途使うコード
シート全体をCSV出力(基本)ExportSheetToCSV
特定範囲だけCSV出力ExportRangeToCSV
UTF-8でCSV出力ExportToCSV_UTF8
保存先をダイアログで選ぶExportCSV_WithDialog

VBAのCSV出力は用途によってコードが変わります。まず「シート全体の基本コード」を動かしてみて、必要に応じて範囲指定や文字コード指定を組み合わせてみてください。

この記事が気に入ったら
フォローしてね!

シェア・記事の保存はこちら!

この記事を書いた人

基本、書くことで生計を立てています。
ITエンジニア歴は約5年ほど。
Pythonを書くことが多いですが、雑食です。
基本情報技術者試験合格。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)