[英]VBA - Reference an object by using a variable
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) 关键是要基于最后一个被激活的工作表引用一个单元格值(此代码会影响Sheet1,Sheet1在激活时不会设置变量)
--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 Sheet5.Range(“ C4”)。Value = Worksheets(MyWS).Range(“ A2”)。Value
Subscript out of range error when the above code is executed on Sheet5 deactivate. 在Sheet5上执行上述代码时,下标超出范围错误被禁用。
MyWS is declared as a public string. MyWS被声明为公共字符串。 MyWS is assigned the Sheet5.CodeName string when Sheet5 is activated.
在激活Sheet5时,将为MyWS分配Sheet5.CodeName字符串。 Sheet5 exists and that is the unmodified codename of the sheet.
Sheet5存在,并且这是工作表的未修改代号。 I can not use the user defined name of the sheet because that can change.
我无法使用工作表的用户定义名称,因为可以更改。
Public MyWS As String
declares a String
variable, not an object. Public MyWS As String
声明一个String
变量,而不是一个对象。
The CodeName
property returns a String
that contains an identifier that VBA uses to generate a project-scoped object variable for a Worksheet
; CodeName
属性返回一个String
,其中包含VBA用于为Worksheet
生成项目范围的对象变量的标识符。 in the properties toolwindow (F4), that's the (Name)
property. 在属性工具窗口(F4)中,即为
(Name)
属性。
This is how such code is legal: 这样的代码是合法的:
Sheet1.Range("A3").Value = 42
Because Sheet1
has a code name string that returns Sheet1
. 因为
Sheet1
的代码名称字符串返回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. 请注意,此标识符不一定是工作表的名称 (尽管默认情况下是默认 名称 ),用户可以在不访问Visual Basic编辑器的情况下随时对其进行更改。
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”选项卡/工作表重命名为“ Summary”,但不更改其代号 ,则代码中仍为
Sheet1
因此,这两个指令的作用完全相同:
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. 现在,如果您想要一个对象变量保存一个在编译时存在的对工作表的引用, 那么您已经有了一个
Sheet1
就是这样。
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: 在这种情况下,您需要声明自己的名称,并使用
Set
关键字进行分配:
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. Excel对象模型还具有
ActiveSheet
对象,该对象将返回当前处于活动状态的图纸。
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:
如果是在标准模块(.bas)中编写的,则此代码等效:
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. Me
所在的位置与您所在的特定工作表模块无关,因此,如果您在工作表模块中编写该代码,则需要使用ActiveSheet
对象显式限定Range
成员调用。
If you need to execute code when a worksheet is activated, you can handle the SheetActivate
event in the ThisWorkbook
module: 如果需要在激活工作表时执行代码,则可以在
ThisWorkbook
模块中处理SheetActivate
事件:
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: 如果需要处理在编译时存在的特定工作表的
Activated
事件,则需要在该工作表的代码背后为其提供事件处理程序:
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): 如果需要处理在运行时创建的工作表的事件,则需要在类模块 (.cls)中使用
WithEvents
对象变量:
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 :) 然后,您可以在该模块中为
MySheet_Activate
编写一个处理程序,但这是更高级的内容,在这里我几乎MySheet_Activate
,但这应该可以使您继续:)
With ActiveSheet
as mentioned in the comments is really the best solution. 如评论中所述,
With ActiveSheet
确实是最好的解决方案。
However, if you want to do it "your way", write these Activate
events in every worksheet: 但是,如果要“按自己的方式”进行操作,请在每个工作表中编写以下
Activate
事件:
Private Sub Worksheet_Activate()
lastWS = Me.Name
End Sub
Then lastWs
would be the name of the ActiveSheet. 然后,
lastWs
将是ActiveSheet的名称。 And you would be able to refer to it like this Worksheets(lastWs)
. 您将可以像
Worksheets(lastWs)
这样引用它。 Thus: 从而:
Sheet1.Range("A3").Value = Worksheets(lastWs).Range("A3").Value
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.