3

I am trying to use the Worksheet Change Event in Excel VBA, but it doesn't seem to working how I thought it would.

I basically want to calculate a cells value (Q2) when the value of another cell (R2) is changed or vise versa.

Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Cells.Count > 1 Then Exit Sub
    If Intersect(Target, Range("O:R")) Is Nothing Then Exit Sub

    Application.EnableEvents = False

    If Target.Column = 3 Then
    'User has changed something in column Q:
        Target.Offset(0, 1).Value = Cells(2, 3) * Cells(2, 1)
    If Target.Column = 4 Then
    'User has changed something in column R:
        Target.Offset(0, -1).Value = Cells(2, 3) / Cells(2, 1)
    End If

    Application.EnableEvents = True
End Sub
1
  • 1
    You need to close off multiline If statements with End IF as well Commented Mar 19, 2017 at 22:58

2 Answers 2

4
Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Cells.CountLarge > 1 Then Exit Sub
    If Intersect(Target, Range("O:R")) Is Nothing Then Exit Sub

    Application.EnableEvents = False

    'If Target.Column = 17 Then 'CHANGED HERE!
        'User has changed something in column Q:
         'Target.Offset(0, 1).Value = Cells(2, 3) * Cells(2, 1)
    'End If
    'If Target.Column = 18 Then 'CHANGED HERE!
        'User has changed something in column R:
        'Target.Offset(0, -1).Value = Cells(2, 3) / Cells(2, 1)
    'End If

    ' I leave the If-versions above for info, but Select Case is better sometimes
    Select Case Target.Column
    Case 17 ' column Q
        Target.Offset(0, 1).Value = Cells(2, 3) * Cells(2, 1)
    Case 18 ' column R
        Target.Offset(0, -1).Value = Cells(2, 3) / Cells(2, 1)
    End Select

    Application.EnableEvents = True
End Sub

Q Column is number 17, and Column R is number 18 as shown above.

Sign up to request clarification or add additional context in comments.

2 Comments

I'm not sure but I believe that Range("O:R") should be Range("Q:R").
looked at that Jeeped :) But I though that best left to the OP to fill in if he wants to do something in changing column O
3

Don't avoid working with multiple cells as the Target. Intersect can quickly parse down even deleting several full columns to the appropriate range and further restrict to the worksheet's UsedRange.

Add error control, especially to the division operation. A blank cell in A2 will quickly choke the calculation on a 'divide-by-zero'.

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    'deal with multiple cells as bel;ow; don't avoid them
    'If Target.Cells.Count > 1 Then Exit Sub

    'use the Intersect to determine if relevant cells have been chanmged
    'note: columns Q:R, not O:R and restrict to the used range
    If Not Intersect(Target, Target.Parent.UsedRange, Range("Q:R")) Is Nothing Then
        On Error GoTo Safe_Exit
        Application.EnableEvents = False
        Dim trgt As Range
        For Each trgt In Intersect(Target, Target.Parent.UsedRange, Range("Q:R"))
            Select Case trgt.Column
                Case 17
                    'guard against multiplying a number by text
                    If Not IsError(Cells(2, 3).Value2 * Cells(2, 1).Value2) Then
                        trgt.Offset(0, 1) = Cells(2, 3).Value2 * Cells(2, 1).Value2
                    End If
                Case 18
                    'guard against possible #DIV/0! error and divding a number by text
                    If Not IsError(Cells(2, 3).Value2 / Cells(2, 1).Value2) Then
                        trgt.Offset(0, -1) = Cells(2, 3).Value2 / Cells(2, 1).Value2
                    End If
            End Select
        Next trgt
    End If  

Safe_Exit:
    Application.EnableEvents = True
End Sub

I'm pretty sure that the actual calculation should involve a variable like trgt.Row but your posted calculation only used C2 and A2 as static cell references to divide/multiply against each other.

6 Comments

I tried both your code and MacroMarc's code and didn't get any results. Here is my reply to him, because maybe I did not explain what I am trying to do well enough. I probably didn't explain this properly, but I defined O:R because the calculation I am trying to accomplish uses a cell is column O. What I want to calculate is if user changes sell Q2, then R2 = O2 * Q2 or if user changes cell R2, then Q2 = R2 / O2.
I explained that in my narrative; I don't think that small modification is hard to figure out.
Well I just started using VBA so sorry if I'm not understanding right away. Is the Cells() function restricted to the defined range, or does it reference the entire worksheet regardless of the defined range?
In a Worksheet_Change (a private sub on a worksheet's code sheet), Cells(row, column) will always refer to that worksheet so column Q is 17 and Q2 is Cells(2, 17) or Cells(2, "Q"). If you see .Cells then look for a With ... End With that the . refers to and use that as a relative reference.
Thank you Jeeped. You of course were right about the target.row. I changed Cells(2,17) etc to Cells((Target.Row), 17) and have the results I am looking for.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.