Worksheet_Change(ByVal Target as Range) doesn't work - excel

Probably I'm missing something but the most simple "Worksheet_Change" doesn't work at all. The code is placed in the correct worksheet and is exactly the same as in samples I have found in my search to solve the problem. Please ignore the lines that start with "'" as they will be part of the code after the issue is solved. I've simplified the code in trying to localize the issue but as I said, even this simple code doesn't work, even if I use a new Workbook with only one sheet. As said, I might be missing something completely simple but for the moment, I don't know what it is. Thank you.
Jan
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
' Dim KeyCells As Range
' Set KeyCells = Range("Orders[Nieuw]")
' If Not Application.Intersect(Range("Orders[Nieuw]"), Target) _
' Is Nothing Then
' If Target.Address = "$C$10" Then
Application.EnableEvents = False
' If Target.Value = "Ja" Then
MsgBox "This Code Runs When Cell A1 Changes!"
Target.Font.ColorIndex = 5
' Range("AG2").Select
' Selection.Copy
' Range("Ordernummerbereik").Select
' Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
' :=False, Transpose:=False
' SendKeys ("{ESC}")
' End If
Application.EnableEvents = True
' End If
End Sub

You probably ended up in EnableEvents = False and therefore no events will be executed anymore including the Worksheet_Change event.
When using Application.EnableEvents = False make sure you use proper error handling that returns it to True otherwise if an error occurs it stays False until you close Excel.
Example for error handling
Public Sub Example()
Application.EnableEvents = False
On Error Goto EventsOn
' your code here
EventsOn:
Application.EnableEvents = True
If Err.Number Then Err.Raise Err.Number ' show the error message
End Sub
That means if any error occurs in your code it jumps to EventsOn: turns events on and throws the error message. This way you ensure that Events are always turned on in case of an error.

The only way I can reproduce your problem is by setting EnableEvents to false outside of the sub. Perhaps it crashed at some stage leaving events disabled?
Incidentally you can replace the copy and paste with
Range("Ordernummerbereik").Value = Range("AG2").Value
which is much more robust
Finally I advise you to use fully qualified ranges for ranges without an explicit name e.g. ThisWorkBook.Sheets("Sheet1").Range("A1") rather than Range("A1")
You can use (note the dot-Range on AG2)
With ThisWorkBook.Sheets("Sheet1")
Range("Ordernummerbereik").Value = .Range("AG2").Value
' ... other code with range references
End With

Related

Excel VBA Function throws an error when changes the cell

I have been using this code which copies the range and paste the range as picture but when i change the concerns cell it throws an error that is Error 1004, Microsoft Excel cannot paste the data.
Any help will be appreciated.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("C5:P5")) Is Nothing Then
Application.CutCopyMode = TRUE
ActiveSheet.Pictures.Delete
Worksheets("Pivot").Range("FC3:FP35").Copy
With Worksheets("Map")
.Activate
.Range("C8").Select
.Pictures.Paste
End With
Application.CutCopyMode = FALSE
End If
End Sub
You need to turn off events Application.EnableEvents = False before changing cells and turn them on after. Make sure they get turned on in any case of an error in this event or you will not be able to fire any other events in your Excel instance. So error handling in this event is a must have. • You might benefit from reading
How to avoid using Select in Excel VBA.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("C5:P5")) Is Nothing Then
On Error Goto ERR_ENABLE_EVENTS
Application.EnableEvents = False
Me.Pictures.Delete
Worksheets("Pivot").Range("FC3:FP35").Copy Destination:=Worksheets("Map").Range("C8").Paste
End If
ERR_ENABLE_EVENTS:
Application.CutCopyMode = False
Application.EnableEvents = True
If Err.Number <> 0 Then
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End If
End Sub

VBA - how do I stop the loop caused by the filter updating?

I want to update a normal filter when a cell within the filter is calculated.
I have a list in the range A2:A10, if it displays 1 then show the row, if it's 0 then hide the row. In the range A2:A10 I have formulas which calculates if it should be 0 or 1. I only need to update the filter if the value change and I do this with this VBA:
Private Sub Worksheet_Calculate()
Dim RG As Range
Set RG = Range("A2:A10")
If Not Intersect(RG, Range("A2:A10")) Is Nothing Then
ActiveSheet.Range("$A$1:$B$10").AutoFilter Field:=1, Criteria1:="1"
End If
End Sub
But whenever the macro runs, excel freezes. I believe this is because a loop is created which never stops. When the filter is updated, that will cause the macro to run again.
I only need it to update the filter when the value in the range is changed, but it updates the filter when the filter is updated, which will update the filter again. So, a loop is created which causes excel to freeze.
I also get a:
run-time error '-2147417848 (80010108)':
Automation error
The object invoked has disconnected from its clients.
Some suggestions on your code:
Add EnableEvents = false so nothing else is triggered by the changes you make with the macro (and reenable them at the end of the procedure)
Name your variables to something meaningful e.g. targetRange instead of RG
Use at least a basic error handling On error Goto
As you have this code behind a Worksheet you can refer to that worksheet as Me instead of ActiveSheet
About the logic:
This line is redundant
If Not Intersect(targetRange, Me.Range("A2:A10")) Is Nothing Then
You are defining the range as Range("A2:A20")
Set targetRange = Me.Range("A2:A10")
I left it so you can change it to whatever you want to check
Refactored code:
Private Sub Worksheet_Calculate()
On Error GoTo CleanFail
' Disable events so nothing else is triggered by the changes you make with the macro
Application.EnableEvents = False
Dim targetRange As Range
Set targetRange = Me.Range("A2:A10")
' This next line doesn't make sense, you're comparing the same ranges
If Not Intersect(targetRange, Me.Range("A2:A10")) Is Nothing Then
Me.Range("$A$1:$B$10").AutoFilter Field:=1, Criteria1:="1"
End If
CleanExit:
' Reenable events
Application.EnableEvents = True
Exit Sub
CleanFail:
MsgBox "Error: " & Err.Description
GoTo CleanExit
End Sub
Let me know if you have any questions.

