不确定如何使用每次激活工作表时更改的变量引用工作表对象。
关键是根据最后激活的工作表引用一个单元格值(此代码影响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
更新
感谢您的所有指导,但至少您的说明不符合我的项目。
Sheet5.Range(“C4”)。Value = Worksheets(MyWS).Range(“A2”)。Value
在Sheet5停用时执行上述代码时,下标超出范围错误。
MyWS被声明为公共字符串。 激活Sheet5时,为MyWS分配Sheet5.CodeName字符串。 Sheet5存在,这是工作表的未修改的代号。我无法使用工作表定义的工作表名称,因为它可以更改。
答案 0 :(得分:2)
Public MyWS As String
声明String
变量,而不是对象。
CodeName
属性返回String
,其中包含VBA用于为Worksheet
生成项目范围的对象变量的标识符;在属性工具窗口(F4)中,这是(Name)
属性。
这就是这样的代码是合法的:
Sheet1.Range("A3").Value = 42
因为Sheet1
的代码名称字符串返回Sheet1
。请注意,此标识符不一定是工作表的名称(默认情况下 ),用户可以随时更改,而无需访问Visual Basic编辑器。
因此,如果您将“Sheet1”标签/工作表重命名为“摘要”,但不更改其代码名称,那么代码中仍然会Sheet1
- 所以这些两条指令完全相同:
Sheet1.Range("A3").Value = 42
ThisWorkbook.Worksheets("Summary").Range("A3").Value = 42
现在,如果您希望一个对象变量保存对编译时存在的工作表的引用,您已经有一个 - Sheet1
就是这样。
如果您在工作表中添加了一个运行时(在编译时不存在),那么该工作表就没有这样的项目范围对象变量;当您需要声明自己的时候,并使用Set
关键字指定它:
Dim someSheet As Worksheet
Set someSheet = ThisWorkbook.Worksheets.Add
Excel对象模型还有ActiveSheet
对象,它返回当前活动的任何工作表。
Sheet1.Range("A3").Value = ActiveSheet.Range("A3").Value
注意显式限定符。如果它是用标准模块(.bas)编写的,则此代码是等效的:
Sheet1.Range("A3").Value = Range("A3").Value
如果它是在特定工作表模块的代码隐藏中编写的,那么上面的代码将改为:
Sheet1.Range("A3").Value = Me.Range("A3").Value
Me
是您所在的特定工作表模块的位置,因此,如果您在工作表模块中编写该代码,则需要明确限定Range
成员调用ActiveSheet
对象。
如果您需要在激活工作表时执行代码,则可以在SheetActivate
模块中处理ThisWorkbook
事件:
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
如果您需要处理编译时存在的特定工作表的Activated
事件,那么在该工作表的代码隐藏中需要一个事件处理程序:
Private Sub Worksheet_Activate()
Debug.Print Me.Name & " activated!"
End Sub
如果需要为在运行时创建的工作表处理该事件,则需要类模块中的WithEvents
对象变量(。cls):
Private WithEvents MySheet As Worksheet
然后你可以在那个模块中为MySheet_Activate
写一个处理程序,但那是更高级的东西,我在这里几乎没有表面,但是那应该让你去:)
答案 1 :(得分:1)
With ActiveSheet
确实是最好的解决方案。
但是,如果您想“按照自己的方式”执行此操作,请在每个工作表中编写这些Activate
个事件:
Private Sub Worksheet_Activate()
lastWS = Me.Name
End Sub
然后lastWs
将成为ActiveSheet的名称。你可以像Worksheets(lastWs)
那样引用它。因此:
Sheet1.Range("A3").Value = Worksheets(lastWs).Range("A3").Value