I have two cells, "R3" and "S3", in the same Excel sheet, "Data", which I want to link so that a manual entry to either is reflected across to the other with a correcting factor. Circular references prevent using formulae. I searched here and found this VBA snippet:
Private Sub Worksheet_Change(ByVal target As Range)
If target.Address = "$R$3" Then
ActiveWorkbook.Worksheets("Data").Range("$S$3").Value = target.Value*2.55
End If
End Sub
It was originally meant to link two cells on different sheets and in my own case the cells are on the same sheet. This works perfectly for entering in one and seeing the change in the other in one direction only. I can also add additional cell pairs using ElseIf. However, if I expand it to contain a dual reference as in R3->S3 and S3->R3 like this:
Private Sub Worksheet_Change(ByVal target As Range)
If target.Address = "$R$3" Then
ActiveWorkbook.Worksheets("Data").Range("$S$3").Value = target.Value*2.55
Else If target.Address = "$S$3" Then
ActiveWorkbook.Worksheets("Data").Range("$R$3").Value = target.Value/2.55
End If
End Sub
Even though the two sections seem mutually exclusive and cannot both be referenced in the same procedure call, this crashes my spreadsheet every time I try to make a change. Obviously I am doing something hugely wrong! I had been led to believe from the original post that this would not cause a circular reference.
My guess is that I should be approaching this with two separate procedures, or is it just plain impossible based on this code?
You are creating an infinite loop using the change module. By updating one it triggers the event using the other cell
update your change event to look like:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Or Target.Address = "$B$1" Then
Call cellUpdate(Target.Address)
End If
End Sub
and then in a module put:
Sub cellUpdate(Target As String)
Application.EnableEvents = False
With ActiveWorkbook.Worksheets("Data")
If Target = "$R$3" Then
.Range("$S$3").Value = .Range(Target) * 2.55
ElseIf Target = "$S$3" Then
.Range("$R$3").Value = .Range(Target) / 2.55
End If
End With
Application.EnableEvents = True
End Sub
By breaking it out into a separate module and controlling the Application.EnableEvents in the separate module you stop the infinite loop.
You are missing one End If:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Target.Address = "$R$3" Then
ActiveWorkbook.Worksheets("Data").Range("$S$3").Value = Target.Value * 2.55
Else
If Target.Address = "$S$3" Then
ActiveWorkbook.Worksheets("Data").Range("$R$3").Value = Target.Value / 2.55
End If
End If
End Sub
Related
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
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
I have a problem with Worksheet_Change. When I target the cell Excel doesn't react at all even if I put an error in the code. I put the Worksheet_Change on the right sheet, so that's not the reason.
I simplified my code as much as I could and there is still no reaction.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$c$2" Then
MsgBox "hi"
End If
End Sub
I think the event listener that you want to trigger is Worksheet_SelectionChange.
For Worksheet_Change to work, you need to type something in cell C3
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Me.Range("C2"), Target) Is Nothing Then
MsgBox "Great! Target is within the chosen range!"
End If
End Sub
This works. I always use the above structure.
Is there an object and/or function that can detect or represent a general change on a worksheet? Something similar to (for example) ComboBox1_Change() but could be applied to a whole worksheet. Almost something like Worksheet1_Change(). Any suggestions are welcome. Thanks.
The simplest would be to use the worksheet change event:
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox "Change Detected!"
End Sub
There are instances will this will throw you in to an infinite loop. Consider this code:
Private Sub Worksheet_Change(ByVal Target As Range)
Range("A1").Value = "Change"
End Sub
Set a breakpoint on the Range("A1") code and make a change somewhere else on the sheet and count how many time that breakpoint gets hit. When you get tired of hitting F5, stop the code and try this:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Range("A1").Value = "Change"
Application.EnableEvents = True
End Sub
You'll see that the code only fires once. Which is probably what you're after.
It's very important that you have the Application.EnableEvents = True line in there, or else you'll get the appearance that your code isn't working (by default EnableEvents does not revert back to True at the end of the code).
I am trying to call a macro named "RE_environmental" when the cell named "RE_1" is changed (i.e. they mark a X in the cell). I've tried several different variations of codes including these two and nothing is happening:
[The first code does work if I use the exact cell location and not the named cell. --> $E$62]
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "RE_1" Then
Call RE_environmental
End If
End Sub
AND
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("Name").Select = "RE_1" Then
Call RE_environmental
End If
End Sub
--Thanks in Advanced and please let me know if you need more information.
Use your first answer but make this small change:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Range("RE_1").Address Then
Call RE_environmental
End If
End Sub
Simple syntax mistake!
Edit: To stop RE_environmental from running once the cell is empty, put the code from RE_environmental inside a do-while (not isempty(Range("RE_1"))) as long as RE_environmental is emptying "RE_1". The user won't be able to edit cells while RE_environmental is running.
If Target is always single-cell range, you can use this one:
If Target.Address = Range("RE_1").Address Then
Call RE_environmental
End If
If Target can be multicell range use this one:
If Not Intersect(Target, Range("RE_1")) Is Nothing Then
Call RE_environmental
End If