简体   繁体   中英

Using Worksheet_Change event in VBA, with a range, how to return value of adjacent cell if value is nothing

I'm trying to make use of the Worksheet_Change event in VBA to return the value of the adjacent cell if current cell value is nothing, within provided range. Ie IF current cell F3 is empty, then return contents in cell G3. This formula only applies to cells in range F3 to F37. Here is my current code for which when any cell in range is empty, the code doesn't seem to evaluate (ie copy data from adjacent cell), and remains empty. Any help would be greatly appreciated. Thanks!

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

Set myCell = Range("F3:F37")

If Not Application.Intersect(myCell, Range(Target.Address)) Is Nothing Then
    Target.Value = Cell.Offset(0, 1).Value
End If

End Sub

Modified to:

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

Application.DisplayAlerts = False
Application.EnableEvents = False

Set myCell = Range("F3:F37")

If Not Application.Intersect(myCell, Range(Target.Address)) Is Nothing Then
    If Target.Value = "" Then
        Target.Value = Target.Offset(0, 1).Value
    End If
End If

Application.EnableEvents = True
Application.DisplayAlerts = True

End Sub

If you use Application.EnableEvents = False in an event make sure you use proper error handling and enable events again in case of any error within the event ( VBA Error Handling – A Complete Guide ). Otherwise your events will stay turned off in case of an error until you close the Excel application completely.
Note that Application.EnableEvents affects the whole application that means all Excel files that are opened in that instance of the application. So not having proper error handling here might have a bigger impact on other projetcts than you think.

Another trap you fell into, is that Target can be a Range (not only a single cell). So for example if you copy/paste a range that affects multiple cells in F3:F37 your Target is not a single cell and therefore Target.Value = "" does not work. You need a loop through all the affected cells:

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim CheckRange As Range
    Set CheckRange = Me.Range("F3:F37") 'Make sure you use "Me" to refer to the same worksheet as Target (and the change event is in)

    Dim AffectedCells As Range 'get the cells of CheckRange that were changed
    Set AffectedCells = Application.Intersect(CheckRange, Target)


    Application.EnableEvents = False
    On Error GoTo ENABLE_EVENTS 'make sure you never end up in a condition where events stay disabled

    If Not AffectedCells Is Nothing Then
        Dim Cell As Range
        For Each Cell In AffectedCells 'loop throug all the affected cells
            If Cell.Value = "" Then
                Cell.Value = Cell.Offset(0, 1).Value
            End If
        Next Cell
    End If

    'no exit sub here!
ENABLE_EVENTS:
    Application.EnableEvents = True
    If Err.Number <> 0 Then 'make sure to re-raise an error message if there was an error (otherwise you won't ever notice that there was one), because the `On Error GoTo` statement muted the error message.
        Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
        'above line to raise the original error message
        'or at least show a message box:
        'MsgBox "There was an error. Tell your Developer to fix it.", vbCritical
    End If
End Sub

Note that I removed Application.DisplayAlerts because there is nothing in the code that would display any alerts, so I see no need to use it in this case here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM