VBA - 使用变量

时间:2018-04-20 12:54:29

标签: excel vba excel-vba

不确定如何使用每次激活工作表时更改的变量引用工作表对象。

关键是根据最后激活的工作表引用一个单元格值(此代码影响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存在,这是工作表的未修改的代号。我无法使用工作表定义的工作表名称,因为它可以更改。

2 个答案:

答案 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

ActiveSheet

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