セルの値変更を自動で履歴として記録する方法! 変更前・変更後の値を保存するVBA | EXCELトピックス

スポンサーリンク
スポンサーリンク

セルが変更されたら自動的に履歴を記録する方法

Excelでは、セルの値を変更すると元の値が失われてしまいます。しかし、VBAを使用することで、セルの変更前・変更後の値を自動で記録し、履歴を保存することが可能です。

例えば、売上データやタスクの進捗を管理する際に、「いつ・誰が・どのセルを変更したのか」を記録することで、データの追跡が容易になります。

VBAの作成と実行

  1. [開発]→[Visual Basic]を開き、対象のシート(例: Sheet1)を選択する。
  2. VBAエディターの[Microsoft Excel Objects]内にある「Sheet1」のコードウィンドウを開く。
  3. 以下のコードを貼り付ける。
  4. Excelのシートでセルを変更すると、「変更履歴」シートに変更履歴が記録される。

セルの変更履歴を自動で記録するVBAコード

このVBAを適用すると、セルの変更前・変更後の値が「変更履歴」シートに自動で記録されます。

Dim OldValues As Object ' 変更前の値を保存する辞書

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim cell As Range
    
    ' 変更前の値を記録するための辞書を初期化
    Set OldValues = CreateObject("Scripting.Dictionary")
    
    ' 選択されたセルの値を辞書に保存
    For Each cell In Target
        If Not IsEmpty(cell.Value) Then
            OldValues(cell.Address) = cell.Value
        Else
            OldValues(cell.Address) = "(空白)"
        End If
    Next cell
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim cell As Range
    Dim oldValue As String

    ' 「変更履歴」シートが存在するか確認し、なければ作成
    On Error Resume Next
    Set ws = ThisWorkbook.Sheets("変更履歴")
    On Error GoTo 0

    If ws Is Nothing Then
        Set ws = ThisWorkbook.Sheets.Add
        ws.Name = "変更履歴"
        ' 見出しを設定
        ws.Cells(1, 1).Value = "No."
        ws.Cells(1, 2).Value = "変更日時"
        ws.Cells(1, 3).Value = "変更者"
        ws.Cells(1, 4).Value = "セルアドレス"
        ws.Cells(1, 5).Value = "変更前の値"
        ws.Cells(1, 6).Value = "変更後の値"
    End If

    ' 変更履歴を記録(複数セルの変更にも対応)
    For Each cell In Target
        ' 変更前の値を取得(辞書にない場合は空白)
        If OldValues.Exists(cell.Address) Then
            oldValue = OldValues(cell.Address)
        Else
            oldValue = "(不明)"
        End If

        ' 履歴の最終行を取得
        lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
        ws.Cells(lastRow, 1).Value = lastRow - 1
        ws.Cells(lastRow, 2).Value = Now
        ws.Cells(lastRow, 3).Value = Application.UserName
        ws.Cells(lastRow, 4).Value = cell.Address
        ws.Cells(lastRow, 5).Value = oldValue ' 変更前の値
        ws.Cells(lastRow, 6).Value = cell.Value ' 変更後の値
    Next cell
End Sub

コードの解説

  • Dim OldValues As Object – `OldValues` という辞書オブジェクトを作成し、変更前のセルの値を保存するために使用します。
  • Worksheet_SelectionChange – セルが選択された際に呼び出されるイベントで、変更前のセルの値を記録します。
  • Set OldValues = CreateObject("Scripting.Dictionary") – 変更前の値を保存するための辞書を作成します。
  • For Each cell In Target – ユーザーが選択したセルが複数の場合、それぞれのセルの値を辞書に記録します。
  • Worksheet_Change – セルの値が変更された際に呼び出されるイベントで、履歴を「変更履歴」シートに記録します。
  • If ws Is Nothing Then – 「変更履歴」シートが存在しない場合は、新規作成して見出しを設定します。
  • For Each cell In Target – 変更されたセルが複数の場合、それぞれについて履歴を記録します。
  • If OldValues.Exists(cell.Address) Then – 変更前の値が辞書に存在する場合、それを取得し、履歴に記録します。
  • lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1 – 「変更履歴」シートの最終行を取得し、新しい履歴を記録する位置を決定します。

動作イメージ

  A B C D E
1 2025/02/03 12:00 User1 $A$1 元の値 変更後の値
2 2025/02/03 12:05 User2 $B$2 旧データ 新データ

まとめ

  • VBAを使用することで、セルの変更前・変更後の値を自動で履歴として記録できる。
  • 変更履歴は「変更履歴」シートに記録され、履歴の管理が容易になる。
  • 「変更履歴」シートがない場合は自動で作成されるため、事前準備が不要。
  • 複数のセルを同時に変更しても、それぞれのセルについて正確に履歴を残すことができる。