简体   繁体   English

VBA-使用变量引用对象

[英]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变量,而不是一个对象。

CodeName 代码名称

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

ActiveSheet ActiveSheet

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成员调用。


Worksheet Events 工作表事件

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM