0

1) Can someone please tell me what the issue could be with this code?

2) I need this code actually to run on a worksheet update, but @ first-time load of the workbook, i'm running an update using the Workbook_Open event handler. Won't this trigger my Worksheet_Change event as well? Is there any way to avoid this

Private Sub Worksheet_Change(ByVal Target As Range)

Dim ws As Worksheet
Dim rowCount As Integer

Set Worksheet = "datasheet"
Set rowCount = ws.Cells(Rows.Count, "A").End(xlUp)

If Not Intersect(Target, Range("M3:M" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If
Else
If Not Intersect(Target, Range("T3:T" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If
Else
If Not Intersect(Target, Range("X3:X" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If
Else
If Not Intersect(Target, Range("AB3:AB" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If
Else
If Not Intersect(Target, Range("AI3:AI" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If

End Sub

I'm getting a Compiler error saying "object required" when i change my data with this handler. On the other hand, if i give values instead of taking a rowcount, I get no issues.

4
  • 1
    Set rowCount = ws.Cells(Rows.Count, "A").End(xlUp) rowCount is not an object but a variable. Use rowCount = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row Commented Oct 23, 2012 at 6:09
  • 1
    And use Dim rowCount As Long - there are more rows in a worksheet than an Integer can hold Commented Oct 23, 2012 at 6:11
  • Good Point @Chris. :@user1638796: Regarding your 2nd question. You can use a public variable to check for the worksheet_open event and then avoid the change event. Commented Oct 23, 2012 at 6:19
  • @user1638796: Are you running the code from the sheets("Datasheet") code area? Commented Oct 23, 2012 at 7:00

2 Answers 2

1

I always recommend this when using Worksheet_Change

  1. You do not need the sheet name. It is understood that the code is to be run on current sheet unless you are trying to use another sheet row as a reference as correctly mentioned by brettdj in the comments below.

  2. Whenever you are working with Worksheet_Change event. Always switch Off events if you are writing data to the cell. This is required so that the code doesn't go into a possible endless loop

  3. Whenever you are switching off events, use error handling else if you get an error, the code will not run the next time.

Here is an example

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Whoa

    Application.EnableEvents = False

    '
    '~~> Rest of the code
    '

LetsContinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume LetsContinue
End Sub

So using the above, your code becomes (UNTESTED)

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim rowCount As Long

    On Error GoTo Whoa

    Application.EnableEvents = False

    With ActiveSheet
        rowCount = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With


    If Not Intersect(Target, Range("M3:M" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("T3:T" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("X3:X" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("AB3:AB" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("AI3:AI" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    End If

LetsContinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume LetsContinue
End Sub

EDIT:

Regarding your 2nd question. As I mentioned in the comment above, you can use a Public variable to check if the worksheet change event is being caused by the workbook open.

Place this code in a module.

Public WasWbOpened As Boolean

Place this code in the workbook code area

Option Explicit

Private Sub Workbook_Open()
    WasWbOpened = True
    '
    '~~> Rest of the code
    '
    WasWbOpened = False
End Sub

And change your worksheet change event to

Private Sub Worksheet_Change(ByVal Target As Range)
    If WasWbOpened = True Then Exit Sub

    Dim rowCount As Long

    On Error GoTo Whoa

    Application.EnableEvents = False

    With ActiveSheet
        rowCount = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With


    If Not Intersect(Target, Range("M3:M" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("T3:T" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("X3:X" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("AB3:AB" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("AI3:AI" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    End If

LetsContinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume LetsContinue
End Sub
Sign up to request clarification or add additional context in comments.

4 Comments

Your code will prevent other events from firing off as the Worksheet_Change event is being handled right? For my purposes, I need to stop the Worksheet_Change event from firing as long as I'm handling the workbook_open event. So i can apply the same structure to my Workbook_open handler instead of the Worksheet_change handler right?
"You do not need the sheet name. It is understood that the code is to be run on current sheet" Not necessarily true. The row count from one sheet may be used as a marker for a different sheet
@user1638796: I am updating the above question with the 2nd part of the question.
@brettdj: Very true. If the user is using another sheet as a marker then yes, we need the worksheet object else we do not need it.
1

You have several issues

  1. As per Sid's comment you should use rowCount = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
  2. You should be using Set ws = Sheets("datasheet") not Set Worksheet = "datasheet"
  3. Your Else statements are causing errors as they are orphaned. If you want to exit on the first "Hi" rather than continuing to test you should try something like this

Sid has covered your other point. You can use a Boolean variable for this

updated code

this tests the intersect on columns M, T, X, AB and AI from row 3 to row rowCount in a single line

Private Sub Worksheet_Change(ByVal Target As Range)

Dim ws As Worksheet
Dim rowCount As Long

Set ws = Sheets("datasheet")
rowCount = ws.Cells(Rows.Count, "A").End(xlUp).Row

If Not Intersect(Target, Range("M3:M" & CStr(rowCount) & ",T3:T" & CStr(rowCount) & ",X3:X" & CStr(rowCount) & ",AB3:AB" & CStr(rowCount) & ",AI3:AI" & CStr(rowCount))) Is Nothing Then MsgBox ("Hi")

End Sub

9 Comments

I guess your 2nd point... You should be using Set ws = "datasheet"
the error fires off when i'm setting row count in this handler
@SiddharthRout you are probably correct :) user1638796 do you actually have a worksheet called "datasheet" as your initial code indicates?
No I meant... It should be Set ws = Sheets("datasheet") and not Set ws = "datasheet". Ah! I see you have updated that in your code. You will have to change point 2 above I guess.
the code was working fine, and then I replaced the MsgBox(Hi) messages with what i Really wanted to do : update the values in the vlookup column based on changes in the previous column. This is working for all but 1 case : if I add an extra row in "Datasheet", and add a value in column M, the Worksheet_Change handler is raising an error stating "unable to get vlookup property of worksheet". what could be wrong? I've added a value to column A as well (since we're taking rowcount in Worksheet_Change based on this)..
|

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.