Contents
この記事でできること
- VBAでExcelのデータ範囲をCSVファイルに自動書き出しできる
- 文字コード(UTF-8 / Shift_JIS)を指定して出力できる(実務版)
- 日付付きファイル名で上書きを防げる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(手作業CSV作成):
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「CSV」に変更
- 確認ダイアログに「はい」を2回クリック
- 文字コードが合っているか不安になる
- 基幹システムに取り込んで文字化け → やり直し
After(VBAで自動CSV出力):
- マクロを実行(またはボタンをクリック)
- 指定範囲のデータがCSVファイルに書き出される
- 文字コード指定済みなので文字化けしない
- 完了メッセージでファイル名を確認
自分も毎週、Excelの在庫データを基幹システムに取り込むためにCSVを手作業で作っていた。「名前を付けて保存→CSV選択→はい→はい」の手順が地味にめんどくさかった。VBAでCSV出力を自動化してからは、ボタン1つで完了。文字化けに悩まされることもなくなった。同じ手作業CSV作成をやっている人に、この記事でワンクリック化を体験してほしい。
「名前を付けて保存」でCSVを作ると、文字コードの制御ができない。VBAなら文字コードもファイル名も自由自在。
なお、複数ファイルのデータを1つにまとめてからCSV出力する場合は 複数Excelファイルを1つに統合 を参照。
実行前の準備
CSV保存先のフォルダを確認する
CSVを保存するフォルダのパスを確認しておく。エクスプローラーでフォルダを開き、アドレスバーからパスをコピーするのが確実。
例: C:\Users\tanaka\Documents\CSV出力
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
シート構成を確認する
このコードは以下のシート構成を前提としている:
- シート名「データ」に出力対象のデータがある
- 1行目はヘッダー(CSVにも出力される)
- A列〜D列がデータ範囲(書き換え可能)
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
Alt + F8→ マクロ名を選んで「実行」
ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。
コード(最小版)– ExcelデータをCSVに書き出し
'============================================================
' ■ ExcelデータをCSVに書き出し(最小版)
' → 指定シートのデータ範囲をカンマ区切りで出力
' → 文字コードは Shift_JIS(Windows標準)
'============================================================
Sub ExportToCSVMinimal()
'--- ★書き換えポイント ---
Dim sheetName As String
sheetName = "データ" '← 出力対象のシート名
Dim startCol As Long
startCol = 1 '← 開始列(1=A列)
Dim endCol As Long
endCol = 4 '← 終了列(4=D列)
Dim filePath As String
filePath = "C:\Users\tanaka\Documents\CSV出力\data.csv" '← 保存先
'--- ★ここまで ---
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(sheetName)
'--- 最終行を取得
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, startCol).End(xlUp).Row
If lastRow < 1 Then
MsgBox "出力するデータがありません。", vbExclamation
Exit Sub
End If
'--- CSVファイルを開く
Dim fileNum As Integer
fileNum = FreeFile
Open filePath For Output As #fileNum
'--- 1行ずつ書き出し
Dim i As Long, j As Long
Dim line As String
Dim cellValue As String
For i = 1 To lastRow
line = ""
For j = startCol To endCol
cellValue = CStr(ws.Cells(i, j).Value)
'--- カンマやダブルクォートを含む場合の処理
If InStr(cellValue, ",") > 0 Or _
InStr(cellValue, """") > 0 Or _
InStr(cellValue, vbLf) > 0 Then
cellValue = """" & Replace(cellValue, """", """""") & """"
End If
If j > startCol Then line = line & ","
line = line & cellValue
Next j
Print #fileNum, line
Next i
Close #fileNum
MsgBox lastRow & " 行のデータをCSVに書き出しました。" & vbCrLf & _
"保存先: " & filePath, vbInformation
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
sheetName |
出力対象のシート名 | "データ" |
startCol / endCol |
出力する列範囲(列番号) | 1(A列)〜 4(D列) |
filePath |
CSVの保存先フルパス | "C:\Users\tanaka\Documents\CSV出力\data.csv" |
コードの流れ
- 対象シートの最終行を取得
Open ... For OutputでCSVファイルを新規作成- 1行ずつループし、各セルの値をカンマで連結
- カンマ・ダブルクォート・改行を含むセルはダブルクォートで囲む
Print #で1行ずつ書き込みCloseでファイルを閉じる
重要: Open ... For Output は既存ファイルを上書きする。追記したい場合は For Append に変更する。Dir関数でファイル操作する方法は フォルダ内ファイル一覧を自動取得 も参照。
コード(実務版)– 文字コード指定+日付付きファイル名で保存
実務では「基幹システムがUTF-8を要求する」「毎回異なるファイル名で保存したい」ケースが多い。ADODB.Streamで文字コードを指定し、日付付きファイル名で保存する。
ADODB.StreamでUTF-8出力に統一してからは、文字化けトラブルがゼロになった。システム担当に怒られることもなくなった。
'============================================================
' ■ CSV書き出し — UTF-8対応+日付付きファイル名(実務版)
' → ADODB.Stream で文字コードを指定(UTF-8 BOM付き)
' → ファイル名に日付を入れて上書き防止
'============================================================
Sub ExportToCSVAdvanced()
'--- ★書き換えポイント ---
Dim sheetName As String
sheetName = "データ" '← 出力対象のシート名
Dim startCol As Long
startCol = 1 '← 開始列(1=A列)
Dim endCol As Long
endCol = 4 '← 終了列(4=D列)
Dim saveFolderPath As String
saveFolderPath = "C:\Users\tanaka\Documents\CSV出力\" '← 保存先フォルダ
Dim filePrefix As String
filePrefix = "data" '← ファイル名の先頭部分
Dim charSet As String
charSet = "UTF-8" '← 文字コード("UTF-8" or "Shift_JIS")
'--- ★ここまで ---
'--- パスの末尾に \ を付ける
If Right(saveFolderPath, 1) <> "\" Then saveFolderPath = saveFolderPath & "\"
'--- 保存先フォルダの存在確認
If Dir(saveFolderPath, vbDirectory) = "" Then
MsgBox "保存先フォルダが見つかりません。" & vbCrLf & _
saveFolderPath, vbExclamation
Exit Sub
End If
'--- 日付付きファイル名を生成
Dim filePath As String
filePath = saveFolderPath & filePrefix & "_" & Format(Date, "yyyyMMdd") & ".csv"
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(sheetName)
'--- 最終行を取得
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, startCol).End(xlUp).Row
If lastRow < 1 Then
MsgBox "出力するデータがありません。", vbExclamation
Exit Sub
End If
'--- ADODB.Stream でCSV書き出し
Dim stream As Object
Set stream = CreateObject("ADODB.Stream")
stream.Type = 2 '← adTypeText(テキストモード)
stream.charSet = charSet
stream.Open
'--- 1行ずつ書き出し
Dim i As Long, j As Long
Dim line As String
Dim cellValue As String
For i = 1 To lastRow
line = ""
For j = startCol To endCol
cellValue = CStr(ws.Cells(i, j).Value)
'--- カンマ・ダブルクォート・改行を含む場合の処理
If InStr(cellValue, ",") > 0 Or _
InStr(cellValue, """") > 0 Or _
InStr(cellValue, vbLf) > 0 Then
cellValue = """" & Replace(cellValue, """", """""") & """"
End If
If j > startCol Then line = line & ","
line = line & cellValue
Next j
stream.WriteText line, 1 '← 1 = adWriteLine(改行付き)
Next i
'--- ファイルに保存
stream.SaveToFile filePath, 2 '← 2 = adSaveCreateOverWrite
stream.Close
Set stream = Nothing
MsgBox lastRow & " 行のデータをCSVに書き出しました。" & vbCrLf & _
"保存先: " & filePath & vbCrLf & _
"文字コード: " & charSet, vbInformation
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
sheetName |
出力対象のシート名 | "データ" |
startCol / endCol |
出力する列範囲 | 1〜4 |
saveFolderPath |
保存先フォルダ | "C:\Users\tanaka\Documents\CSV出力\" |
filePrefix |
ファイル名の先頭部分 | "data" |
charSet |
文字コード | "UTF-8"("Shift_JIS" に変更可) |
コードの流れ
- 保存先確認: フォルダの存在をチェック
- 日付付きファイル名:
data_20260308.csv形式で自動生成 - ADODB.Stream生成:
CreateObjectで参照設定不要 - 文字コード指定:
.Charset = "UTF-8"で指定 - 行ごとの書き出し: カンマ・ダブルクォート・改行の特殊処理付き
- ファイル保存:
SaveToFileで書き出し
CSV出力マクロをボタン(マクロをボタン1つで実行する方法)に割り当てれば、毎週のCSV作成がボタン1つで完了する。
よくある落とし穴5選
1. 文字コード違いで文字化けする
自分もこれで30分溶かした。Shift_JISで出力したCSVをUTF-8前提のシステムに取り込んだら、全角文字が全部文字化け。原因に気づくまで「データが壊れた?」と焦った。
対策: 取り込み先のシステムが要求する文字コードを確認し、実務版コードの charSet を合わせる。迷ったらUTF-8が無難。
2. セル内のカンマでCSVの列がずれる
原因: セルの値に , が含まれていると、CSVのカラム区切りと誤認される。
対策: コード内でカンマを含む値をダブルクォートで囲む処理を入れている。この処理を外すと列ずれが発生する。
3. 同名ファイルが上書きされる
原因: 最小版では filePath が固定のため、実行するたびに上書きされる。
対策: 実務版のように日付付きファイル名にする。同日に複数回出力する場合は時刻も追加する:Format(Now, "yyyyMMdd_HHmmss")
4. 数値の先頭ゼロが消える
原因: CSVをExcelで開くと、0001 が 1 に変換される。これはExcelの仕様でVBA側の問題ではない。
対策: VBAでの出力時には先頭ゼロは保持される。CSVを確認するときはメモ帳やテキストエディタで開くと正確に見える。
5. 保存先フォルダが存在せずエラーになる
原因: filePath に指定したフォルダが存在しない。
対策: 実務版では Dir でフォルダの存在を確認している。存在しない場合はメッセージを出して処理を止める。
FAQ
Q1: ヘッダー行を出力しない場合
ループの開始行を変更する:
For i = 2 To lastRow '← 1 を 2 に変えるとヘッダーをスキップ
Q2: タブ区切り(TSV)で出力したい
カンマの代わりにタブ文字 vbTab を使う:
If j > startCol Then line = line & vbTab '← "," を vbTab に変更
Q3: 特定の列だけ出力したい
出力する列番号を配列で指定する:
Dim cols As Variant
cols = Array(1, 3, 5) '← A列, C列, E列だけ出力
For j = LBound(cols) To UBound(cols)
cellValue = CStr(ws.Cells(i, cols(j)).Value)
'--- 以降同様
Next j
Q4: CSV出力後にメールで送りたい
CSV添付でメールを作成できる。Excelからメール自動作成(Outlook連携) を参照。
Q5: ボタン1つでCSV出力を実行したい
マクロをボタン1つで実行する方法 で ExportToCSVAdvanced をボタンに割り当てる。
まとめ
Open/Print#でExcelデータをCSVに書き出せる(最小版・Shift_JIS)ADODB.Streamで文字コードを指定してCSV出力できる(実務版・UTF-8対応)- カンマ・ダブルクォート・改行を含むセルの処理が重要
- 日付付きファイル名で上書きを防止する
関連記事
- フォルダ内のファイルを日付フォルダに自動バックアップ — CSV出力前にバックアップ
- ExcelファイルをPDFに一括変換 — CSV出力 vs PDF出力の使い分け
- マクロをボタン1つで実行する方法 — CSV出力マクロをボタンに割り当て
次にやりたくなること
- Excelからメール自動作成(Outlook連携): CSV添付でメール送信。データ連携を完全自動化
- 一覧表からExcelテンプレートに差し込み印刷: 一覧表データの別の活用法。帳票作成も自動化
もっとカスタマイズしたい場合
「出力項目を条件で絞りたい」「複数シートをまとめてCSV化したい」「BOMなしUTF-8で出力したい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。
相談時に伝えると話が早い情報:
- Excel のバージョン / OS
- 出力対象のデータの列数と行数の目安
- 取り込み先のシステムが要求する文字コード
- ファイル名のルール(日付・連番など)


コメント