Excelのブックを複数人で使っていると、
「誰がこのセルを変えた?」「いつデータを上書きした?」といったトラブルがよく起きます。
SharePointやTeams上で履歴を取る方法もありますが、
もっと手軽に VBAだけで“変更履歴ログ”を残す ことができるのをご存知ですか?
この記事では、
Excel VBAの 「イベントプロシージャ」 を使って、
「ブックを開いた/シートを変更した/保存した」などの動作を自動的に検知し、
その内容を別シートに時系列で記録していく仕組みを紹介します。
イベントを使うと何ができるか?
通常のマクロは「ボタンを押すと動く」ものですが、
イベントプロシージャ を使うと、Excelの動作そのものに反応して処理を実行できます。
たとえば:
- ブックを開いたとき → 「Openイベント」
- セルが変更されたとき → 「Changeイベント」
-
保存されたとき → 「BeforeSaveイベント」
これらを組み合わせることで、
Excelが「勝手に」あなたの作業を監視・記録してくれるようになります。
全体の仕組み概要
ログを取る仕組みの全体像は次の通りです。
-
「Log」という専用シートを作る
-
Workbook_Open
イベントで、開いた人・時刻を記録 -
Workbook_SheetChange
イベントで、編集内容を記録 -
Workbook_BeforeSave
イベントで、保存ログを残す -
ログが増えすぎないよう、1000件超えたら古いものを自動削除
コードは少し長く見えますが、実際は順を追えば簡単です。
コード全体(ThisWorkbookモジュール)
以下のコードを「ThisWorkbook」モジュールに貼り付けます。
Option Explicit
Private Sub Workbook_Open()
Call WriteLog("ブックを開きました")
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Call WriteLog("ブックを保存しました")
End Sub
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
' Logシートならスキップ
If Sh.Name = "Log" Then Exit Sub
Dim msg As String
msg = "シート[" & Sh.Name & "]の" & Target.Address & "を変更"
Call WriteLog(msg)
End Sub
Private Sub WriteLog(ByVal message As String)
Dim ws As Worksheet
Dim nextRow As Long
Dim userName As String
Dim logTime As String
On Error GoTo SafeExit
Application.EnableEvents = False
Set ws = GetLogSheet()
nextRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
userName = Environ("USERNAME")
logTime = Format(Now, "yyyy/mm/dd hh:nn:ss")
ws.Cells(nextRow, 1).Value = logTime
ws.Cells(nextRow, 2).Value = userName
ws.Cells(nextRow, 3).Value = message
ws.Cells(nextRow, 4).Value = ThisWorkbook.Name
SafeExit:
Application.EnableEvents = True
End Sub
Private Function GetLogSheet() As Worksheet
On Error Resume Next
Set GetLogSheet = ThisWorkbook.Worksheets("Log")
On Error GoTo 0
If GetLogSheet Is Nothing Then
Set GetLogSheet = ThisWorkbook.Worksheets.Add
GetLogSheet.Name = "Log"
GetLogSheet.Range("A1:D1").Value = Array("時刻", "ユーザー", "操作内容", "ブック名")
End If
End Function
■実行例
コード解説
Workbook_Open イベント
ブックを開いた瞬間に動作します。
誰が・いつ開いたかを自動記録します。
Workbook_SheetChange イベント
シートのどのセルを変更したかを検知。
セルのアドレスとシート名をログに残します。
例:「シート[売上表]の$C$5を変更」
Workbook_BeforeSave イベント
保存の直前に発火します。
「誰が保存したか」を記録します。
WriteLog プロシージャ
実際にログを書き込む処理をまとめています。Environ("USERNAME")
でWindowsユーザー名を取得し、
時刻・操作内容・ブック名を「Log」シートに追記します。
ログが増えすぎた場合は、古い行(先頭50件)を自動削除する設計にしています。
応用アイデア
上記の基本を押さえたら、こんな応用もできます。
ユーザーごとの操作集計
Logシートのデータをピボットテーブルにして、
「誰が一番編集しているか」を可視化できます。
チーム共有ブックの監査にも便利です。
ファイルへの出力
WriteLog
内に下記コードを追加すると、
ログをテキストファイルに追記することも可能です。
これにより、「ブックを閉じても残る」操作履歴が得られます。
特定シートのみ記録
頻繁に変わる入力シートだけ監視したい場合は、If Sh.Name = "入力" Then ...
などの条件分岐を追加すればOKです。
パスワードで改ざん防止
Logシートを非表示にして、VeryHidden
に設定すると、
一般ユーザーが勝手に消すことを防げます。
トラブル対策&注意点
-
「イベントが動かない」場合
→ コードは「ThisWorkbook」モジュールに書かれているか確認してください。
→ 標準モジュールではイベントは動きません。 -
「開いた瞬間にセキュリティ警告が出る」
→ マクロ有効ブック(*.xlsm)として保存する必要があります。
→ 信頼済みフォルダに置くと警告を減らせます。 -
「複数人が同時に開くと競合する」
→ 共有ブックではイベントの順序が不安定になるため、
OneDrive共有などでは注意が必要です。
実際に使ってみると…
このログシステムを導入すると、
「このファイル、誰がいつ触った?」という問いに即答できます。
また、ミスの再現やトラブルの原因調査にも役立ちます。
実務では、特に次のような場面で効果を発揮します。
- 経理・営業の共有Excelで入力履歴を残す
- 複数担当者が更新する進捗管理表
-
外部提出用ファイルの「作業証跡」を残したい場合
まさに「マニアックだけど現場が助かるVBA」の代表例です。
まとめ:VBAで“裏方の自動化”を楽しもう
VBAと聞くと、「業務効率化のための自動処理」という印象が強いですが、
こうした“裏方の自動記録”のような用途こそ、
現場のトラブルを防ぎ、信頼性を高める強力な活用法です。
今回紹介したイベントログVBAをベースに、
自分の業務やチーム運用に合わせてカスタマイズしてみてください。