MS Excel工作表更改事件 – 保留旧的单元格值与新值的logging

我是这个论坛的新手,但是由于我当前angular色的VBA需求,在过去的几个月中一直在积累我的编码经验。 今天的问题已经看到我通过许多网站(和我的Excel VBA傻瓜书)拖网,但我还没有完全钉牢它。

我正在尝试在Excel中为我们的公司Risk Register创build一个审计跟踪文件。 这个想法是,一旦build立了风险登记簿,任何变更都将创build一个显示旧logging和新logging的审计追踪(在单独的选项卡上)。

我已经使用Change Event处理程序编写了代码。 每次发生更改时,我都希望我的macros启动,并执行以下操作:
1.引用旧的单元格值(用户刚覆盖的内容)
2.跳转到“审计跟踪”选项卡并粘贴完整风险logging的两个副本 – 每个风险logging是一行数据,占用17列
3.在这17列的第一个副本中,确定编辑了哪一列,并用旧单元格值replace此单元格(在第1步中捕获)
4.插入一个时间戳
5.有条件格式高亮显示已经改变的logging[这个function在代码中是不需要的,因为我已经在电子表格中设置了它]
6.跳回到用户刚刚编辑的单元格(在“风险注册”选项卡上)

我已经pipe理步骤1,2和4-7,但我有问题得到代码input“旧单元格值”到“审计跟踪”选项卡中的正确位置。 如果我手动定义要粘贴的单元格范围,我可以在那里得到它,但我似乎无法使其dynamic化,以便它会自动识别用户正在更改的字段,并确保在审计中修改相同的字段落后。

真的很感谢为什么“ PasteRange.Value =工作表(”风险注册“)。范围(”oldValuePaste“) ”行不工作

我的代码如下:

Dim oldValue As Variant Dim LastRow As Long Private Sub Worksheet_SelectionChange(ByVal Target As Range) Application.ScreenUpdating = False If Not Intersect(Target, Range("b13:r13")) Is Nothing Then oldValue = Target.Value End If Application.ScreenUpdating = True End Sub Private Sub Worksheet_Change(ByVal Target As Range) Application.ScreenUpdating = False If Not Intersect(Target, Range("b13:r14")) Is Nothing Then If Target.Value <> oldValue Then 'MsgBox "You just changed " & Target.Address Cells(65, 5).Value = oldValue 'this cell is a named range called: OldValuePaste Cells(66, 5).Value = Target.row 'this cell is a named range called: OldValueRowNumber Cells(67, 5).Value = Target.Column 'this cell is a named range called: OldValueColumnNumber Range(Cells(Target.row, 2), Cells(Target.row, 18)).Copy 'Cells(70, 2).PasteSpecial xlPasteValues Call Paste_on_AuditSheet Sheets("Risk Register").Activate Target.Select Application.CutCopyMode = False End If End If Application.ScreenUpdating = True End Sub _____________________________________________________________________________________________________ Sub Paste_on_AuditSheet() Application.ScreenUpdating = False Dim LastRow As Long Dim ColNum As Long Dim PasteRange As Range ColNum = OldValueColumnNumber Sheets("Audit trail").Select 'MsgBox "Activated " & ActiveSheet.Name 'Find the last used row in a Column: column B in this example With ActiveSheet LastRow = .Cells(.Rows.Count, "B").End(xlUp).row End With Set PasteRange = Cells(LastRow, ColNum) 'The following two lines bring in the new data and paste into old record and new record sections: Cells(LastRow + 1, 2).PasteSpecial xlPasteValues Cells(LastRow + 1, 20).PasteSpecial xlPasteValues 'Then this line goes back over the piece just pasted in and changes one cell in "old record" section to what it was prior to the edit: 'PasteRange.Value = Worksheets("Risk Register").Range("oldValuePaste") 'Above line of code is not working, but can get it to do the right thing using this code (although it's not dynamic): Range("E3").Value = Worksheets("Risk Register").Range("oldValuePaste") 'Add a time stamp: Cells(LastRow + 1, 1) = Now Application.ScreenUpdating = True End Sub 

最后一点 – 尽pipe我重复使用Application.ScreenUpdating命令,我仍然得到一些屏幕闪烁 – 任何想法,为什么?

先谢谢您的帮助!

在审查你的代码时,我看到了一些我不认为会按照你的意思工作的东西,同时也认识到你的代码可以变得更简单,只需从Worksheet_Change事件中调用。

所以下面的重构代码,让我知道如果你有问题:

 Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Range("b13:r14")) Is Nothing Then 'get oldValue Dim sNewVal As String, sOldVal As String sNewValue = Target.Value 'store current or "new" value since this is what is stored after the cell change takes place With Application .EnableEvents = False 'turns off event firing so the code will not go into endless loop .Undo 'undo the change (to store old value in next line) End With sOldValue = Target.Value 'store old value Target.Value = sNewValue 'reset new value Dim lCol As Long lCol = Target.Column 'which column of data was changed 'assumes columns AQ are 17 columns Me.Range(Me.Cells(Target.Row, 1), Me.Cells(Target.Row, 17)).Copy With Sheets("Audit Trail") Dim lRow As Long lRow = .Range("B" & .Rows.Count).End(xlUp).Offset(1).Row .Range("B" & lRow).PasteSpecial xlPasteValues .Range("B" & lRow + 1).PasteSpecial xlPasteValues .Range("A" & lRow).Value = Now .Cells(lRow, lCol + 1).Value = sOldValue 'store old value in first pasted line ... add 1 since starting from column B End With End If Application.EnableEvents = True End Sub