19. VBA Tips - Log An Audit Trail

Logging an audit trail of your changes can be useful, and can be done with a small amount of VBA...
Here's our data:
Here's a screen shot of what we're trying to achieve:
Here's the code to do it (put in the worksheet's macro module):
Explanation:
- PreviousValue is a variable that we Dim outside the sub routines so that it's available to both routines
- When you select a different cell, PreviousValue is set to the value of the cell that you have selected
- This is set via the Worksheet_SelectionChange event
- When you change a cell's value, the Worksheet_Change sub routine is run and it compares the new value (Target.value) with PreviousValue... logging if there has been a change.
- The Log sheet contains details of the changes including the name of the person who changed the cell, what cell was changed, and what it went from and to.
Download sheet to practise how to Log An Audit Trail in Excel
Training Video on how to Log An Audit Trail in Excel:
| Attachment | Size |
|---|---|
| log-an-audit-trail.xls | 40 KB |
»
- Nick's blog
- Add new comment
- 12632 reads

code for logging the changes in a workbook
is it possible for you to publish a code that logging the changes in the entire workbook, and not only in one worksheet??
regards,
Ziv
code for logging the changes in a workbook
Hi
All you have to do is to add the code to each worksheet you want to log changes to.
... and if you want to add the worksheet name, change the code to:
Nick
code for logging the changes in a workbook
log changes to file
Following code in
Following code in Thisworkbook macro module can log the changes in whole workbook except the one named 'Log' for logging.
Dim PreviousValue
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Sh.Name = "Log" Then Exit Sub
If Target.Value <> PreviousValue Then
Application.EnableEvents = False
Sheets("log").Cells(65000, 1).End(xlUp).Offset(1, 0).Value = _
Application.UserName & " changed cell " & Sh.Name & "." & Target.Address _
& " from " & PreviousValue & " to " & Target.Value
Application.EnableEvents = True
End If
End Sub
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
PreviousValue = Target.Value
End Sub
Changing multiple cells simultaneously
Great post, by the way.
Is there any way that the code can be changed to handle copying and pasting more than one cell at a time?
Nick
Changing multiple cells simultaneously
NOTE the result of copying col 1 into col 2:
- you get the same cell address
Audit trailing
Log an audit trail
I think this might be what you want then:
Change:
If Target.Value <> PreviousValue Then
to:
If Target.Value <> PreviousValue and Target.Value <> 0 Then
Audit trail for Merged Cells
Hi Nick,
Thanks for the codes. They are very helpful.
In adidition to the code where changes to more than one cell at a time is recorded, is it possible to have a code to audit trail 5 cells, which are merged.
merged cells
merged cells count as 1, no ?
You can pick up all the cells in a merged range, use Selection.MergeArea
Using selection.mergearea
what is the proper syntax for this? how can we use this? I tried using this by changing this original code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
PreviousValue = Target.Value
End Sub
to
Private Sub Worksheet_SelectionMergeArea(ByVal Target As Range)
PreviousValue = Target.Value
End Sub
-- It seemed to work but then it appears that the logs created are always stuck at the PreviousValue returning a 'blank' value.
Changing multiple cells
Hi Nick,
i input this code and tested it and was working great. I now have entered the spreadsheet again and it no longer records the log. It doesn't give me any errors or anything. I've checked the code and it's exactly the same. Do you know why this would be happening? No one has opened it since. Not sure why it would just stop working as the code is still there.
Thanks,
Did you enable macros when
Did you enable macros when opening ?
Also, are events enabled.. maybe another bit of VBA turns off events.
- try opening in a new Excel session making sure macros are enabled.
This macro is SUPERB!
Is it possible to protect the log worksheet so that users can't modify it? Thanks!
log changes
yes.. just Record a Macro of protecting and unprotecting the sheet with a password.
unprotect at the beginning, and protect at the end.
Audit trail for Merged Cells
Hi Nick,
Thanks for the codes. They are very helpful.
In addition to the code where changes to more than one cell at a time is recorded, is it possible to have a code to audit trail 5 cells, which are merged.
Thanks,
Naresh
merged cells
see the answer above
Audit Rail
How can i add a date to the Audit trail code given?
Add date to audit trail
Thx!
turn off events
Application.enableevents = falseApplication.enableevents = trueInserting rows/columns
Hi,
I find your macro quite useful. However, i am having problems when I insert colmns - creates all logs for the created blank cells which is a bit too much. Can the log just say that a new column has been inserted?
Thanks!
logging column insert
the logging procedure is designed for an end-user system... the end user should not be inserting columns.
Recommend excluding events where the range impacted is more than one cell.
At the start of the sub, put:
if Target.rows.count>1 then exit sub
if Target.columns.count>1 then exit sub
Nick
what triggers the subroutine?
The code itself totally makes sense; what I don't understand is the link between typing in the cell and kicking off the sub.
events
Excel traps a number of events like opening a workbook, selecting a worksheet, changing a value on a worksheet etc..
This is inbuilt to Excel..
Update from a Website
Hello.I have a table who's on a website, and when i click to update in excel it says me error 13.Any solution for this bug?Thanks you very much!
Re:
I have the solution but now why when i update the website table don't write on log the changes?Anybody knows?thanks for your help
Error Only
Hi,
Anyway I can edit it to log if user entered an invalid data together with the time and data entered?
Thanks.
Chk this url as
Chk this url as well
http://excelexperts.com/cell-content-change-history-comments
Auditing a single cell changes
Hi Nick,
We need to audit changes only to a single cell on the spreadsheet. Could you please show the code?
Thank you,
Viki
add this line at the start of
add this line at the start of the logging code:
if target.address <> Range("RangeToMonitor").address then exit sub
where "RangeToMonitor" is the range you're monitoring...
writing to access
Hi nik, i have an audit trail which writes changes to an access database, it is all fine, excpept i need to know how to send the previous cell value and previous formula value to the database. It works fine when sending it to another workbook/worksheet, just not to a databse
here is my code so far:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim Cn As ADODB.Connection
Dim oCm As ADODB.Command
Dim logDate As String
Dim logTime As String
Dim logAuthor As String
Dim logWorkbook As String
Dim logWorksheet As String
Dim logcellchange As String
Dim logPrev As String
Dim logNew As String
Dim logPrevForm As String
Dim logNewForm As String
Dim sOldAddress As String
Dim vOldValue As Variant
Dim sOldFormula As String
Dim iRecAffected As Integer
logWorkbook = ThisWorkbook.Name
logWorksheet = Sh.Name
logAuthor = Application.UserName
logDate = Format(Now(), "hh:mm:ss")
logTime = Format(Now(), "dd/mmm/yyyy")
logcellchange = Target.Address
'logPrev = Target.Previous.Value
logNew = Target.Value
'logPrevForm = ActiveCell.Value
logNewForm = Target.Formula
If Target.Rows.Count > 1 Then
Set Cn = New ADODB.Connection
Cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=G:\log.accdb;Persist Security Info=False"
Cn.ConnectionTimeout = 40
Cn.Open
Set oCm = New ADODB.Command
oCm.ActiveConnection = Cn
oCm.CommandText = "Insert Into AuditTrail (Workbook, Worksheet, Author, DateDetails, TimeDetails, ChangedCell, OldValue, NewValue, OldFormula, NewFormula) Values ('" & logWorkbook & "','" & logWorksheet & "','" & logAuthor & "','" & logDate & "','" & logTime & "','" & logcellchange & "','" & sOldAddress & "','" & logNew & "','" & sOldFormula & "','" & logNewForm & "')"
oCm.Execute iRecAffected
End If
If Target.Columns.Count > 1 Then
Set Cn = New ADODB.Connection
Cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=G:\log.accdb;Persist Security Info=False"
Cn.ConnectionTimeout = 40
Cn.Open
Set oCm = New ADODB.Command
oCm.ActiveConnection = Cn
oCm.CommandText = "Insert Into AuditTrail (Workbook, Worksheet, Author, DateDetails, TimeDetails, ChangedCell, OldValue, NewValue, OldFormula, NewFormula) Values ('" & logWorkbook & "','" & logWorksheet & "','" & logAuthor & "','" & logDate & "','" & logTime & "','" & logcellchange & "','" & sOldAddress & "','" & logNew & "','" & sOldFormula & "','" & logNewForm & "')"
oCm.Execute iRecAffected
End If
End Sub
Is there a way to make this report to a .Log file instead?
I\\\'m looking at this code, and I love what it does, but I\\\'ve been asked if there is a way to make this report to a log file instead of an excel sheet, only because the person that is asking wants to read this outside of the excel sheet, just in case something went wrong and corrupted the sheet there is a possibility to see why that happened.
Thanks.
we\'d very happy to write
we\'d very happy to write this for you on a consultancy basis..
http://excelexperts.com/contact
tks
Nick