我可能会失明,但我已经和VBA合作了几年但仍然写出来
Workbook("Book1").Sheets("Sheet1").Range("A1").Value
或(将Book1调整为工作簿,将Sheet1调整为字符串
Book1.Sheets(Sheet1).Range("A1").Value
有没有办法可以简写" workbook.sheets" part(没有做" With"语句)?
答案 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
使用对象。声明对象,分配对象引用并使用它们,将它们作为参数传递给您的过程。没有理由不断地像你一样去解除对象。 如果你需要这样做,那么你只需要一次。
答案 1 :(得分:5)
不确定。只是以正确的方式做到:
vals['a'] => 1
(抱歉Mat的马克杯 - 我不得不对第一行进行一些挖掘:D)
答案 2 :(得分:3)
好的,我将从字面上理解“Book1”这个名称,并假设您正在编写代码来处理 new 工作簿 - 可能是这样的:
Dim myWorkbook As Workbook
Workbooks.Add
Set myWorkbook = Workbooks("Book1")
这已经是一个糟糕的开始,因为:
因此,许多没有经验的编码员会尝试这样做:
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