- VBAでExcelのデータをCSVに出力したい
- 特定の範囲だけCSVに書き出したい
- 文字化けせずにCSVを出力したい
このような疑問にお答えします。
VBAでは、シート全体の出力から特定範囲の指定出力まで、柔軟にCSVファイルを作成できます。
本記事では基本のシート全体出力 → 範囲指定出力 → 文字コード設定の順に解説します。
まずは自分の用途に合ったコードを見つけてください。
シート全体をCSV出力する(基本)
まず最もシンプルな方法として、アクティブシート全体をCSV出力するコードを紹介します。
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出力する
シート全体ではなく、特定の範囲だけを出力したい場合は配列を使った方法が処理速度の面で優れています。
以下が結論となるコードです。
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 Sub1. 対象のセル情報を配列で取得
dataArray = ws.Range("A1:C10").Valueセルの値を一度に配列へ格納します。セルを1つずつ読み込む方法より大幅に処理が速いのが特徴です。
出力範囲を変えたい場合は "A1:C10" の部分を書き換えてください。
2. 出力CSVパスを設定
outputPath = ThisWorkbook.Path & "\output.csv"ThisWorkbook.Path はExcelファイルが保存されているフォルダのパスを返します。
この書き方にしておくと、Excelファイルと同じ場所にCSVが出力されます。
3. CSVファイル形式で出力
3-1. ファイルを開く
fileNum = FreeFile
Open outputPath For Output As #fileNumFreeFile で未使用のファイル番号を取得してからファイルを開きます。
3-2. データをCSV形式で書き込む
2重ループで行・列を順番に処理します。
3-3. ループ処理
For i = LBound(dataArray, 1) To UBound(dataArray, 1)
For j = LBound(dataArray, 2) To UBound(dataArray, 2)LBound / UBound で配列の開始・終了インデックスを取得しています。
3-4. セルの内容を型変換
cellValue = CStr(dataArray(i, j))配列の要素はVariant型なので、CStr() で文字列に変換します。
3-5. 「CSVファイルのお作法」に合わせる処理
If InStr(cellValue, ",") > 0 Or InStr(cellValue, """") > 0 Then
cellValue = """" & Replace(cellValue, """", """""") & """"
End Ifセルの値にカンマやダブルクォートが含まれる場合、そのままCSVに書くとデータが壊れます。ダブルクォートで囲む処理を入れることで正しいCSV形式を保てます。
3-6. CSVファイルに書き出す
Print #fileNum, outputLine1行分のデータをまとめてファイルに書き込みます。
3-7. ファイルを閉じる
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 を使います。
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 を使います。
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出力は用途によってコードが変わります。まず「シート全体の基本コード」を動かしてみて、必要に応じて範囲指定や文字コード指定を組み合わせてみてください。


コメント