概要
日々の業務で、部署ごとや担当者ごとに作成されたバラバラのExcelファイルを集計する作業が発生していませんか?一つずつファイルを開き、シートを右クリックして「移動またはコピー」を選択し、集約先ブックを指定する……この単純作業を繰り返すのは、ヒューマンエラーの温床であり、貴重な時間の浪費です。
Excel VBAを活用すれば、指定したフォルダ内の全ブックを自動で読み込み、すべてのシートをワンクリックでマスターブックに集約することが可能です。本記事では、単なるコピーではなく、ファイル名やシート名の重複を回避し、実務でそのまま使える堅牢なVBAコードの書き方を徹底解説します。
詳細解説:仕組みとロジック
複数ブックの集約を実現するためには、以下の5つのステップをコードに落とし込む必要があります。
1. フォルダの選択:集計対象のファイルが格納されているフォルダを指定します。
2. ファイルのループ処理:Dir関数またはFileSystemObjectを使用して、フォルダ内のExcelファイルを一つずつ取得します。
3. ブックの開閉処理:対象ブックを開き、シートをコピーし、処理が終わったら閉じるというサイクルを回します。
4. シートのコピー処理:Worksheets.Copyメソッドを使用し、集約先のブックを指定して配置します。
5. エラーハンドリング:ファイルが開けない場合や、シート名が重複した場合の対策を講じます。
ここで重要なのは、処理中に「画面更新」と「自動計算」をオフにすることです。これを行わないと、ファイルを開くたびに計算処理が走り、実行時間が大幅に遅延します。
サンプルコード:実務特化型集約ツール
以下は、指定フォルダ内の全ブックの全シートを、実行ブックにコピーするコードです。
Sub MergeAllWorkbooks()
Dim TargetFolder As String
Dim FileName As String
Dim wbSource As Workbook
Dim wbDest As Workbook
Dim ws As Worksheet
' 画面更新と自動計算の停止
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Set wbDest = ThisWorkbook
' フォルダ選択ダイアログの表示
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "集約対象のブックが入っているフォルダを選択してください"
If .Show = -1 Then
TargetFolder = .SelectedItems(1) & "\"
Else
Exit Sub
End If
End With
FileName = Dir(TargetFolder & "*.xls*")
' ファイルループ開始
Do While FileName <> ""
' 自分自身はスキップ
If FileName <> wbDest.Name Then
Set wbSource = Workbooks.Open(TargetFolder & FileName)
' 全シートをループしてコピー
For Each ws In wbSource.Worksheets
ws.Copy After:=wbDest.Sheets(wbDest.Sheets.Count)
' コピーしたシートにファイル名をプレフィックスとして付与する場合
wbDest.Sheets(wbDest.Sheets.Count).Name = Left(FileName, 5) & "_" & ws.Name
Next ws
wbSource.Close SaveChanges:=False
End If
FileName = Dir
Loop
' 設定を元に戻す
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
MsgBox "全シートの集約が完了しました!", vbInformation
End Sub
実務アドバイス:プロの現場で生き残るためのテクニック
コードを動かすだけなら上記で十分ですが、実際の業務環境では「想定外」がつきものです。以下のポイントを意識してください。
1. シート名の重複リスク:
異なるブックに同じシート名(例:「Sheet1」)が複数存在する場合、シート名が重複してVBAがエラーを吐きます。コード内で「Left(FileName, 5) & “_” & ws.Name」のように、ファイル名を付与して一意のシート名にする工夫が不可欠です。
2. リンク切れの防止:
コピー元のシートに他のファイルへの外部参照(数式)が含まれていると、コピー後に「リンクの更新」メッセージが表示され、処理が止まってしまうことがあります。必要に応じて、コピー後に数値を「値貼り付け」に変換する処理を追加しましょう。
3. シートの非表示状態:
非表示シートも含めてコピーしたい場合は、`ws.Visible = xlSheetVisible` を活用して一時的に表示状態にするか、そのままコピーするかの判断が必要です。業務の要件に合わせてロジックを調整してください。
4. データの量とメモリ管理:
対象が数GBのデータである場合、一度にすべてを開くとメモリ不足になる可能性があります。その場合は、一度に開く数を制限する、あるいはADO/DAOを用いて直接データを吸い上げる手法(SQLクエリ)への切り替えを検討すべきです。
5. 実行順序の制御:
Dir関数はファイルの並び順を保証しません。もし「日付順」や「ファイル名順」に並べたい場合は、一度配列にファイル名を格納し、ソートしてから処理する仕組みを組み込むと、集約後のシート順序が美しくなります。
まとめ
複数ブックのシート集約は、VBA習得において最もコストパフォーマンスが高い自動化タスクの一つです。今回紹介したコードをベースに、ご自身の業務環境に合わせてカスタマイズしてみてください。
「手作業で数時間かかる集計が、数秒で終わる」。この体験こそが、VBAを学ぶ最大の報酬です。まずは小さなフォルダでテストを行い、エラーハンドリングを学びながら、少しずつ機能を拡張していきましょう。自動化は一日にして成らず。しかし、一度完成したツールは、あなたの業務を永続的に守り続けてくれる最強の武器となります。さあ、今すぐコードをコピーして、定時退社への第一歩を踏み出しましょう。
