【Excel VBA】複数CSVファイルを一括結合!1つのシートにまとめる自動化マクロ

Excel・VBA

はじめに

日々の業務で、複数のCSVファイルをExcelで集計する機会は少なくありません。例えば、各店舗から送られてくる日報CSV、システムから出力される月次データCSVなど、これらを一つ一つ手作業で開いてコピー&ペーストするのは、時間もかかり、ミスも発生しやすいため非常に非効率です。

この記事では、Excel VBA(Visual Basic for Applications)を使って、指定したフォルダ内の複数CSVファイルを自動で読み込み、1つのExcelシートにまとめて集計する方法を解説します。初級者の方でも理解できるよう、具体的なコードと丁寧な解説を心がけましたので、ぜひご自身の業務自動化にお役立てください。

なぜExcel VBAでCSV一括処理をするのか?

  • 作業時間の短縮: 手作業でのコピペ作業を劇的に削減します。
  • ヒューマンエラーの削減: 毎回同じ処理を自動で行うため、コピペミスや範囲選択ミスがなくなります。
  • 再利用性: 一度作成したマクロは、同じ形式のCSVファイルであれば何度でも繰り返し利用できます。
  • プログラミング学習の第一歩: 身近な業務課題を解決することで、VBAの基礎を実践的に学べます。

準備するもの

  • Microsoft Excel(Windows版を推奨)
  • 結合したい複数のCSVファイル(同じフォルダ内にまとめておいてください)

具体的な手順

今回は、以下の手順でマクロを作成し、実行します。

  1. 新しいExcelブックを開き、VBAエディタを起動する。
  2. 標準モジュールにVBAコードを記述する。
  3. マクロを実行し、対象フォルダを選択する。

サンプル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ファイルが見つからなかった場合にメッセージを表示し、処理を中断します。

マクロの実行方法

  1. VBAエディタを閉じ、Excelシートに戻ります。
  2. 「開発」タブ(表示されていない場合は、「ファイル」→「オプション」→「リボンのユーザー設定」から「開発」にチェックを入れてください)をクリックします。
  3. 「マクロ」をクリックし、「CSV_一括読み込み_結合」を選択して「実行」ボタンを押します。
  4. フォルダ選択ダイアログが表示されるので、CSVファイルが保存されているフォルダを選択し、「OK」をクリックします。
  5. 処理が完了するとメッセージが表示され、新しいシートに結合されたデータが表示されます。

応用と注意点

  • CSVファイルの形式: このマクロは、全てのCSVファイルが同じ列構成を持つことを前提としています。異なる列構成のファイルが混在している場合、データがずれて結合される可能性があります。
  • 大量データの場合: 非常に大量のCSVファイルや、1ファイルあたりのデータ量が膨大な場合、処理に時間がかかることがあります。その際は、より効率的なデータ処理方法(例: ADO接続など)の検討が必要になる場合があります。
  • 区切り文字: CSVファイルの区切り文字がカンマ(,)以外(例: タブ、セミコロン)の場合、Workbooks.Openの引数にDelimiterなどを追加して調整する必要があります。

まとめ

Excel VBAを活用することで、フォルダ内の複数CSVファイルを簡単に、そして正確に1つのExcelシートにまとめることができます。手作業による集計作業から解放され、より重要な業務に時間を割けるようになります。

今回ご紹介したコードは、あくまで基本的なテンプレートです。ご自身の業務内容に合わせて、エラー処理を強化したり、特定の条件でデータをフィルタリングしたり、といったカスタマイズも可能です。ぜひこのマクロを参考に、日々の業務自動化を始めてみてください。

コメント

タイトルとURLをコピーしました