Excel VBAでイベントログを自動記録する仕組みを作る〜 誰が・いつ・何をしたかを自動で残すマクロ 〜

Excel VBA

Excelのブックを複数人で使っていると、
「誰がこのセルを変えた?」「いつデータを上書きした?」といったトラブルがよく起きます。
SharePointやTeams上で履歴を取る方法もありますが、
もっと手軽に VBAだけで“変更履歴ログ”を残す ことができるのをご存知ですか?

この記事では、
Excel VBAの 「イベントプロシージャ」 を使って、
「ブックを開いた/シートを変更した/保存した」などの動作を自動的に検知し、
その内容を別シートに時系列で記録していく仕組みを紹介します。

イベントを使うと何ができるか?

通常のマクロは「ボタンを押すと動く」ものですが、
イベントプロシージャ を使うと、Excelの動作そのものに反応して処理を実行できます。

たとえば:

  • ブックを開いたとき → 「Openイベント」
  • セルが変更されたとき → 「Changeイベント」
  • 保存されたとき → 「BeforeSaveイベント」

これらを組み合わせることで、
Excelが「勝手に」あなたの作業を監視・記録してくれるようになります。

全体の仕組み概要

ログを取る仕組みの全体像は次の通りです。

  1. 「Log」という専用シートを作る

  2. Workbook_Open イベントで、開いた人・時刻を記録

  3. Workbook_SheetChange イベントで、編集内容を記録

  4. Workbook_BeforeSave イベントで、保存ログを残す

  5. ログが増えすぎないよう、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

excel vba

■実行例

excel vba

コード解説

Workbook_Open イベント

ブックを開いた瞬間に動作します。
誰が・いつ開いたかを自動記録します。

Workbook_SheetChange イベント

シートのどのセルを変更したかを検知。
セルのアドレスとシート名をログに残します。
例:「シート[売上表]の$C$5を変更」

Workbook_BeforeSave イベント

保存の直前に発火します。
「誰が保存したか」を記録します。

WriteLog プロシージャ

実際にログを書き込む処理をまとめています。
Environ("USERNAME") でWindowsユーザー名を取得し、
時刻・操作内容・ブック名を「Log」シートに追記します。

ログが増えすぎた場合は、古い行(先頭50件)を自動削除する設計にしています。

応用アイデア

上記の基本を押さえたら、こんな応用もできます。

ユーザーごとの操作集計

Logシートのデータをピボットテーブルにして、
「誰が一番編集しているか」を可視化できます。
チーム共有ブックの監査にも便利です。

ファイルへの出力

WriteLog 内に下記コードを追加すると、
ログをテキストファイルに追記することも可能です。

Open ThisWorkbook.Path & "\操作ログ.txt" For Append As #1 
Print #1, logTime & "," & userName & "," & message 
Close #1

これにより、「ブックを閉じても残る」操作履歴が得られます。

特定シートのみ記録

頻繁に変わる入力シートだけ監視したい場合は、
If Sh.Name = "入力" Then ... などの条件分岐を追加すればOKです。

パスワードで改ざん防止

Logシートを非表示にして、VeryHidden に設定すると、
一般ユーザーが勝手に消すことを防げます。

トラブル対策&注意点

  • 「イベントが動かない」場合
     → コードは「ThisWorkbook」モジュールに書かれているか確認してください。
     → 標準モジュールではイベントは動きません。

  • 「開いた瞬間にセキュリティ警告が出る」
     → マクロ有効ブック(*.xlsm)として保存する必要があります。
     → 信頼済みフォルダに置くと警告を減らせます。

  • 「複数人が同時に開くと競合する」
     → 共有ブックではイベントの順序が不安定になるため、
      OneDrive共有などでは注意が必要です。

実際に使ってみると…

このログシステムを導入すると、
「このファイル、誰がいつ触った?」という問いに即答できます。
また、ミスの再現やトラブルの原因調査にも役立ちます。

実務では、特に次のような場面で効果を発揮します。

  • 経理・営業の共有Excelで入力履歴を残す
  • 複数担当者が更新する進捗管理表
  • 外部提出用ファイルの「作業証跡」を残したい場合

まさに「マニアックだけど現場が助かるVBA」の代表例です。

まとめ:VBAで“裏方の自動化”を楽しもう

VBAと聞くと、「業務効率化のための自動処理」という印象が強いですが、
こうした“裏方の自動記録”のような用途こそ、
現場のトラブルを防ぎ、信頼性を高める強力な活用法です。

今回紹介したイベントログVBAをベースに、
自分の業務やチーム運用に合わせてカスタマイズしてみてください。

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