完成イメージ(Before / After)
Before(手作業でCSV保存)

| A | B | C | |
|---|---|---|---|
| 1 | ロット番号 | スペック名 | 測定値 |
| 2 | 001 | ラインA | 15.2 |
| 3 | 002 | ラインA | 14.8 |
| 4 | 003 | ラインB | 15.0 |
毎回「名前を付けて保存→CSV」を手動で実行。文字コードの指定ができず文字化けリスクあり。
After(VBAで自動CSV出力)

| A | B | C | |
|---|---|---|---|
| 1 | ロット番号 | スペック名 | 測定値 |
| 2 | 001 | ラインA | 15.2 |
| 3 | 002 | ラインA | 14.8 |
| 4 | 003 | ラインB | 15.0 |
ボタン1つでUTF-8のCSVが出力される。日付付きファイル名(例: 検査データ_20260418.csv)で自動保存。
他システムにデータを渡すたびに、手作業でCSVに変換していた。文字化けして戻されることもあって地味にストレスだった。VBAでUTF-8対応の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でファイルを閉じる
最小版のコードで注目してほしいのは、カンマ・ダブルクォート・改行を含むセルの処理だ。CSVはカンマで列を区切る形式なので、セルの値自体にカンマが含まれていると列がずれてしまう。そこで、カンマや改行を含む値はダブルクォートで囲む(RFC 4180準拠)。さらに値の中にダブルクォートがある場合は "" にエスケープする。なぜこの処理が必要かというと、これを省略すると取り込み先のシステムでCSVが正しくパースされず、データが壊れるからだ。
FreeFile はVBAが空いているファイル番号を自動で割り当ててくれる関数だ。固定の番号(#1 など)を使うと、他の処理でファイルを開いている場合に競合する。FreeFile を使う癖をつけておけば安全だ。
重要: Open ... For Output は既存ファイルを上書きする。追記したい場合は For Append に変更する。Dir関数でファイル操作する方法は フォルダ内ファイル一覧を自動取得 も参照。
—
コード(実務版)– 文字コード指定+日付付きファイル名で保存
実務では「基幹システムがUTF-8を要求する」「毎回異なるファイル名で保存したい」ケースが多い。ADODB.Streamで文字コードを指定し、日付付きファイル名で保存する。
ADODB.StreamでUTF-8出力に統一してからは、文字化けトラブルがゼロになった。システム担当に怒られることもなくなった。CSV出力先のファイル管理には フォルダ内ファイル一覧を自動取得 も役立つ。
'============================================================
' ■ 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 が固定のため、実行するたびに上書きされる。
自分も過去のCSVを上書きしてしまい、先週分のデータを失ったことがある。それ以来、日付付きファイル名を使うようにした。
対策: 実務版のように日付付きファイル名にする。同日に複数回出力する場合は時刻も追加する:Format(Now, "yyyyMMdd_HHmmss")
4. 数値の先頭ゼロが消える
原因: CSVをExcelで開くと、0001 が 1 に変換される。これはExcelの仕様でVBA側の問題ではない。
対策: VBAでの出力時には先頭ゼロは保持される。CSVを確認するときはメモ帳やテキストエディタで開くと正確に見える。
5. 保存先フォルダが存在せずエラーになる
原因: filePath に指定したフォルダが存在しない。
対策: 実務版では Dir でフォルダの存在を確認している。存在しない場合はメッセージを出して処理を止める。
VBAでCSV出力すると文字化けするときの対処法
「VBAで書き出したCSVを基幹システムに取り込んだら全角文字が文字化けした」という場合、原因は文字コードの不一致だ。最小版の Open ... For Output はShift_JIS(Windows標準)で出力するが、取り込み先がUTF-8を要求していると文字化けする。対処法は実務版の ADODB.Stream を使い、.Charset = "UTF-8" で文字コードを明示的に指定すること。逆にShift_JISが必要な場合は .Charset = "Shift_JIS" にすればよい。自分もShift_JISで出力したCSVをUTF-8前提のWebシステムに取り込んで全滅した経験がある。取り込み先の仕様書で文字コードを確認してから出力するのが鉄則だ。
VBAのCSV出力でカンマを含むデータが壊れるときの対処法
「セルの値にカンマが入っていると、CSV取り込み時に列がずれてデータが壊れる」という場合、原因はカンマを含む値をダブルクォートで囲んでいないことだ。CSVはカンマで列を区切るフォーマットなので、値自体にカンマがあるとカラム区切りと誤認される。対処法はカンマ・ダブルクォート・改行を含む値を """" & Replace(cellValue, """", """""") & """" でダブルクォートで囲みエスケープすること。最小版・実務版のコードにはこの処理が組み込み済みなので、そのままコピペすれば安全にCSV出力できる。住所や備考欄にカンマが入りがちなので、CSV出力時には必ずこのエスケープ処理を入れておくべきだ。
—
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出力は「他システムとの橋渡し」になる重要な処理だ。最小版で基本的な書き出しの仕組みを理解したら、実務版でUTF-8対応と日付付きファイル名を導入してほしい。一度セットアップすれば、毎回の「名前を付けて保存→CSV→文字コード確認」という手作業がゼロになる。自分の場合、毎週金曜に在庫データをCSV出力して基幹システムに取り込む作業があったが、VBA化してからは出力ボタンを押すだけで文字コード指定済みのCSVが生成されるようになった。取り込み先で文字化けしないかヒヤヒヤする必要もない。CSV出力は地味だが、一度仕組みを作れば毎週・毎月の定型作業が確実に楽になる処理だ。なお、CSV出力先のフォルダが存在しない場合にエラーで止まるのはよくあるトラブルだ。実務版のようにDir関数で事前チェックする方法に加えて、ファイルやフォルダの存在確認で紹介しているMakeDirパターンを組み込めば、フォルダがなければ自動作成→CSVを出力、という流れが作れる。出力するデータに空白行が混ざっている場合は、空白行の一括削除で事前にクリーニングしておくとCSVの品質が上がる。ブックの保存と組み合わせれば、CSV出力後にExcelブックも自動保存する運用が作れる。マクロの実行結果を記録したい場合は実行ログの導入も検討してみてほしい。
関連記事
- フォルダ内のファイルを日付フォルダに自動バックアップ — CSV出力前にバックアップ
- ExcelファイルをPDFに一括変換 — CSV出力 vs PDF出力の使い分け
- マクロをボタン1つで実行する方法 — CSV出力マクロをボタンに割り当て
—
次にやりたくなること
- 複数Excelファイルを1つに統合: 複数ファイルのデータを統合してからCSV出力。散らばったデータを1つのCSVにまとめたいときに
- フォルダ内ファイル一覧を自動取得: CSV出力先のファイル管理に。過去の出力ファイルを一覧化して整理できる
- マクロをボタン1つで実行する方法: CSV出力をボタン化。毎週の定型作業を完全にワンクリック化
—


コメント