ExcelマクロでCSVファイルを自動的にインポート・エクスポートできれば、毎日の手作業を大幅に削減できます。本記事では、実務でそのまま使えるVBAコードを交えながら、CSVの読み込み・書き出し・エラー対処まで徹底解説します。「実行時エラー 1004」「実行時エラー 53」など現場でよく遭遇するエラー番号の原因と解決策も網羅しているため、初めてマクロに触れる方から中級者まで役立つ内容になっています。
目次
- CSVとExcelマクロを組み合わせるメリット
- 事前準備:VBAエディタの起動と設定
- CSVをExcelに自動インポートする基本コード
- 実務向け:文字コード・区切り文字に対応したインポート
- ExcelシートをCSVとして自動エクスポートするコード
- フォルダ内の複数CSVを一括取り込む方法
- 実行時エラー番号一覧と解決策
- 実務で使えるテクニック集
- まとめ
CSVとExcelマクロを組み合わせるメリット
CSVファイルはシステム間のデータ連携でもっとも広く使われるフォーマットです。基幹システムからのエクスポート、ECサイトの注文データ、経費精算ツールの出力など、業務の至るところにCSVが登場します。しかしExcelで手動インポートを繰り返すと、次のような問題が生じます。
- テキストインポートウィザードを毎回操作する手間がかかる
- 電話番号や商品コードなど先頭ゼロが自動で消えてしまう
- 文字コードのミスマッチでデータが文字化けする
- 複数ファイルを処理するとき、ヒューマンエラーが起きやすい
VBAマクロでCSV操作を自動化すると、これらの問題をまとめて解消できます。さらに「毎朝9時に所定フォルダのCSVを読み込んでレポートを生成する」といったスケジュール実行まで組み合わせれば、完全なノーオペレーション運用も実現可能です。
事前準備:VBAエディタの起動と設定
まず開発タブを表示させます。Excelの「ファイル」→「オプション」→「リボンのユーザー設定」で「開発」にチェックを入れてください。その後、Alt + F11 キーを押すとVBAエディタ(Visual Basic for Applications)が開きます。
メニューから「挿入」→「標準モジュール」を選択し、以下のコードを貼り付けて実行してください。
また、ファイルシステム操作(フォルダ存在確認など)を行う場合は、VBAエディタの「ツール」→「参照設定」から Microsoft Scripting Runtime にチェックを入れておくと便利です。
CSVをExcelに自動インポートする基本コード
もっともシンプルなインポート方法は、Open ステートメントを使ってCSVをテキストとして読み込む方法です。ウィザードを使わないため、先頭ゼロが消えないという大きなメリットがあります。
' ========================================
' 基本CSVインポートマクロ
' 対象: UTF-8またはShift-JIS のカンマ区切りCSV
' ========================================
Sub ImportCSV_Basic()
Dim filePath As String
Dim fileNo As Integer
Dim lineText As String
Dim cols() As String
Dim ws As Worksheet
Dim rowIndex As Long
' --- インポート先シートの準備 ---
Set ws = ThisWorkbook.Sheets(1)
ws.Cells.Clear
rowIndex = 1
' --- ファイル選択ダイアログ ---
filePath = Application.GetOpenFilename( _
FileFilter:="CSVファイル (*.csv),*.csv", _
Title:="インポートするCSVを選択してください")
If filePath = "False" Then
MsgBox "キャンセルされました。", vbInformation
Exit Sub
End If
' --- ファイルを開いて1行ずつ読み込む ---
fileNo = FreeFile()
Open filePath For Input As #fileNo
Do While Not EOF(fileNo)
Line Input #fileNo, lineText
' カンマで分割
cols = Split(lineText, ",")
Dim i As Integer
For i = 0 To UBound(cols)
' 先頭ゼロ保持のため文字列として貼り付け
ws.Cells(rowIndex, i + 1).NumberFormat = "@"
ws.Cells(rowIndex, i + 1).Value = cols(i)
Next i
rowIndex = rowIndex + 1
Loop
Close #fileNo
MsgBox "インポート完了! " & rowIndex - 1 & " 行を読み込みました。", vbInformation
End Sub
ポイント解説
FreeFile():使用可能なファイル番号を自動取得する。ハードコードすると競合するため必ず使用する。NumberFormat = "@":セル書式を文字列に設定してから値を入れることで、先頭ゼロや日付の自動変換を防ぐ。EOF(fileNo):ファイル末尾に達したらループを終了する。
実務向け:文字コード・区切り文字に対応したインポート
基幹システムによっては UTF-8(BOM付き) や タブ区切り(TSV) で出力されることがあります。Open ステートメントのみではUTF-8を正しく扱えないケースがあるため、ADODB.Stream オブジェクトを使う方法が安全です。
' ========================================
' UTF-8 CSV インポートマクロ(ADODB.Stream使用)
' 参照設定不要・Windows標準コンポーネントで動作
' ========================================
Sub ImportCSV_UTF8()
Dim filePath As String
Dim stream As Object
Dim lineText As String
Dim cols() As String
Dim ws As Worksheet
Dim rowIndex As Long
Dim delimiter As String
delimiter = "," ' タブ区切りの場合は vbTab に変更
Set ws = ThisWorkbook.Sheets(1)
ws.Cells.Clear
rowIndex = 1
filePath = Application.GetOpenFilename( _
FileFilter:="CSVファイル (*.csv),*.csv,テキストファイル (*.txt),*.txt", _
Title:="インポートするファイルを選択")
If filePath = "False" Then Exit Sub
' ADODB.Stream でUTF-8読み込み
Set stream = CreateObject("ADODB.Stream")
With stream
.Type = 2 ' テキストモード
.Charset = "UTF-8" ' 文字コード指定
.Open
.LoadFromFile filePath
End With
Do While Not stream.EOS
lineText = stream.ReadText(-2) ' -2 = adReadLine(1行ずつ)
' BOMが先頭行に混入する場合の除去
If rowIndex = 1 Then
lineText = Replace(lineText, Chr(239) & Chr(187) & Chr(191), "")
End If
cols = Split(lineText, delimiter)
Dim i As Integer
For i = 0 To UBound(cols)
ws.Cells(rowIndex, i + 1).NumberFormat = "@"
ws.Cells(rowIndex, i + 1).Value = cols(i)
Next i
rowIndex = rowIndex + 1
Loop
stream.Close
Set stream = Nothing
MsgBox "UTF-8インポート完了! " & rowIndex - 1 & " 行を処理しました。", vbInformation
End Sub
文字コードの判断基準
- Windowsの旧システム・日本語基幹パッケージ → Shift-JIS(CP932):
.Charset = "CP932"を指定 - 新しいクラウド系SaaS・Googleスプレッドシートエクスポート → UTF-8:
.Charset = "UTF-8" - BOM付きUTF-8(Excel出力に多い)→ BOM除去処理を追加(上記コード参照)
ExcelシートをCSVとして自動エクスポートするコード
Excelの「名前を付けて保存」でCSV保存すると確認ダイアログが出て手間がかかります。マクロを使えばダイアログなしで指定フォルダにCSVを自動保存できます。
' ========================================
' アクティブシートをCSVエクスポートするマクロ
' 文字コード: UTF-8 BOM付き(Excelで開いたとき文字化けしない)
' ========================================
Sub ExportCSV_UTF8BOM()
Dim ws As Worksheet
Dim savePath As String
Dim fileNo As Integer
Dim rowIndex As Long
Dim colIndex As Long
Dim lastRow As Long
Dim lastCol As Long
Dim lineBuffer As String
Dim cellVal As String
Set ws = ActiveSheet
' 保存先フォルダとファイル名を指定(必要に応じて変更)
savePath = ThisWorkbook.Path & "\output_" & _
Format(Now(), "yyyymmdd_HHmmss") & ".csv"
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
fileNo = FreeFile()
Open savePath For Output As #fileNo
' UTF-8 BOM を先頭に書き込む
Print #fileNo, Chr(239) & Chr(187) & Chr(191);
For rowIndex = 1 To lastRow
lineBuffer = ""
For colIndex = 1 To lastCol
cellVal = CStr(ws.Cells(rowIndex, colIndex).Value)
' カンマ・ダブルクォート・改行を含む場合はダブルクォートで囲む
If InStr(cellVal, ",") > 0 Or _
InStr(cellVal, """") > 0 Or _
InStr(cellVal, vbLf) > 0 Then
cellVal = """" & Replace(cellVal, """", """""") & """"
End If
If colIndex = lastCol Then
lineBuffer = lineBuffer & cellVal
Else
lineBuffer = lineBuffer & cellVal & ","
End If
Next colIndex
Print #fileNo, lineBuffer
Next rowIndex
Close #fileNo
MsgBox "CSVエクスポート完了!" & vbCrLf & savePath, vbInformation
End Sub
ポイント解説
- ファイル名にタイムスタンプを付与することで上書き防止になる。
- セル値にカンマやダブルクォートが含まれるとき、RFC 4180に従ってダブルクォートで囲む処理を入れることで破損を防ぐ。
- BOM(
Chr(239)&Chr(187)&Chr(191))を先頭に付けることで、Excelで開いたとき文字化けしない。
フォルダ内の複数CSVを一括取り込む方法
月次レポートや日次データなど、同じ形式のCSVが大量にある場合は、フォルダをループして全ファイルを一気に処理するマクロが有効です。
' ========================================
' 指定フォルダ内の全CSVを縦に積み上げてインポート
' ========================================
Sub ImportAllCSVInFolder()
Dim folderPath As String
Dim fileName As String
Dim fileNo As Integer
Dim lineText As String
Dim cols() As String
Dim ws As Worksheet
Dim rowIndex As Long
Dim isFirst As Boolean
Dim skipHeader As Boolean
skipHeader = True ' 2ファイル目以降のヘッダー行をスキップするか
Set ws = ThisWorkbook.Sheets(1)
ws.Cells.Clear
rowIndex = 1
' フォルダ選択ダイアログ
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "CSVファイルが入ったフォルダを選択"
If .Show = False Then Exit Sub
folderPath = .SelectedItems(1) & "\"
End With
isFirst = True
fileName = Dir(folderPath & "*.csv")
If fileName = "" Then
MsgBox "CSVファイルが見つかりませんでした。", vbExclamation
Exit Sub
End If
Do While fileName <> ""
Dim isHeaderRow As Boolean
isHeaderRow = True
fileNo = FreeFile()
Open folderPath & fileName For Input As #fileNo
Do While Not EOF(fileNo)
Line Input #fileNo, lineText
' 2ファイル目以降のヘッダーをスキップ
If skipHeader And Not isFirst And isHeaderRow Then
isHeaderRow = False
GoTo NextLine
End If
isHeaderRow = False
cols = Split(lineText, ",")
Dim i As Integer
For i = 0 To UBound(cols)
ws.Cells(rowIndex, i + 1).NumberFormat = "@"
ws.Cells(rowIndex, i + 1).Value = cols(i)
Next i
rowIndex = rowIndex + 1
NextLine:
Loop
Close #fileNo
isFirst = False
fileName = Dir() ' 次のファイルへ
Loop
MsgBox "一括インポート完了! 合計 " & rowIndex - 1 & " 行を処理しました。", vbInformation
End Sub
実行時エラー番号一覧と解決策
VBAでCSV操作をするときに遭遇しやすいエラーをまとめました。エラー番号でそのまま検索してもこの一覧が役に立つよう、原因と修正方法を丁寧に記載しています。
実行時エラー 1004:アプリケーション定義またはオブジェクト定義のエラー
- 主な原因:存在しないシート名・範囲への書き込み、保護されたシートへの操作、ファイルが既に開いている状態でのSaveAs
- 解決策:シート名のスペルミスを確認。シートを
Sheets(1)のようにインデックスで指定する。保護がかかっている場合はws.Unprotectを先に実行する。
実行時エラー 53:ファイルが見つかりません
- 主な原因:
Openステートメントで指定したファイルパスが間違っている。ファイルが別のフォルダに移動された。 - 解決策:
Dir(filePath)で事前に存在確認を行い、空文字だったら処理を中断する。
' ファイル存在確認の書き方
If Dir(filePath) = "" Then
MsgBox "ファイルが見つかりません: " & filePath, vbCritical
Exit Sub
End If
実行時エラー 70:書き込みできません(パーミッションエラー)
- 主な原因:出力先のCSVファイルがExcelや他のアプリで既に開かれている。読み取り専用属性が付いている。管理者権限が必要なフォルダへの書き込み。
- 解決策:対象ファイルを閉じてから実行する。保存先を
ThisWorkbook.Path配下にして権限問題を回避する。
実行時エラー 75:パス名が無効です
- 主な原因:ファイルパスに使用できない文字(
: * ? " < > |)が含まれている。パスの末尾に余分な\が付いている。 - 解決策:パスをデバッグウィンドウに
Debug.Print filePathで出力して確認する。
実行時エラー 9:インデックスが有効範囲にありません
- 主な原因:
Sheets("Sheet1")のように名前で参照しているが、シート名が日本語や別の名前になっている。配列のUBoundを超えたアクセス。 - 解決策:シートを番号(
Sheets(1))またはコード名(Sheet1)で参照する。
実行時エラー 13:型が一致しません
- 主な原因:CSV内の空白行・空セルを数値型変数に代入しようとした。
CInt()などの変換関数に非数値文字列を渡した。 - 解決策:
IsNumeric()やIsEmpty()で値を検証してから変換する。
' 型チェックの書き方
If IsNumeric(cols(2)) Then
ws.Cells(rowIndex, 3).Value = CDbl(cols(2))
Else
ws.Cells(rowIndex, 3).Value = cols(2)
End If
実行時エラー 91:オブジェクト変数またはWithブロック変数が設定されていません
- 主な原因:
Setを使わずにオブジェクト変数に代入しようとした。Nothingのオブジェクトにメソッドを呼び出した。 - 解決策:オブジェクト変数には必ず
Setキーワードを使う。処理前にIf Not obj Is Nothing Thenでガード処理を入れる。
実行時エラー 5:プロシージャの呼び出し、または引数が不正です
- 主な原因:
Split関数に空文字を渡した。Openステートメントのモード指定が間違っている(InputモードでOutputしようとするなど)。 - 解決策:引数の型と値を見直す。空行の場合は
If Len(Trim(lineText)) = 0 Then GoTo NextLineでスキップする。
実務で使えるテクニック集
画面更新を止めて高速化する
大量行の処理では画面描画がボトルネックになります。処理の前後で次のコードを追加するだけで劇的に速くなります。
' 処理前(高速化設定)
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
' --- メイン処理 ---
' 処理後(必ず元に戻す)
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
エラーハンドリングをつけてロバストにする
本番運用するマクロには必ずエラーハンドリングを実装してください。ファイルが開きっぱなしになるのを防ぐために Close を確実に実行する構造が重要です。
Sub SafeImport()
Dim fileNo As Integer
fileNo = FreeFile()
On Error GoTo ErrorHandler
Open "C:\data\sample.csv" For Input As #fileNo
' --- 処理 ---
Close #fileNo
Exit Sub
ErrorHandler:
If fileNo > 0 Then Close #fileNo
MsgBox "エラーが発生しました。" & vbCrLf & _
"エラー番号: " & Err.Number & vbCrLf & _
"内容: " & Err.Description, vbCritical
End Sub
今日の日付のCSVを自動的に読み込む
「毎朝、日付が付いたCSVを取り込む」という業務に対応するパターンです。
Dim todayFile As String
todayFile = "C:\daily_data\" & Format(Date, "yyyymmdd") & "_sales.csv"
If Dir(todayFile) = "" Then
MsgBox "本日分のファイルが存在しません: " & todayFile, vbExclamation
Exit Sub
End If
' 以降インポート処理へ
インポート後に自動でピボットテーブルを更新する
' 全ピボットテーブルを更新
Dim pt As PivotTable
For Each pt In ActiveSheet.PivotTables
pt.RefreshTable
Next pt
Outlookと連携してCSVをメール添付で送信する
' 参照設定: Microsoft Outlook XX.X Object Library が必要
Sub SendCSVByMail()
Dim olApp As Object
Dim olMail As Object
Dim csvPath As String
csvPath = ThisWorkbook.Path & "\report.csv"
Set olApp = CreateObject("Outlook.Application")
Set olMail = olApp.CreateItem(0)
With olMail
.To = "[email protected]"
.Subject = "日次レポート " & Format(Date, "yyyy/mm/dd")
.Body = "本日のレポートをお送りします。"
.Attachments.Add csvPath
.Send
End With
MsgBox "メール送信完了", vbInformation
End Sub
まとめ
本記事では、ExcelマクロによるCSVの自動インポート・エクスポートについて、基本コードから実務向けの応用まで解説しました。要点を整理すると次のとおりです。
- Open ステートメントを使ったインポートは先頭ゼロを守れる・シンプルで速い
- UTF-8対応には ADODB.Stream が有効で、BOM除去処理もセットで実装する
- エクスポート時は RFC 4180 に沿ったダブルクォート囲み処理を入れてデータ破損を防ぐ
- フォルダループで複数CSVを一括処理するとき、2件目以降のヘッダー行スキップを忘れずに
- 実行時エラー 1004・53・70・75・9・13・91・5 の原因と対策を覚えておくとデバッグが格段に速くなる
ScreenUpdating = FalseやOn Error GoToによるエラーハンドリングは本番マクロの必須実装
マクロは一度作れば何度でも再利用できます。まず「毎日手作業でやっているCSV処理」を1つピックアップし、本記事のコードをベースにカスタマイズすることから始めてみてください。業務の自動化は、小さな一歩の積み重ねで大きな時間削減につながります。