I read a lot of pages saying that, but none of them put the solution if the value change by an "if function" not by hand.
The code I get is that:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("A18:A30")) Is Nothing Then Exit Sub
Application.EnableEvents = False 'to prevent endless loop
On Error GoTo Finalize 'to re-enable the events
MsgBox "You changed THE CELL!"
Finalize:
Application.EnableEvents = True
End Sub
It only works if I change the value by hand.
Thank you in advance.
Another solution; instead of triggering your function every time when your worksheet recalculates, add a function in a module:
Function DetectChange() As Integer
MsgBox "You changed THE CELL!"
DetectChange = 0
End Function
Assuming the outcome of your formula is numeric:(otherwise outcome of function must be a empty string and the "+" must be "&")
Add to your IF-formula at the end ...+Detectchange()
Now there will be a msgbox only when your formula is recalculated
Edit by Darren Bartrup-Cook:
I found this code gave worked when the formula recalculated. It didn't fire if I changed a cell that doesn't affect the cell it's entered to and it didn't fire using Calculate Now or Calculate Sheet.
It did occasionally fire for all formula that I used the function in, but that seemed to be when I was debugging - maybe further investigation needed.
Public Function DetectChange()
MsgBox "You changed cell " & Application.Caller.Address
End Function
e.g.:
=IF(A1=1,A2,A3) & DetectChange() entered in cell A4 displays the message "You changed cell $A$4" if cells A1, A2 or A3 is changed.
Write this in Sheet1 and run the TestMe sub:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("A1:A30")) Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo Finalize
MsgBox "You changed THE CELL!"
Finalize:
Application.EnableEvents = True
End Sub
Sub TestMe()
Range("A1") = 34
End Sub
It has worked quite ok on my PC.
If the cell is changed by a built-in Excel function, then the comment of #Vincent G states the correct answer:
Worksheet_Change event occurs when cells on the worksheet are changed by the user or by an external link. and This event does not occur when cells change during a recalculation. Use the Calculate event to trap a sheet recalculation.
If you want to track the calclulation event based on some changes at Range(A18:A30) this is a working solution:
Add a new Worksheet to your Workbook (Sheet2);
In the current Worksheet write the Calculate event:
Private Sub Worksheet_Calculate()
Dim cell As Range
For Each cell In Sheet2.Range("A18:A30")
If cell <> Sheet1.Range(cell.Address) Then
cell = Sheet1.Range(cell.Address)
End If
Next cell
End Sub
In the Sheet2 write an event, catching the changes.
As simple as #Vincent G says.
Private Sub Worksheet_Calculate()
Call YourFunction
End Sub
I am trying to write a code using Macro, but with no luck.
The task can be simply defined as, when the user enters a Serial Number such "AB123" anywhere in column I, a list should appear automatically in columns in (J, K, L). please the the attached picture
If there is any other way to do that without using Macro, I am glad to hear it.
Thank you in advance, I hop that I make myself clear.
The pic. shows whenever the RED Serial Number is entered. The Highlighted columns in green should appear.
Something for you to think about. Put this code in your Sheet. Double-click the sheet name and a windoe to enter code will appear.
Option Explicit
Public Sub Worksheet_Activate()
Me.Range("J:L").EntireColumn.Hidden = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Target, Me.Range("I:I")) Is Nothing Then
If Target.Cells.CountLarge = 1 Then
If Target.Value = "AB1234" Then
Me.Range("J:L").EntireColumn.Hidden = False
Else
Me.Range("J:L").EntireColumn.Hidden = True
End If
Else
'Nothing
End If
End If
End Sub
Private Sub Worksheet_Deactivate()
Me.Range("J:L").EntireColumn.Hidden = False
End Sub
I am trying to create a macro to prevent users from printing a form if they don't fill out all cells. However, I am getting an error message:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
If Application.Sheets("Form").Range("B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6,M6,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7,M7,B8,C8,D8,E8,F8,G8,H8,I8,B9,C9,D9,E9,F9,G9,H9,I9,B11,C11,D11,E11,F11,G11,H11,I11,B12,C12,D12,E12,F12,G12,H12,I12,B13,C13,D13,E13,F13,G13,H13,I13,B14,C14,D14,E14,F14,G14,H14,I14,B16,C16,D16,E16,F16,G16,H16,I16,B17,C17,D17,E17,F17,G17,H17,I17").Value = "" Then
Cancel = True
MsgBox "Fill out all the cells"
End If
End Sub
I have another macro for another form that has fewer cells and that one works just fine:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
If Application.Sheets("Form 2").Range("C4,C5,C6,D4,D5,D6,F4,F5,F6,B8,B9,B10,B11,C8,C9,C10,C11,D8,D9,D10,D11,E8,E9,E10,E11,C13,D13,C16,C17,C18,F16,F17,F18,C22,D22").Value = "" Then
Cancel = True
MsgBox "Fill out all the cells"
End If
End Sub
What can I do to solve this problem?
It seems that there is a limit to line length or to how long of a string you can put into a range(). But you can consolidate it like this. Also I think that the return value from a range() with more than one cell is an array so I am not sure if it is valid to compare it to a string like you did.
Try this:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
For Each cell In Application.Sheets("Form").Range("B4:M7,B8:I9,B11:I14,B16:I17")
If cell.Value = "" Then
Cancel = True
MsgBox "Fill out all the cells"
Exit Sub
End If
Next
End Sub
Its a protected worksheet/workbook and I have a code that will throw a prompt for the user, whether to edit the sheet or not. Cells are editable, but the problem is cells are not getting highlighted with border. So its difficult for the user to know which cells is he working on.
I have 2 sheets here, Corefiller and Ad-filler, if dropdown on corefiller sheet is "No". User gets a prompt when he selects the sheet, he clicks ok to edit the sheet or cancel if he doesnt want to edit.
Code on Sheet "Ad-filler"
Option Explicit
Private mMessageDisplayed As Boolean
Private Sub Worksheet_Activate()
Carry
End Sub
Code on a module.
Public Sub Carry()
If ActiveSheet.ProtectContents And Not mMessageDisplayed Then
mMessageDisplayed = True
If ThisWorkbook.Sheets("Corefiller").Range("E29") = "NO" Then
If MsgBox("Click OK to include Filler for this request", vbOKCancel + vbInformation) = vbOK Then
ThisWorkbook.Worksheets("Corefiller").Range("E29") = "YES"
With ThisWorkbook.Sheets("Ad-filler")
.Range("E13:E14").Locked = False
End With
Else
With ThisWorkbook.Sheets("Ad-filler")
.Range("E13:E14").Locked = True
End With
End If
Else
Exit Sub
End If
End If
End Sub
Whats wrong in my code? why the cell is not highlighted. If i try to use protect/unprotect in the code, cells on the first sheet (Corefiller) will not be highlighted and I have to click on other sheets and come back to get the cell highlighted.
Can you restart, implement this and check whether the problem still exists:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Cells.Interior.ColorIndex = 0
Target.Interior.ColorIndex = 3
End Sub
In Excel 2010, I'm trying to pass 'Target' from a Worksheet_Change event to a subroutine. The sub checks if a change has occurred within a specific range and does certain things if it does. The problem I'm having is that target seems to behave differently in the sub that in the calling procedure. For instance, in the calling procedure I can use Target within an intersect, when I pass it to the sub and do the same thing I get a run time error (1004). My code is below, I'd be grateful if someone can inform me what I'm doing wrong.
'Code on sheet - this is on several sheets
Private Sub Worksheet_Change(ByVal Target As Range)
SubRout Target
End Sub
'Code in Module
Sub SubRout (ByVal Target As Range)
Dim ValidChange As Boolean
ValidChange = True
'Check if change on sheet was a change to cell in named range
If Intersect(Target, Names("WB4aWBSRange").RefersToRange) Is Nothing Then ValidChange = False
If ValidChange = True And Target.value <> "" Then
'Do stuff
End If
End Sub
The run time error occurs on the Intersect line, but if I move all the code up to the calling routine it works fine.
The error is not because of that. Error is because of Names("WB4aWBSRange").RefersToRange. You can't use it like that.
Use this
If Intersect(Target, Range("WB4aWBSRange")) Is Nothing Then ValidChange = False
Because is Nothing returns a Boolean value the first if statement isn't needed:
ValidChange = Not Intersect(Target, Range("WB4aWBSRange")) Is Nothing
I would rather not use the variable at all and do this instead:
If Not Intersect(Target, Range("WB4aWBSRange")) Is Nothing' then
If Target.value <> "" Then
'Do stuff
End If
End Sub