修改Excel VBA单元格变更追踪代码:排除行增删触发场景
解决Excel VBA单元格变更追踪中行增删报错的问题
原代码可追踪单元格值变更,但添加或删除行时会触发代码执行并报错,以下是修改后的代码,仅在单元格值更新时运行追踪逻辑:
Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) ' 排除整行/整列的变更(行/列增删操作会触发这类Target) If Target.EntireRow.Address = Target.Address Or Target.EntireColumn.Address = Target.Address Then Exit Sub End If Dim wb As Workbook Dim ws2 As Worksheet Dim NextRow As Long Dim j As Range Dim CellAdd As String Dim sht As String Dim newValue As Variant Dim oldValue As Variant Set wb = ThisWorkbook Set ws2 = wb.Worksheets("Change Log") ' 用于记录变更的工作表 sht = Me.Name ' 改用Me.Name获取当前工作表名,比ActiveSheet更可靠 ' 遍历每个变更的单元格 For Each j In Target ' 跳过合并单元格的子单元格(避免重复记录) If j.MergeCells Then If j.Address <> j.MergeArea.Address Then Continue For End If End If ' 获取新值 newValue = j.Value Application.EnableEvents = False ' 撤销操作获取旧值 Application.Undo oldValue = j.Value ' 再次撤销恢复新值 Application.Undo Application.EnableEvents = True ' 计算日志表的下一行 NextRow = ws2.Cells(ws2.Rows.Count, 1).End(xlUp).Row + 1 ' 写入变更日志 ws2.Cells(NextRow, 1) = sht & " - " & j.Address & _ " 被修改为 '" & newValue & "',原内容为 '" & _ oldValue & "',修改人:" & Environ("username") & _ ",修改时间:" & Format(Now(), "M-DD-YYYY H:MM:ss") Next j End Sub
关键修改说明
- 排除行/列增删触发:通过判断
Target是否为整行或整列,直接退出过程,避免行增删时执行后续逻辑导致报错。 - 变量优化:将所有变量声明移至过程开头,符合VBA编码规范;改用
Me.Name获取当前工作表名,比ActiveSheet.Name更可靠,避免切换工作表时出现错误。 - 合并单元格处理:跳过合并单元格的子单元格,避免重复记录同一合并区域的变更。
- 事件防护:全程确保
Application.EnableEvents在操作前后正确切换,防止事件递归触发。
内容的提问来源于stack exchange,提问作者A J
相关产品推荐
相关产品推荐

