workbook()。worksheets()的简写?

时间:2017-04-11 03:10:18

标签: excel vba excel-vba

我可能会失明,但我已经和VBA合作了几年但仍然写出来

Workbook("Book1").Sheets("Sheet1").Range("A1").Value

或(将Book1调整为工作簿,将Sheet1调整为字符串

Book1.Sheets(Sheet1).Range("A1").Value

有没有办法可以简写" workbook.sheets" part(没有做" With"语句)?

5 个答案:

答案 0 :(得分:9)

不确定。只是以错误的方式做到:

Sheet1.Activate
Range("A1").Value = 42

在标准代码模块中不合格,Range_Global的成员,它通过在任何工作表恰好处于活动状态时返回指定范围来实现其Range属性...任何(在工作表的代码隐藏中,它隐含地引用Me.Range,即该表上的范围。)

如果您要隐式处理ActiveSheet,您还可以使用性能较低的后期绑定调用将类型解析延迟到运行时,并创建主机应用程序(这里Excel)评估一个括号内的表达式,以便更快地输入:

[A1].Value = 42

哎呀,Range类型的默认成员指向Value,所以你甚至可以这样做:

[A1] = 42

正如您所看到的, less 代码并不总是更好的代码。限定您的Worksheet会员电话,并有意识和明智地使用默认会员。

每当有人在_Global上进行隐含调用时,一个婴儿独角兽就会死亡,并且两个新的Stack Overflow问题涉及来自不合格工作表调用的错误,这些问题都是从黑暗中召唤出来的。

除了讽刺之外,如果你发现自己经常链接这样的Workbook("Book1").Sheets("Sheet1").Range(...)...个调用,那么你会不断地反复引用相同的对象,一遍又一遍:这不仅是类型的冗余,而且执行也是多余的。

如果您正在使用ThisWorkbook(运行代码的工作簿),那么从不有合理的理由来取消引用编译时存在的工作表。请改用代码名称

Sheet1.Range(...)...

如果工作簿仅在运行时存在,或者不是ThisWorkbook,那么在您的代码打开或创建该工作簿的某个时间点 - 没有必要从{{1}取消引用它收集,...如果你在第一时间存储了引用:

Workbooks

与代码在其他工作簿中在运行时创建的工作表相同:保留该对象引用!

Set wbExisting = Workbooks.Open(path)
Set wbNew = Workbooks.Add

这只留下一个场景,您需要一个字符串来取消引用特定工作表:该工作簿已存在于非Set wsNew = wbNew.Worksheets.Add 的工作簿中。

如果该工作簿的结构没有(或不能)受到保护,请尽可能避免对工作表的索引或名称进行硬编码:

ThisWorkbook

TL; DR

使用对象。声明对象,分配对象引用并使用它们,将它们作为参数传递给您的过程。没有理由不断地像你一样去解除对象。 如果你需要这样做,那么你只需要一次

答案 1 :(得分:5)

不确定。只是以正确的方式做到:

vals['a'] => 1

(抱歉Mat的马克杯 - 我不得不对第一行进行一些挖掘:D)

答案 2 :(得分:3)

好的,我将从字面上理解“Book1”这个名称,并假设您正在编写代码来处理 new 工作簿 - 可能是这样的:

Dim myWorkbook As Workbook
Workbooks.Add
Set myWorkbook = Workbooks("Book1")

这已经是一个糟糕的开始,因为:

  1. 用户的语言将决定名称的“预订”部分。
  2. 数字后缀将随每个新的工作簿一起增加
  3. 因此,许多没有经验的编码员会尝试这样做:

    Dim myWorkbook As Workbook
    Workbooks.Add
    Set myWorkbook = ActiveWorkbook
    

    但这也是错误的。如果有事件处理程序想要更改活动工作簿怎么办?什么是用户在单步执行代码时更改活动工作簿?

    分配myWorkbook变量的最佳方法是使用以下内容:

    Dim myWorkbook As Workbook
    Set myWorkbook = Workbooks.Add
    

    而且,就像添加新工作簿一样,在打开现有工作簿时应该遵循相同的方法:

    Dim myWorkbook As Workbook
    Set myWorkbook = Workbooks.Open("C:\Foo.xlsx")
    

    在这两种情况下,您知道您已获得对正确工作簿的引用,并且您不关心它所谓的是否它活跃。您刚刚使代码更加健壮更高效。

    或者,如果您的VBA正在使用它所在的工作簿,您可以使用ThisWorkbook或工作表的代号。

    Debug.Print ThisWorkbook.Name
    
    'By default, a sheet named "Sheet" has a codename of 'Sheet1'
    Debug.Assert Sheet1.Name = ThisWorkbook("Sheet1").Name
    
    'But give meaningful names to your sheet name and 
    'sheet codename, and your code becomes clearer:
    Debug.Assert AppSettings.Name = ThisWorkbook("Settings").Name
    

    您可能会发现大多数代码都处理它所在的工作簿,代码打开的现有工作簿或代码创建的新工作簿。所有这些情况都在上面处理。在极少数情况下,您的代码必须与已经打开的工作簿交互,或者由其他进程打开,您需要按名称引用工作簿,或者枚举Workbooks集合:

    Dim myWorkbook As Workbook
    Set myWorkbook = Workbooks("DailyChecklist.xlsx")
    
    For Each myWorkbook In Workbooks
      Debug.Print myWorkbook.Name
    Next myWorkbook
    

    一个例外是加载项,使用Workbooks集合无法枚举,但可以使用Workbooks("MyAddin.xlam")

    引用

答案 3 :(得分:2)

喜欢这个

Sub temp()
    Dim WB As Workbook, WS As Worksheet
    Set WB = ActiveWorkbook
    Set WS = WB.Sheets(2)
    MsgBox WS.Range("A2").Text
End Sub

答案 4 :(得分:0)

您可以设置工作表变量及其父工作簿

Dim wb1s1 As Worksheet
Set wb1s1 = Workbook("Book1").Sheets("Sheet1")

然后写

wb1s1.Range("A1").Value