避免使用 SELECT 或 ACTIVATE
这是非常罕见的,你永远要使用 Select
或 Activate
在你的代码,但一些 Excel 的方法需要做的工作表或工作簿被激活之前预期他们会工作。
如果你刚刚开始学习 VBA,通常会建议你使用宏录制器录制你的动作,然后查看代码。例如,我记录了在 Sheet2 上输入单元格 D3 中的值所采取的操作,宏代码如下所示:
Option Explicit
Sub Macro1()
'
' Macro1 Macro
'
'
Sheets("Sheet2").Select
Range("D3").Select
ActiveCell.FormulaR1C1 = "3.1415" '(see **note below)
Range("D4").Select
End Sub
但请记住,宏录制器会为你的(用户)操作创建一行代码。这包括单击工作表选项卡以选择 Sheet2(Sheets("Sheet2").Select
),在输入值(Range("D3").Select
)之前单击单元格 D3,然后使用 Enter 键(有效地选择当前所选单元格下方的单元格:Range("D4").Select
)。
这里使用 .Select
有很多问题:
- **并不总是指定工作表。**如果在录制时不切换工作表,则会发生这种情况,这意味着代码将为不同的活动工作表生成不同的结果。
- **
.Select()
很慢。**即使Application.ScreenUpdating
设置为False
,这也是一个不必要的处理操作。 - **
.Select()
是不守规矩的。**如果Application.ScreenUpdating
留给True
,Excel 实际上会选择单元格,工作表,表格……无论你正在使用什么。这对眼睛来说很紧张,看起来真的很不愉快。 - **
.Select()
将触发听众。**这已经有点先进,但除非解决,否则会触发像Worksheet_SelectionChange()
这样的功能。
当你在 VBA 中编码时,不再需要所有键入操作(即 Select
语句)。你的代码可以简化为单个语句,以将值放入单元格中:
'--- GOOD
ActiveWorkbook.Sheets("Sheet2").Range("D3").Value = 3.1415
'--- BETTER
Dim myWB As Workbook
Dim myWS As Worksheet
Dim myCell As Range
Set myWB = ThisWorkbook '*** see NOTE2
Set myWS = myWB.Sheets("Sheet2")
Set myCell = myWS.Range("D3")
myCell.Value = 3.1415
(上面的更好示例显示使用中间变量来分隔单元格引用的不同部分 .GOOD 示例将始终正常工作,但在更长的代码模块中可能非常麻烦,如果其中一个引用输入错误则更难以调试。 )
**注意:宏录制器会对你输入的数据类型做出许多假设,在这种情况下输入字符串值作为创建值的公式。你的代码不必执行此操作,只需将数值直接分配给单元格,如上所示。
**注意 2:建议的做法是将本地工作簿变量设置为 ThisWorkbook
而不是 ActiveWorkbook
(除非你明确需要它)。原因是你的宏通常需要/使用 VBA 代码所源自的任何工作簿中的资源,并且不会在该工作簿之外查看 - 除非你明确指示你的代码与其他工作簿一起使用。当你在 Excel 中打开多个工作簿时,ActiveWorkbook
的焦点可能与你在 VBA 编辑器中查看的工作簿不同。因此,当你真正引用另一个工作簿时,你认为你正在执行一个工作簿。ThisWorkbook
指的是包含正在执行的代码的工作簿。