How to pass a parameter when calling a Module from an Object in Excel VBA

I am new to VBA and have a simple question. I am having trouble passing a parameter through a Sub that is being called in an Object. If I take the parameters out of the code, it works like expected. When I put the parameters in it just stops at the Application.Run Code and does not even try to go into transposeValues, but no errors are shown. Please see below:
My Object:
Private Sub Worksheet_Change(ByVal Target As Range)
With Worksheets("DO NOT EDIT")
Dim book As String
book = "test"
For Each c In .Range("A1:A2").Cells
If Not Application.Intersect(Target, Range("B" & c)) Is Nothing Then
On Error Resume Next
Application.EnableEvents = False
Application.Run "Module1.transposeValues(book)"
Application.EnableEvents = True
End If
Next
End With
End Sub
My Sub where I am calling transposeValues:
Sub transposeValues(ByVal s As String)
'
' transposeValues Macro
'
Debug.Print num
Selection.Copy
Range("C3").Select
Selection.PasteSpecial Paste:=xlAll, Operation:=xlNone, SkipBlanks:=False _
, Transpose:=True
Range("B1:B5000").Select
Application.CutCopyMode = False
Selection.ClearContents
End Sub
I tried the following lines of code as well:
Application.Run "Module1.transposeValues , book"
Application.Run Module1.transposeValues , book
Application.Run "Module1.transposeValues book"
Application.Run Module1.transposeValues book
None of these work and I tried searching online and in other stackoverflow questions and the answers don't seem to be working. Please help.
Looks like I just had the syntax a little wrong. This worked:
Application.Run "Module1.transposeValues", book

Vba beginner question: same macro applied differently shows different behaviour

I have the following question:
The code you see below has been pasted in an excel object
Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Application.ScreenUpdating = False
Dim DAY, other As Range
Set DAY = Range("b4:af4")
If Not Intersect(DAY, Range(Target.Address)) Is Nothing Then
ActiveCell.Copy
Sheets("SP Analysis").Activate
Range("b2").PasteSpecial Paste:=xlPasteValues
'ElseIf Not Intersect(other, Range(Target.Address)) Is Nothing Then
End If
End Sub
The macro runs but it doesn't copy the activecell in the sheet SP Analysis.
If I change the code with the following:
Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Application.ScreenUpdating = False Dim DAY, other As Range Set DAY = Range("b4:af4")
If Not Intersect(DAY, Range(Target.Address)) Is Nothing Then Call TEST
'ElseIf Not Intersect(other, Range(Target.Address)) Is Nothing Then End If End Sub
with macro TEST doing
sub test
ActiveCell.Copy
Sheets("SP Analysis").Activate
Range("b2").PasteSpecial Paste:=xlPasteValues
end sub
The command does what is supposed to do.
Question is why? what's the difference between one method and the other?
And, how can I have the command working in an excel object rather than having to call a macro?
Thank you
Try this. Use Target rather than ActiveCell although in this case I don't know why the latter wouldn't work. And we can transfer the value directly without having to activate anything.
Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Application.ScreenUpdating = False
Dim DAY As Range, other As Range 'need to specify type for each variable, otherwise Variant
Set DAY = Range("b4:af4")
If Not Intersect(DAY, Target) Is Nothing Then
Cancel=True
Sheets("SP Analysis").Range("b2").Value = Target.Value 'use target
End If
Application.ScreenUpdating = True 'turn it back on
End Sub

Copy Range value and format

I am trying to copy Cells B2:B26 from sheet1 to sheet2 B8:B32 with the value and format if a change occurs in sheet 1. The problem is it seems to run in loop for about 10 seconds. I can't see what's wrong. This is my code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Copy_Range
End Sub
Sub Copy_Range()
Sheets("liste d'élèves").Range("B2:B26").Copy
With Sheets("Feuil1").Range("B8:B32").End(xlToLeft).Offset(, 1)
.PasteSpecial xlPasteAll
End With
Application.CutCopyMode = False
End Sub
You need to disable events. Also, I highly recommend limiting the scope of your Worksheet_SelectionChange. Do you really want any change to trigger the macro? Maybe you are looking in a change within a specific region. If so, specify that region and run the macro when the selection change overlaps (Intersects) with the specified region.
Sub Copy_Range()
Application.EnableEvents = False <--- Off
Sheets("liste d'élèves").Range("B2:B26").Copy
With Sheets("Feuil1").Range("B8:B32").End(xlToLeft).Offset(, 1)
.PasteSpecial xlPasteAll
End With
Application.EnableEvents = True <--- On
End Sub

Resources