Reputation: 21
Not sure how to reference the worksheet object with a variable that changes each time a sheet is activated.
The point is to reference a cell value based on the last worksheet that was activated (this code affects Sheet1 which does not set the variable when activated)
--Module1
Public MyWS as String
--Sheet3 (Deactivation)
MyWS = Sheet3.Codename
--Sheet2 (Deactivation)
MyWS = Sheet2.Codename
--Sheet1
Sheet1.Range("A3").Value = MyWS.Range("A3").Value
Updated:
Thanks for all the guidance but your instructions are not working for my project at least.
Sheet5.Range("C4").Value = Worksheets(MyWS).Range("A2").Value
Subscript out of range error when the above code is executed on Sheet5 deactivate.
MyWS is declared as a public string. MyWS is assigned the Sheet5.CodeName string when Sheet5 is activated. Sheet5 exists and that is the unmodified codename of the sheet. I can not use the user defined name of the sheet because that can change.
Upvotes: 2
Views: 4480
Reputation: 71217
Public MyWS As String
declares a String
variable, not an object.
The CodeName
property returns a String
that contains an identifier that VBA uses to generate a project-scoped object variable for a Worksheet
; in the properties toolwindow (F4), that's the (Name)
property.
This is how such code is legal:
Sheet1.Range("A3").Value = 42
Because Sheet1
has a code name string that returns Sheet1
. Note that this identifier isn't necessarily the sheet's name (it is by default though), which the user can change at any time without accessing the Visual Basic Editor.
So if you rename the "Sheet1" tab/sheet to "Summary", but don't change its code name, then it will still be Sheet1
in code - so these two instructions do exactly the same thing:
Sheet1.Range("A3").Value = 42
ThisWorkbook.Worksheets("Summary").Range("A3").Value = 42
Now, if you want an object variable holding a reference to a worksheet that exists at compile-time, you already have one - Sheet1
is exactly that.
If you added a worksheet a run-time (doesn't exist at compile-time), then there's no such project-scope object variable for that sheet; that's when you need to declare your own, and assign it with the Set
keyword:
Dim someSheet As Worksheet
Set someSheet = ThisWorkbook.Worksheets.Add
The Excel object model also has the ActiveSheet
object, which returns whatever sheet is currently active.
Sheet1.Range("A3").Value = ActiveSheet.Range("A3").Value
Notice the explicit qualifiers. If it's written in a standard module (.bas), this code is equivalent:
Sheet1.Range("A3").Value = Range("A3").Value
If it's written in the code-behind of a specific worksheet module, then the above code will instead be doing this:
Sheet1.Range("A3").Value = Me.Range("A3").Value
Where Me
is whatever the specific worksheet module you're in is, so if you're writing that code in a worksheet module, you will want to explicitly qualify the Range
member call with the ActiveSheet
object.
If you need to execute code when a worksheet is activated, you can handle the SheetActivate
event in the ThisWorkbook
module:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim sheet As Worksheet
If TypeOf Sh Is Worksheet Then
Set sheet = Sh
Else
'Sh is not a worksheet. could be a chart sheet, or something else.
Exit Sub
End If
Debug.Print sheet.Name & " activated!"
End Sub
If you need to handle the Activated
event of a specific worksheet that exists at compile-time, you need an event handler for it in that worksheet's code-behind:
Private Sub Worksheet_Activate()
Debug.Print Me.Name & " activated!"
End Sub
If you need to handle that event for a worksheet that is created at run-time, you need a WithEvents
object variable in a class module (.cls):
Private WithEvents MySheet As Worksheet
And then you can write a handler for MySheet_Activate
in that module, but that's more advanced stuff and I'm barely scratching the surface here, but that should get you going :)
Upvotes: 2
Reputation: 43593
With ActiveSheet
as mentioned in the comments is really the best solution.
However, if you want to do it "your way", write these Activate
events in every worksheet:
Private Sub Worksheet_Activate()
lastWS = Me.Name
End Sub
Then lastWs
would be the name of the ActiveSheet. And you would be able to refer to it like this Worksheets(lastWs)
. Thus:
Sheet1.Range("A3").Value = Worksheets(lastWs).Range("A3").Value
Upvotes: 1