避免使用 SELECT 或 ACTIVATE

這是非常罕見的,你永遠要使用 SelectActivate 在你的程式碼,但一些 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 指的是包含正在執行的程式碼的工作簿。