Prevent changes to a single column

tiredofit

Well-known Member
Joined
Apr 11, 2013
Messages
1,915
Office Version
  1. 365
  2. 2019
Platform
  1. Windows
Let's assume I have the numbers 1,2,3 in cells A1 through to A3 and the numbers 2,3,4 in cells B1 through to D1.

This is the code to prevent changes to column A:

Code:
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    
    Dim rng As Range

    For Each rng In Target.Cells   
        If rng.Column = 1 Then Call Reverse
    Next rng
    
    Set rng = Nothing
    
End Sub

Private Sub Reverse()

    With Application    
        .EnableEvents = False
        .Undo
        .EnableEvents = True
    End With
    
End Sub

It works as expected if only a single cell is changed.

For example, if I attempt to change the value in cell A1 to say f, the code reverses the change and cell A1 shows the value of 1.

However, if I highight cells A1 and B1, then type something, say e and press Ctrl + Enter, the code reverses the action (and cell A1 shows 1 and cell B1 shows 2 as originally) but what I want is for cell A1 to show the value of 1 (because it's reversed the action) and cell B1 to show the newly entered value of e.

How can I amned my code to achieve this?

Thanks
 

Excel Facts

What do {} around a formula in the formula bar mean?
{Formula} means the formula was entered using Ctrl+Shift+Enter signifying an old-style array formula.
Try this:
VBA Code:
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    Dim colAChanged As Boolean
    Dim nonColAValues As Variant
    Dim cell As Range
    Dim r As Long, c As Long

    ' Check if any cell in column A was changed
    For Each cell In Target
        If cell.Column = 1 Then
            colAChanged = True
            Exit For
        End If
    Next cell

    ' If column A was changed, store values and undo
    If colAChanged Then
        nonColAValues = Target.Value

        Application.EnableEvents = False
        Application.Undo
        Application.EnableEvents = True
       
        ' Restore the stored values only for cells not in column A
        For r = 1 To UBound(nonColAValues, 1)
            For c = 1 To UBound(nonColAValues, 2)
                If Target.Cells(r, c).Column <> 1 Then
                    Target.Cells(r, c).Value = nonColAValues(r, c)
                End If
            Next c
        Next r
    End If

End Sub
 
Upvote 0
Amend to handle single cell, 1-D and 2-D array changes.
VBA Code:
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    Dim colAChanged As Boolean
    Dim nonColAValues As Variant
    Dim cell As Range
    Dim r As Long, c As Long

    For Each cell In Target
        If cell.Column = 1 Then
            colAChanged = True
            Exit For
        End If
    Next cell

    If colAChanged Then
        ' Store the original values of the range before undoing
        nonColAValues = Target.Value

        Application.EnableEvents = False
        Application.Undo
        Application.EnableEvents = True

 
        If IsArray(nonColAValues) Then
            ' Restore the stored values only for cells not in column A
            For r = 1 To UBound(nonColAValues, 1)
                For c = 1 To UBound(nonColAValues, 2)
                    If Target.Cells(r, c).Column <> 1 Then
                        Target.Cells(r, c).Value = nonColAValues(r, c)
                    End If
                Next c
            Next r
        Else
 
            If Target.Column <> 1 Then
                Target.Value = nonColAValues
            End If
        End If
    End If

End Sub
 
Upvote 0
Solution
Amend to handle single cell, 1-D and 2-D array changes.
VBA Code:
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    Dim colAChanged As Boolean
    Dim nonColAValues As Variant
    Dim cell As Range
    Dim r As Long, c As Long

    For Each cell In Target
        If cell.Column = 1 Then
            colAChanged = True
            Exit For
        End If
    Next cell

    If colAChanged Then
        ' Store the original values of the range before undoing
        nonColAValues = Target.Value

        Application.EnableEvents = False
        Application.Undo
        Application.EnableEvents = True

 
        If IsArray(nonColAValues) Then
            ' Restore the stored values only for cells not in column A
            For r = 1 To UBound(nonColAValues, 1)
                For c = 1 To UBound(nonColAValues, 2)
                    If Target.Cells(r, c).Column <> 1 Then
                        Target.Cells(r, c).Value = nonColAValues(r, c)
                    End If
                Next c
            Next r
        Else
 
            If Target.Column <> 1 Then
                Target.Value = nonColAValues
            End If
        End If
    End If

End Sub

Thanks, this is what I was seeking.
 
Upvote 0

Forum statistics

Threads
1,223,588
Messages
6,173,225
Members
452,505
Latest member
Neeraj1990

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top