はじめに
日々の業務で、複数のCSVファイルをExcelで集計する機会は少なくありません。例えば、各店舗から送られてくる日報CSV、システムから出力される月次データCSVなど、これらを一つ一つ手作業で開いてコピー&ペーストするのは、時間もかかり、ミスも発生しやすいため非常に非効率です。
この記事では、Excel VBA(Visual Basic for Applications)を使って、指定したフォルダ内の複数CSVファイルを自動で読み込み、1つのExcelシートにまとめて集計する方法を解説します。初級者の方でも理解できるよう、具体的なコードと丁寧な解説を心がけましたので、ぜひご自身の業務自動化にお役立てください。
なぜExcel VBAでCSV一括処理をするのか?
- 作業時間の短縮: 手作業でのコピペ作業を劇的に削減します。
- ヒューマンエラーの削減: 毎回同じ処理を自動で行うため、コピペミスや範囲選択ミスがなくなります。
- 再利用性: 一度作成したマクロは、同じ形式のCSVファイルであれば何度でも繰り返し利用できます。
- プログラミング学習の第一歩: 身近な業務課題を解決することで、VBAの基礎を実践的に学べます。
準備するもの
- Microsoft Excel(Windows版を推奨)
- 結合したい複数のCSVファイル(同じフォルダ内にまとめておいてください)
具体的な手順
今回は、以下の手順でマクロを作成し、実行します。
- 新しいExcelブックを開き、VBAエディタを起動する。
- 標準モジュールにVBAコードを記述する。
- マクロを実行し、対象フォルダを選択する。
サンプルCSVファイルの準備
まずは、適当なフォルダ(例: C:\Temp\CSVデータ)を作成し、その中に以下のようなCSVファイルをいくつか作成してください。
sample1.csv
商品名,売上,数量
りんご,100,5
みかん,80,10
sample2.csv
商品名,売上,数量
バナナ,120,7
ぶどう,200,3
※ヘッダー行は最初のファイルだけ必要で、それ以降のファイルはデータのみが結合されます。
VBAコード
新しいExcelブックを開き、Alt + F11キーを押してVBAエディタを起動します。「挿入」メニューから「標準モジュール」を選択し、以下のコードを貼り付けてください。
Sub CSV_一括読み込み_結合()
Dim folderPath As String
Dim fileName As String
Dim targetSheet As Worksheet
Dim csvWorkbook As Workbook
Dim csvWorksheet As Worksheet
Dim lastRow As Long
Dim firstFile As Boolean
' 結合先のシートを設定
' 新しいシートを作成してそこに結合する場合
Set targetSheet = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
targetSheet.Name = "結合結果_" & Format(Now, "yyyymmdd_hhmmss")
' フォルダ選択ダイアログを表示
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "CSVファイルのあるフォルダを選択してください"
.AllowMultiSelect = False
If .Show = True Then
folderPath = .SelectedItems(1) & "\"
Else
MsgBox "フォルダが選択されませんでした。処理を中止します。", vbExclamation
Exit Sub
End If
End With
' 最初のファイルかどうかのフラグ
firstFile = True
lastRow = 1 ' 結合先のシートの開始行
' フォルダ内のCSVファイルを検索
fileName = Dir(folderPath & "*.csv")
If fileName = "" Then
MsgBox "指定されたフォルダにCSVファイルが見つかりませんでした。", vbExclamation
targetSheet.Delete ' 作成した空のシートを削除
Exit Sub
End If
Application.ScreenUpdating = False ' 画面更新を停止
Application.DisplayAlerts = False ' 警告表示を停止
Do While fileName <> ""
' CSVファイルを開く
Set csvWorkbook = Workbooks.Open(folderPath & fileName, Local:=True)
Set csvWorksheet = csvWorkbook.Sheets(1)
' ヘッダー行の処理
If firstFile Then
' 最初のファイルはヘッダーを含めて全てコピー
csvWorksheet.UsedRange.Copy targetSheet.Cells(lastRow, 1)
firstFile = False
Else
' 2つ目以降のファイルはヘッダー行(1行目)を除いてコピー
' データが2行目から始まることを想定
If csvWorksheet.UsedRange.Rows.Count > 1 Then ' 1行以上のデータがある場合
csvWorksheet.Range(csvWorksheet.Cells(2, 1), csvWorksheet.Cells(csvWorksheet.UsedRange.Rows.Count, csvWorksheet.UsedRange.Columns.Count)).Copy _
targetSheet.Cells(lastRow, 1)
End If
End If
' 次のデータ書き込み開始位置を更新
lastRow = targetSheet.Cells(targetSheet.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
' 開いたCSVファイルを閉じる(保存しない)
csvWorkbook.Close SaveChanges:=False
' 次のCSVファイルを取得
fileName = Dir()
Loop
Application.ScreenUpdating = True ' 画面更新を再開
Application.DisplayAlerts = True ' 警告表示を再開
' 最終調整
targetSheet.Columns.AutoFit ' 列幅を自動調整
targetSheet.Activate ' 結合結果シートをアクティブにする
MsgBox "全てのCSVファイルの読み込みと結合が完了しました!", vbInformation
End Sub
コードの解説
1. 結合先シートの準備
Set targetSheet = ThisWorkbook.Sheets.Add(...): 新しいシートを作成し、そこに結合結果を出力します。シート名には実行日時が含まれるため、複数回実行しても過去の結果が上書きされる心配がありません。
2. フォルダ選択ダイアログ
Application.FileDialog(msoFileDialogFolderPicker): ユーザーがCSVファイルが格納されているフォルダをGUIで選択できるようにします。これにより、コードを書き換えることなく様々なフォルダに対応できます。
3. CSVファイルの検索とループ処理
fileName = Dir(folderPath & "*.csv"): 指定されたフォルダ内の最初のCSVファイル名を取得します。Do While fileName <> "" ... Loop:Dir()関数は、引数なしで呼び出すと、前回の検索条件に合致する次のファイル名を返します。ファイルがなくなるまでこのループを繰り返します。
4. CSVファイルの読み込みとデータ転記
Workbooks.Open(folderPath & fileName, Local:=True): CSVファイルをExcelブックとして開きます。Local:=Trueを指定することで、PCの地域設定に応じた区切り文字(カンマやセミコロンなど)で正しく開かれます。If firstFile Then ... Else ... End If: ヘッダー行の処理をコントロールする重要な部分です。firstFile = Trueの場合(最初のCSVファイル):csvWorksheet.UsedRange.Copy targetSheet.Cells(lastRow, 1)で、ヘッダーを含めた全てのデータをコピーします。firstFile = Falseの場合(2つ目以降のCSVファイル):csvWorksheet.Range(csvWorksheet.Cells(2, 1), ...)で、2行目以降のデータのみをコピーします。これにより、結合結果のシートにはヘッダーが1つだけになります。
lastRow = targetSheet.Cells(targetSheet.Rows.Count, 1).End(xlUp).Offset(1, 0).Row: 結合先のシートのA列の最終行を特定し、その次の行を次のデータ書き込み開始位置として設定します。csvWorkbook.Close SaveChanges:=False: 開いたCSVファイルを閉じます。SaveChanges:=Falseとすることで、誤ってCSVファイルを変更してしまうことを防ぎます。
5. 処理の高速化とエラー対策
Application.ScreenUpdating = False: マクロ実行中の画面のちらつきを抑え、処理を高速化します。Application.DisplayAlerts = False: ファイルを閉じる際の「変更を保存しますか?」といった警告メッセージを表示しないようにします。- エラーハンドリング: フォルダが選択されなかった場合や、CSVファイルが見つからなかった場合にメッセージを表示し、処理を中断します。
マクロの実行方法
- VBAエディタを閉じ、Excelシートに戻ります。
- 「開発」タブ(表示されていない場合は、「ファイル」→「オプション」→「リボンのユーザー設定」から「開発」にチェックを入れてください)をクリックします。
- 「マクロ」をクリックし、「
CSV_一括読み込み_結合」を選択して「実行」ボタンを押します。 - フォルダ選択ダイアログが表示されるので、CSVファイルが保存されているフォルダを選択し、「OK」をクリックします。
- 処理が完了するとメッセージが表示され、新しいシートに結合されたデータが表示されます。
応用と注意点
- CSVファイルの形式: このマクロは、全てのCSVファイルが同じ列構成を持つことを前提としています。異なる列構成のファイルが混在している場合、データがずれて結合される可能性があります。
- 大量データの場合: 非常に大量のCSVファイルや、1ファイルあたりのデータ量が膨大な場合、処理に時間がかかることがあります。その際は、より効率的なデータ処理方法(例: ADO接続など)の検討が必要になる場合があります。
- 区切り文字: CSVファイルの区切り文字がカンマ(,)以外(例: タブ、セミコロン)の場合、
Workbooks.Openの引数にDelimiterなどを追加して調整する必要があります。
まとめ
Excel VBAを活用することで、フォルダ内の複数CSVファイルを簡単に、そして正確に1つのExcelシートにまとめることができます。手作業による集計作業から解放され、より重要な業務に時間を割けるようになります。
今回ご紹介したコードは、あくまで基本的なテンプレートです。ご自身の業務内容に合わせて、エラー処理を強化したり、特定の条件でデータをフィルタリングしたり、といったカスタマイズも可能です。ぜひこのマクロを参考に、日々の業務自動化を始めてみてください。


コメント