はじめに:Excelブックの比較、手作業にサヨナラ!
複数のExcelブック間で、シート名やシートの構成(順番、有無)を比較する必要に迫られたことはありませんか?
- 異なるバージョンのブック間で変更点を確認したい
- 複数の担当者が作成したブックの整合性をチェックしたい
- システム連携用のテンプレートが正しく利用されているか確認したい
このような場面で、手作業で一つずつシートを目視確認するのは、時間と労力がかかり、ミスも発生しやすいため非常に非効率です。そこで本記事では、Excel VBAを使って、複数ブックのシート名と構成を自動的に比較し、その結果をレポートとして出力するマクロの作成方法を解説します。
このマクロを使えば、煩雑な比較作業を劇的に効率化し、整合性チェックの精度を向上させることができます。初級者の方でも理解できるよう、具体的なコードと丁寧な解説を心がけましたので、ぜひ最後までお読みください。
比較のポイントと準備
今回のマクロで比較する主なポイントは以下の3点です。
- シート数: 比較対象の2つのブックのシート数が同じかどうか。
- シート名: 各ブックの同じ位置にあるシートの名称が一致しているか。
- シート順序: 各シートの並び順が一致しているか。
これらの情報を基に、最終的な比較結果を新しいシートにレポートとして出力します。
マクロ実行前の準備
特に準備は必要ありませんが、比較したいExcelファイルが手元にあることを確認してください。マクロを実行すると、ファイル選択ダイアログが表示され、比較対象のブックを選択する形式になります。
Excel VBAコードの全体像
それでは、具体的なVBAコードを見ていきましょう。以下のコードを標準モジュールに貼り付けて使用します。このマクロは、2つのExcelブックを選択させ、シート数、シート名、シート順序を比較し、結果を新しいシートにレポートとして出力します。
Sub CompareExcelWorkbooksStructure()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim reportWs As Worksheet
Dim path1 As String, path2 As String
Dim i As Long
Dim rowNum As Long
Dim differentDetected As Boolean
' 比較対象のブックを選択させる
MsgBox "比較する1つ目のブックを選択してください。", vbInformation
path1 = Application.GetOpenFilename("Excelファイル (*.xlsx;*.xlsm),*.xlsx;*.xlsm")
If path1 = "False" Then Exit Sub
MsgBox "比較する2つ目のブックを選択してください。", vbInformation
path2 = Application.GetOpenFilename("Excelファイル (*.xlsx;*.xlsm),*.xlsx;*.xlsm")
If path2 = "False" Then Exit Sub
' ブックを開く(読み取り専用で開くことで、元のファイルへの影響を避ける)
Set wb1 = Workbooks.Open(path1, ReadOnly:=True)
Set wb2 = Workbooks.Open(path2, ReadOnly:=True)
' 結果出力用のシートを新規作成(マクロ実行中のブックに作成)
Set reportWs = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
reportWs.Name = "比較レポート_" & Format(Now, "yyyymmdd_hhmmss")
' レポートヘッダーの設定
rowNum = 1
With reportWs
.Cells(rowNum, 1).Value = "比較項目"
.Cells(rowNum, 2).Value = "ブック1 (" & wb1.Name & ")"
.Cells(rowNum, 3).Value = "ブック2 (" & wb2.Name & ")"
.Cells(rowNum, 4).Value = "結果"
.Range(.Cells(rowNum, 1), .Cells(rowNum, 4)).Font.Bold = True
.Range(.Cells(rowNum, 1), .Cells(rowNum, 4)).Interior.Color = RGB(220, 230, 241) ' 薄い青
End With
rowNum = rowNum + 1
differentDetected = False ' 差異が検出されたかどうかを追跡するフラグ
' 1. シート数の比較
reportWs.Cells(rowNum, 1).Value = "シート数"
reportWs.Cells(rowNum, 2).Value = wb1.Sheets.Count
reportWs.Cells(rowNum, 3).Value = wb2.Sheets.Count
If wb1.Sheets.Count <> wb2.Sheets.Count Then
reportWs.Cells(rowNum, 4).Value = "異なる"
reportWs.Cells(rowNum, 4).Font.Color = RGB(255, 0, 0) ' 赤
differentDetected = True
Else
reportWs.Cells(rowNum, 4).Value = "同じ"
End If
rowNum = rowNum + 1
' 2. シート名と順序の比較(詳細レポート)
reportWs.Cells(rowNum, 1).Value = "シート名と順序"
reportWs.Cells(rowNum, 4).Value = "--- 詳細 ---"
reportWs.Cells(rowNum, 4).Font.Bold = True
rowNum = rowNum + 1
Dim maxSheets As Long
' 両方のブックのシート数を比較し、多い方に合わせてループする
maxSheets = Application.Max(wb1.Sheets.Count, wb2.Sheets.Count)
For i = 1 To maxSheets
Dim sheetName1 As String, sheetName2 As String
Dim sheetOrder1 As Long, sheetOrder2 As Long
Dim comparisonResult As String
' ブック1のシート情報取得
sheetName1 = ""
sheetOrder1 = -1 ' 存在しないことを示す
If i <= wb1.Sheets.Count Then
Set ws1 = wb1.Sheets(i)
sheetName1 = ws1.Name
sheetOrder1 = ws1.Index
End If
' ブック2のシート情報取得
sheetName2 = ""
sheetOrder2 = -1 ' 存在しないことを示す
If i <= wb2.Sheets.Count Then
Set ws2 = wb2.Sheets(i)
sheetName2 = ws2.Name
sheetOrder2 = ws2.Index
End If
' レポートにシート情報を記述
reportWs.Cells(rowNum, 1).Value = "シート " & i & " (位置)"
reportWs.Cells(rowNum, 2).Value = IIf(sheetName1 = "", "(存在しない)", sheetName1)
reportWs.Cells(rowNum, 3).Value = IIf(sheetName2 = "", "(存在しない)", sheetName2)
' 比較結果の判定
If sheetName1 = sheetName2 And sheetOrder1 = sheetOrder2 Then
comparisonResult = "同じ"
Else
comparisonResult = "異なる"
reportWs.Cells(rowNum, 4).Font.Color = RGB(255, 0, 0) ' 赤
differentDetected = True
End If
reportWs.Cells(rowNum, 4).Value = comparisonResult
rowNum = rowNum + 1
Next i
' 総合判定
rowNum = rowNum + 1 ' 1行空ける
reportWs.Cells(rowNum, 1).Value = "総合判定"
If Not differentDetected Then
reportWs.Cells(rowNum, 4).Value = "完全に一致しました!"
reportWs.Cells(rowNum, 4).Font.Color = RGB(0, 128, 0) ' 緑
Else
reportWs.Cells(rowNum, 4).Value = "差異が検出されました!"
reportWs.Cells(rowNum, 4).Font.Color = RGB(255, 0, 0) ' 赤
End If
reportWs.Cells(rowNum, 4).Font.Bold = True
' レポートシートの整形
reportWs.Columns("A:D").AutoFit
' 後処理:開いたブックを閉じる(変更は保存しない)
wb1.Close SaveChanges:=False
wb2.Close SaveChanges:=False
MsgBox "比較が完了しました。現在のブックに「比較レポート」シートが作成されました。", vbInformation
End Sub
VBAコードの解説
コードの主要な部分をステップごとに解説します。
1. 変数の宣言とブックの選択
Dim wb1 As Workbook, wb2 As Workbook
Dim reportWs As Worksheet
Dim path1 As String, path2 As String
' ...その他の変数
MsgBox "比較する1つ目のブックを選択してください。", vbInformation
path1 = Application.GetOpenFilename("Excelファイル (*.xlsx;*.xlsm),*.xlsx;*.xlsm")
If path1 = "False" Then Exit Sub
' ...2つ目のブック選択
Set wb1 = Workbooks.Open(path1, ReadOnly:=True)
Set wb2 = Workbooks.Open(path2, ReadOnly:=True)
- `Dim` ステートメントで必要な変数を宣言します。`Workbook` オブジェクトはExcelブックを、`Worksheet` オブジェクトはシートを扱います。
- `Application.GetOpenFilename` を使用して、ユーザーに比較対象のExcelブックを2つ選択させます。これにより、どんなブックでも汎用的に比較できるようになります。
- 選択されたパスを使って `Workbooks.Open` でブックを開きます。`ReadOnly:=True` を指定することで、元のファイルに変更が加わらないように保護しています。
2. 比較レポートシートの作成とヘッダー設定
Set reportWs = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
reportWs.Name = "比較レポート_" & Format(Now, "yyyymmdd_hhmmss")
' レポートヘッダーの設定
' ...
- `ThisWorkbook.Sheets.Add` で、マクロを実行している現在のブックの末尾に新しいシートを追加します。
- シート名には実行日時を含めることで、複数のレポートが作成されても区別しやすくしています。
- レポートの見出し(「比較項目」「ブック1」「ブック2」「結果」)を設定し、視認性を高めるために太字や背景色を適用しています。
3. シート数の比較
reportWs.Cells(rowNum, 1).Value = "シート数"
reportWs.Cells(rowNum, 2).Value = wb1.Sheets.Count
reportWs.Cells(rowNum, 3).Value = wb2.Sheets.Count
If wb1.Sheets.Count <> wb2.Sheets.Count Then
reportWs.Cells(rowNum, 4).Value = "異なる"
reportWs.Cells(rowNum, 4).Font.Color = RGB(255, 0, 0)
differentDetected = True
Else
reportWs.Cells(rowNum, 4).Value = "同じ"
End If
- `wb.Sheets.Count` で各ブックのシート数を取得し、比較します。
- 結果に応じて「異なる」または「同じ」をレポートに記載し、「異なる」場合は文字色を赤にして目立たせています。
- `differentDetected` フラグは、一つでも差異が見つかった場合に `True` に設定され、最終的な総合判定に利用されます。
4. シート名と順序の詳細比較
maxSheets = Application.Max(wb1.Sheets.Count, wb2.Sheets.Count)
For i = 1 To maxSheets
' ブック1のシート情報取得
If i <= wb1.Sheets.Count Then
Set ws1 = wb1.Sheets(i)
sheetName1 = ws1.Name
sheetOrder1 = ws1.Index
Else
sheetName1 = ""
sheetOrder1 = -1
End If
' ブック2のシート情報取得
' ...同様の処理
' 比較結果の判定
If sheetName1 = sheetName2 And sheetOrder1 = sheetOrder2 Then
comparisonResult = "同じ"
Else
comparisonResult = "異なる"
reportWs.Cells(rowNum, 4).Font.Color = RGB(255, 0, 0)
differentDetected = True
End If
' ...レポートに記述
Next i
- `For i = 1 To maxSheets` で、シート数の多い方に合わせてループを回します。これにより、片方のブックにしか存在しないシートも検出できます。
- `wb.Sheets(i)` でインデックス(順序)を指定してシートを取得し、`ws.Name` でシート名を取得します。
- 各シートの位置で、シート名と順序が一致しているかを比較し、結果をレポートに詳細に出力します。
- もし片方のブックにシートが存在しない場合は「(存在しない)」と表示されます。
5. 総合判定と後処理
If Not differentDetected Then
reportWs.Cells(rowNum, 4).Value = "完全に一致しました!"
reportWs.Cells(rowNum, 4).Font.Color = RGB(0, 128, 0) ' 緑
Else
reportWs.Cells(rowNum, 4).Value = "差異が検出されました!"
reportWs.Cells(rowNum, 4).Font.Color = RGB(255, 0, 0) ' 赤
End If
' 後処理
wb1.Close SaveChanges:=False
wb2.Close SaveChanges:=False
MsgBox "比較が完了しました。現在のブックに「比較レポート」シートが作成されました。", vbInformation
- `differentDetected` フラグの状態に応じて、最終的な「完全に一致」または「差異あり」のメッセージをレポートに出力します。
- `wb.Close SaveChanges:=False` で、開いたブックを保存せずに閉じます。これにより、元のファイルが意図せず変更されることを防ぎます。
- 最後にメッセージボックスで比較完了を通知します。
マクロの実行方法
- 比較したいExcelファイルを開き、
Alt + F11キーを押してVBAエディター(VBE)を開きます。 - VBEのメニューから
挿入>標準モジュールを選択します。 - 開いたモジュールウィンドウに、上記のVBAコードをコピー&ペーストします。
- Excelワークシートに戻り、
Alt + F8キーを押してマクロダイアログを開きます。 CompareExcelWorkbooksStructureを選択し、実行ボタンをクリックします。- ファイル選択ダイアログが2回表示されるので、比較したい2つのExcelブックをそれぞれ選択します。
- マクロの実行後、現在のブックに「比較レポート_YYYYMMDD_HHMMSS」という名前のシートが作成され、比較結果が表示されます。
活用例と応用
このマクロは、以下のような業務シーンで特に役立ちます。
- バージョン管理: Excelファイルの更新前と更新後で、シート構成に予期せぬ変更がないか確認する。
- 共同作業: 複数の担当者が編集したExcelファイルを結合する前に、各ファイルのシート構成が整合しているかチェックする。
- テンプレート管理: システムから出力されるExcelテンプレートや、部署内で共有するテンプレートのシート構成が、常に正しい状態であることを確認する。
さらに高度な比較が必要な場合は、本マクロを拡張して以下のような機能を追加することも可能です。
- 特定のセル範囲の値の比較
- シートの保護設定の比較
- 非表示シートの有無の比較
これらの機能を追加することで、より詳細なExcelブックの整合性チェックが可能になります。
まとめ
本記事では、Excel VBAを使って複数ブックのシート名と構成を自動的に比較・チェックする方法を解説しました。手作業では時間と手間がかかり、ミスも発生しやすい作業をマクロで自動化することで、業務効率と精度を大幅に向上させることができます。
今回ご紹介したコードは、そのまま現場で活用できる実用的なものです。ぜひご自身の業務に組み込み、日々のExcel作業をよりスマートに、より確実に進めてみてください。VBAによる自動化は、あなたの業務を大きく変える強力なツールとなるはずです。


コメント