I have two cells named INPUT_A_1 and INPUT_A_2 in worksheets named "Sheet1" and "Sheet2" respectively, that I'm linking (changing one cell triggers the identical change in the other) with the following sheet macros which work very well:
In Sheet1:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If (Target.Address = Range("INPUT_A_1").Address) Then
Sheets("Sheet2").Range("INPUT_A_2") = Target.Value
End If
Application.EnableEvents = True
End Sub
and in Sheet2:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If (Target.Address = Range("INPUT_A_2").Address) Then
Sheets("Sheet1").Range("INPUT_A_1") = Target.Value
End If
Application.EnableEvents = True
End Sub
My problem is that owing to the syntax Sheets(sheetname).Range(rangename), if I decide to rename either or both worksheets, then I have to alter the macros accordingly. Is there some sort of workaround to this that does not involve summoning the cells by the corresponding worksheet name? This problem becomes decidedly more compelling when I have 3 or more linked cells each in a different worksheet.
Thanks
The "workaround" is to use the codename of the worksheet instead
Using the Code Name of a Worksheet
The best method of accessing the worksheet is using the code name.
Each worksheet has a sheet name and a code name. The sheet name is the
name that appears in the worksheet tab in Excel.
Changing the sheet name does not change the code name meaning that
referencing a sheet by the code name is a good idea.
Following Storax's excellent suggestion above, here is the fix that I implemented:
In the first worksheet (which can be renamed at will):
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If (Target.Address = Range("INPUT_A_1").Address) Then
SheetFromCodeName("Sheet2").Range("INPUT_A_2") = Target.Value
End If
Application.EnableEvents = True
End Sub
and in the Second worksheet (which can also be renamed at will):
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If (Target.Address = Range("INPUT_A_2").Address) Then
SheetFromCodeName("Sheet1").Range("INPUT_A_1") = Target.Value
End If
Application.EnableEvents = True
End Sub
And finally, in any module:
Public Function SheetFromCodeName(CodeName$) As Worksheet
Dim sh As Worksheet
For Each sh In ThisWorkbook.Sheets
If sh.CodeName = CodeName Then
Set SheetFromCodeName = sh
Exit For
End If
Next sh
End Function
The SheetName and CodeName association is according to:
If one has multiple sheets with linked cells, and any of the sheets is deleted, an On Error Resume Next should work.
In fact, the Sheet Index could be used instead thereby obviating the need for the SheetFromCodeName routine altogether.
The syntax in this case in the first and second sheets would be
Worksheets(2).Range("INPUT_A_2") = Target.Value
and
Worksheets(1).Range("INPUT_A_1") = Target.Value
Related
I have an excel workbook and I am running some code to remove extra spaces from one cell in several sheets. When I enter something in cell "E4", it removes every instance of " " and replaces it with "". This works as anticipated.
I am trying to get this to work for more than one sheet, by using named ranges. In the sheets, I created a named range "ConfigurationInput" with a scope of sheet.
The following code is in one of the sheets, and it functions as expected:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("E4")) Is Nothing Then
Call RemoveSpaces(Range("E4"))
End If
End Sub
This calls the following Sub, located in a module:
Sub RemoveSpaces(RngRemove)
Dim rng As Range
Set rng = RngRemove
rng = WorksheetFunction.Substitute(rng, " ", "")
End Sub
I am trying to replace "E4" with the named range "ConfigurationInput", and I am receiving the following error which crashes Excel:
Does anybody have a suggestion? I tried simplifying to a single cell and using .Address but that didn't work either:
If Target.Address = Range("ConfigurationInput").Address Then
I finally figured it out:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not Intersect(Target, Range("ConfigurationInput")) Is Nothing Then
Call FixConfig(Range("ConfigurationInput"))
End If
Application.EnableEvents = True
End Sub
I had to wrap the code with Application.EnableEvents = False and Application.EnableEvents = True
Hej,
I've created a small VBA code to dynamically rename a worksheet.
It's working perfectly when the cell is just manually typed.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("C9")) Is Nothing Then
ActiveSheet.Name = ActiveSheet.Range("C9")
End If
End Sub
But then as soon as I will put a formula concatenating 2 cells values within C9 cell it will not update it automatically.
To make it work I need to enter the cell and type ENTER again and it works.
I have to do same manipulation each time I change a value in on of the 2 cell concatenated.
THANKS for your help guys
You need to capture a different event:
Private Sub Worksheet_Calculate()
Application.EnableEvents = False
ActiveSheet.Name = ActiveSheet.Range("C9")
Application.EnableEvents = True
End Sub
NOTE:
We disable events during the name change in case the worksheet contains a formula referencing the tab-name.
this should work:
replace
ActiveSheet.Name = ActiveSheet.Range("C9")
by
ActiveSheet.Name = ActiveSheet.Range("C9").Value
This is an alternate answer if someone still wants to execute this on worksheet change event
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Dim formulacell As Range
Set formulacell = Range("C9")
Set formulacell = Application.Union(formulacell, formulacell.Precedents)
If Not Intersect(Target, formulacell) Is Nothing Then
ActiveSheet.Name = ActiveSheet.Range("C9").Value
End If
Application.EnableEvents = True
End Sub
I am trying to hide a commandbutton based on a specific cell value. I have looked up several codes and pasted them in excel (in the vba form when right clicking the sheet and selecting "view code").
What am I doing wrong?
Here's one of the codes I've tried:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("A1") = 0 Then ActiveSheet.CommandButton1.Visible = False
If Range("A1") = 1 Then ActiveSheet.CommandButton1.Visible = True
End Sub
Make sure you enable events before using your code. Also, you must place your code in Worksheet module, not in regular module. To enable events, use this simple sub.
Sub Enable_events()
Application.EnableEvents = True
End Sub
please run this first:
Sub enable_()
Application.EnableEvents = True
End Sub
and then your Code will run perfectly:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("A1") = 0 Then ActiveSheet.CommandButton1.Visible = False
If Range("A1") = 1 Then ActiveSheet.CommandButton1.Visible = True
End Sub
Your code is confusing, for a number of reasons.
Range, when it's not qualified with a Worksheet object, implicitly refers to the ActiveSheet, i.e. ActiveSheet.Range... but when it's in a worksheet's code-behind, it implicitly refers to that worksheet's Range property, i.e. Me.Range. Because the meaning of an unqualified Range call depends on context, it's best to always qualify it with an explicit Worksheet object.
So if you're in the code-behind module for Sheet1, then Range("A1") is equivalent to Sheet1.Range("A1"), or even better, Me.Range("A1").
The two conditions will be evaluated every time, but only one of them needs to be: it's inefficient.
Truth is, you don't need to assign a Boolean literal - a Boolean expression is much cleaner.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Me.CommandButton1.Visible = (Me.Range("A1") = 1)
End Sub
Now, assuming Application.EnableEvents returns True, that code will run every time the selection changes, which is rather overkill.
Handle the Worksheet.Change event instead, and only act when the modified cell is A1:
Private Sub Worksheet_Change(ByVal Target As Range)
If Application.Intersect(Target, Me.Range("A1")) Is Nothing And Target.Count <> 1 Then
' we don't care about that cell: bail out
Exit Sub
End If
Me.CommandButton1.Visible = (Me.Range("A1") = 1)
End Sub
Please try this code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A1")) Is Nothing Then
If Selection.Cells.Count = 1 Then
If Range("A1") = 0 Then ActiveSheet.CommandButton1.Visible = False
If Range("A1") = 1 Then ActiveSheet.CommandButton1.Visible = True
End If
End If
End Sub
Hope this help.
I've found a VBA code that allows me to change the sheet name based on a cell value. That cell values are constantly changing but the 48 sheets that I have do not update unless I click into that sheet. How do I get the marcos to run every time the cell value changes?
Below is the code that I'm using.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Set Target = Range("DK5")
If Target = "" Then Exit Sub
Application.ActiveSheet.Name = VBA.Left(Target, 31)
Exit Sub
End Sub
If you always activate the sheet before manually changing the contents of cell DK5 in that sheet, then enter this event macro in the each sheet that you want this functionality:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("DK5")) Is Nothing Then Exit Sub
Application.EnableEvents = False
ActiveSheet.Name = Range("DK5").Text
Application.EnableEvents = True
End Sub
If cell DK5 contains a formula, then a different event macro is required.
EDIT#1:
If the DK5 cells contain formulas rather than typed constants, then use these events macro instead:
Private Sub Worksheet_Calculate()
Application.EnableEvents = False
Me.Name = Me.Range("Dk5").Value
Application.EnableEvents = True
End Sub
(one macro in each sheet)
I've been working on this for some time now and have hit a real stumbling block.
I have a set of values that are available via a validated dropdown menu in Sheet 3, Column D. Once selected this value currently displays in a different sheet (Sheet 7) using excel function ='Sheet 3'!D4 and so on, and I have some code that reads this and performs an IF statement to produce a value in another cell.
My problem is the code is dependant on reading the value and not the formula.
I currently have a worksheet change command for a separate function I want to run, is there a way for this to run a second function and call any changes from sheet 3 column D into sheet 8 column D and then run my other change function?
Sheet 7 Code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim c As Range
If Intersect(Target, Range("D2:D102")) Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo Finalize
For Each c In Target.Cells
Select Case c.Column
Case 4
Call Print_Quality(c)
End Select
Next c
Finalize:
Application.EnableEvents = True
End Sub
Sheet 7 Module:
Sub Print_Quality(c As Range)
Dim PrintQuality As String
Dim PrintSpeed As String
PrintQuality = c.Value
If PrintQuality = "A Quality 1" Then PrintSpeed = "100"
c.Offset(0, 5).Value = PrintSpeed
End Sub
I've been trying this route but to no avail:
Worksheet 3 code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("D4:D104")) Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo Finalize
UpdateVal
Finalize:
Application.EnableEvent = True
End Sub
Module:
Sub UpdateVal()
Worksheets("Sheet 7").Range("D2").Value = Worksheets("Sheet 3").Range("D4").Value
End Sub
Many thanks
Sods law, I've managed to fix this an hour after my desperation post.
I completed another worksheet change from the sheet it was calling from (Sheet 3)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Range("D4:D104")
If Not Application.Intersect(KeyCells, Range(Target.Address)) Is Nothing Then
Call UpdateVal
End If
End Sub
then added this function into the module
Sub UpdateVal()
Sheet8.Cells(2, 4).Value = Sheet3.Cells(4, 4)
End Sub
this now references the value of the dropdowns in sheet 8 and allows other functionality to continue using the cell value
Have you tried stepping through your code to see where it is having an issue? It not, I would suggest putting a break at the beginning of each module, and then use F8 to step through. This will confirm it is running as it should.
You should also be fully-qualifying your references to worksheets. While presumably the sheet references should carry through given that they are in worksheet modules, there is the chance of failure. You can simply assign a variable to hold the worksheet like so:
Dim wb as Workbook
Dim ws as Worksheet
Set wb = ThisWorkbook
Set ws = wb.Sheets("YourSheetName")
Additionally, your worksheet 3 code:
EnableEvent = True
Should be:
EnableEvents = True