Excel VBAで複数ブックのシート名と構成を自動比較!整合性チェックを効率化するマクロ

Excel・VBA

はじめに: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` で、開いたブックを保存せずに閉じます。これにより、元のファイルが意図せず変更されることを防ぎます。
  • 最後にメッセージボックスで比較完了を通知します。

マクロの実行方法

  1. 比較したいExcelファイルを開き、Alt + F11 キーを押してVBAエディター(VBE)を開きます。
  2. VBEのメニューから 挿入 > 標準モジュール を選択します。
  3. 開いたモジュールウィンドウに、上記のVBAコードをコピー&ペーストします。
  4. Excelワークシートに戻り、Alt + F8 キーを押してマクロダイアログを開きます。
  5. CompareExcelWorkbooksStructure を選択し、実行 ボタンをクリックします。
  6. ファイル選択ダイアログが2回表示されるので、比較したい2つのExcelブックをそれぞれ選択します。
  7. マクロの実行後、現在のブックに「比較レポート_YYYYMMDD_HHMMSS」という名前のシートが作成され、比較結果が表示されます。

活用例と応用

このマクロは、以下のような業務シーンで特に役立ちます。

  • バージョン管理: Excelファイルの更新前と更新後で、シート構成に予期せぬ変更がないか確認する。
  • 共同作業: 複数の担当者が編集したExcelファイルを結合する前に、各ファイルのシート構成が整合しているかチェックする。
  • テンプレート管理: システムから出力されるExcelテンプレートや、部署内で共有するテンプレートのシート構成が、常に正しい状態であることを確認する。

さらに高度な比較が必要な場合は、本マクロを拡張して以下のような機能を追加することも可能です。

  • 特定のセル範囲の値の比較
  • シートの保護設定の比較
  • 非表示シートの有無の比較

これらの機能を追加することで、より詳細なExcelブックの整合性チェックが可能になります。

まとめ

本記事では、Excel VBAを使って複数ブックのシート名と構成を自動的に比較・チェックする方法を解説しました。手作業では時間と手間がかかり、ミスも発生しやすい作業をマクロで自動化することで、業務効率と精度を大幅に向上させることができます。

今回ご紹介したコードは、そのまま現場で活用できる実用的なものです。ぜひご自身の業務に組み込み、日々のExcel作業をよりスマートに、より確実に進めてみてください。VBAによる自動化は、あなたの業務を大きく変える強力なツールとなるはずです。

コメント

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