[vba] How do I get the old value of a changed cell in Excel VBA?

I have read this old post, and I would like to provide another solution.

The problem with running Application.Undo is that Woksheet_Change runs again. We have the same problem when we restore.

To avoid that, I use a piece of code to avoid the second steps through Worksheet_Change.

Before we begin, we must create a Boolean static variable BlnAlreadyBeenHere, to tell Excel not to run Worksheet_Change again

Here you can see it:

    Private Sub Worksheet_Change(ByVal Target As Range)

    Static blnAlreadyBeenHere As Boolean

    'This piece avoid to execute Worksheet_Change again
    If blnAlreadyBeenHere Then
        blnAlreadyBeenHere = False
        Exit Sub
    End If

    'Now, we will store the old and new value
    Dim vOldValue As Variant
    Dim vNewValue As Variant

    'To store new value
    vNewValue = Target.Value

    'Undo to retrieve old value

    'To avoid new Worksheet_Change execution
    blnAlreadyBeenHere = True

    Application.Undo

    'To store old value
    vOldValue = Target.Value

    'To rewrite new value

    'To avoid new Worksheet_Change execution agein
    blnAlreadyBeenHere = True
    Target.Value = vNewValue

    'Done! I've two vaules stored
    Debug.Print vOldValue, vNewValue

End Sub

The advantage of this method is that it is not necessary to run Worksheet_SelectionChange.

If we want the routine to work from another module, we just have to take the declaration of the variable blnAlreadyBeenHere out of the routine, and declare it with Dim.

Same operation with vOldValue and vNewValue, in the header of a module

Dim blnAlreadyBeenHere As Boolean
Dim vOldValue As Variant
Dim vNewValue As Variant