VBA 巨集入門介紹,第一次學必看

VBA為一種程序語言,主要用來設定Office系列軟體的自動化程序,VBA最常被用來處理Excel重複性的工作,另也可以用來設定不同應用程式間如Excel與Word、PowerPoint之間的自動化設定,例如設定將Excel資料表的數據自動貼到Word的文件裡的指定標籤上。
在Excel Powe功能(如Power Query、Power Pivot)普及之前,VBA幾乎代表了一個人Excel的操作能力,最近小編與同事聊天時,詢問同事使用Excel的狀況,他第一個反應竟是回答說:「欸...我不太會巨集,但其他的....還可以。」,此段對話也讓小編會心一笑。

本篇文章將先簡介VBA及VBA編輯器,接著說明VBA巨集的編寫流程,並以實際範例帶著大家一起編寫巨集。

VBA 簡介

VBA是Visual Basic for Applications的縮寫,VBA為一種程序語言(以下稱VBA),係於西元1993年由Microsoft公司發布,取代了先前的XLM語言,Excel專家Bill先生於他最新出版的書中預測:VBA可以至少繼續使用到西元2049年,仍是相當值得投資學習的程序語言。

VBA編寫的程式稱為巨集(Macro),例如可以說:「我寫了一個巨集,幫我檢查一下好嗎。」

20230209_G1

含有巨集的Excel檔案類型為.xlsm,而不含巨集的Excel檔案類型為.xlsx,等等會介紹打開.xlsm檔案時需注意的安全事項。

20230209_P1

若要於Office系列軟體編寫VBA,需先進入VBA編輯器,進入的方式有兩種:
(1)使用鍵盤快捷鍵:Alt + F11進入。
(2)於Tab Developer -> Visual Basic 點選進入(如下圖)

20230209_P2

若各位的Tab上找不到開發者(Developer)不要擔心,因為其預設為隱藏,可至File -> Options -> Customize Ribbon裡面進行勾選開啟。(如下圖)

20230209_P3

接著簡單介紹一下打開.xlsm檔案類型需注意的安全事項,因為VBA具備「事件(Event)」觸發程式碼的功能,例如打開檔案(工作簿)就是一種事件,故如果使用來源不明的.xlsm檔案,可能在打開工作簿後,VBA會刪除你電腦中資料夾的檔案,或將你電腦中的檔案自動發送Email轉給他人,故在打開檔案前要特別留意

Office系列軟體已針對防範上述的資安風險具備了相關的安全設定,可於Tab Developer -> Macro Security點選進入信任中心(Trust Center)的巨集設定(Macro Settings)查看,如下圖各位可以看到預設值為Disable VBA macros with notification,意思是:打開.xlsm檔案後並不會馬上激活VBA巨集,會先出現提示通知,當用戶點選同意激活後,才會激活VBA巨集,建議維持此設定。(如下圖)

20230209_P10
20230209_P11

上述說明的提示通知畫面請參考如下圖。

20230209_P12

另外Microsoft對於從網域中下載的.xlsm檔案,還有另外一種檔案封鎖(Block)的防護機制,各位可以看到(如下圖)打開檔案後跳出的警告提示為:Microsoft has blocked macros from running because the source of this file is untrusted。此狀況是無法激活VBA巨集的。

20230209_P14

若各位要開啟如上述被封鎖的.xlsm檔案,大致分為兩種處理方式:
(1)檔案可能放在區域網內的路徑,試著把檔案下載到自己電腦的硬碟上,應該就可以正常開啟。

(2)還是不行的話,滑鼠左擊檔案 ->點選內容(如下圖),各位可以看到右下角有個解除封鎖的方塊,把它打勾後,應該就可以正常地開啟檔案。

20230209_P13

以上已介紹完了編寫VBA巨集前及開啟含巨集檔案前應注意的事項,接下來將跟各位介紹VBA編輯器。

VBA 編輯器環境介紹

如上所述,各位可使用快捷鍵 Alt + F11進入VBA編輯器,進入後的畫面如下圖。

20230209_P4

畫面左側為專案總管(VBAProject)視窗,在此處顯示了你電腦Excel相關的VBA巨集項目,尚未編寫程式前,各位可以看到只有Excel物件(Objects)含工作表(Sheet)與工作簿(Workbook)。

20230209_P18

PS 如果您的電腦有安裝插件(Add-ins),那你還會看到插件的巨集。(範例如下圖)

20230209_P21_1

VBAProject視窗下方為屬性(Properties)視窗,如下圖當我們於VBAProject視窗選擇Sheet1 (Sheet1)時,於Properties視窗會顯示出相關Sheet1的屬性設定,使用者可在此調整設定,例如可調整工作表的名稱(Name)、自動計算激活與否(EnableCalculation),或顯示與否(Visible,如果你選擇0 - xlsheetHidden,代表一般的隱藏,使用者可以解除隱藏;如果您選擇2 - xlsheetVeryHidden,則使用者將不會知道此工作表的存在)。

20230209_P20

上述介紹了VBA編輯器中的兩個預設顯示視窗,其他還有如瀏覽物件(Object Brower)、即時運算視窗(Immediate Window)、區域變數視窗(Locals)及監看視窗(Watch Window)等等(如下圖),其用途將於未來文章中陸續介紹。

20230209_P22

接著介紹於VBA編輯器中編寫程式碼的地方,可簡單依使用目的分為三大類:
1.事件(Event):事件如前述所提,係為以事件觸發程式碼,其又分為工作表(Sheet)及工作簿(Workbook)兩種物件,於下圖範例中,以滑鼠左鍵連續兩次點擊VBAProject中的Sheet1 (Sheet1),將會打開工作表的事件程式編碼區。

20230209_P23

2.模組(Module):此為最常使用編寫巨集的方式,點選Tab Insert -> Module 進行插入,如下圖插入後各位可以看到VBAProject視窗中出現了Module資料夾及其中包含了預設名稱為Module1的模組,再以滑鼠左鍵連續兩次點擊Module1打開程式編碼區(如下下圖)。

20230209_P19
20230209_P7

3.表單(UserForm):此為較進階的功能,可自製使用者介面(讓人有專業的感覺),點選Tab Insert -> UserForm 進行插入,如下圖插入後各位可以看到VBAProject視窗中出現了Forms資料夾及其中包含了預設名稱為UserForm1的表單,再以滑鼠左鍵連續兩次點擊UserForm1打開表單編輯區。

20230209_P6
20230209_P17

接下來,將跟各位介紹巨集的編寫流程。

VBA 巨集的編寫流程(含範例)

巨集的編寫流程可分為5個步驟:
1.巨集名稱設定
2.宣告變數
3.定義變數
4.主程式碼編寫
5.偵錯

以下將於模組(Modules)中,以實際範例帶著大家了解編寫巨集的流程,此範例的程式用途為:

將使用者輸入於儲存格B2的數字(1~10)與儲存格B7:B16範圍進行比對,並將相同數字的儲存格變為黃色。(如下動圖)

20230209_G2_1

編寫巨集之前,請各位先依照前述步驟插入一個Module,再打開Module1模組,進入程式編碼區。(如下圖)

20230209_P7

1.巨集名稱設定

於程式碼編輯區裡可以編寫很多的巨集,每一個巨集的開頭跟結尾,一般皆為:

Sub 巨集名稱()
End Sub

巨集的名稱不能為數字開頭、不能有特殊符號、不能有空白,其他沒有甚麼特別限制;例如此範例小編取名為:CheckNumber_1to10。(如下圖)

20230209_P26

2.宣告變數

宣告變數前,先讓我們想一想此範例需用到的變數,(如下圖)最直觀的變數有兩個,一個是使用者要輸入的input(儲存格B2),及要比對數字的範圍(儲存格B7:B16);另外還有一個變數是等等主程式碼會用到的迴圈遞增整數,共3個變數。

20230209_P27

於VBA中,宣告變數的語法為:

Dim 變數名稱 As 資料類型(Data Type),或
Dim 變數名稱 As 物件類型(Object)

其中,若沒有設定 As 資料類型,VBA預設的資料類型為VariantVariant雖可代表任何的資料類型,但佔了最大的記憶體16 bytes,恐會影響到程式的效能。

此範例的第一個變數為使用者input,故小編將其命名為InputValue,因此變數為1~10的數字,故資料類型選擇為佔記憶體最小的類型As Byte(0~255);

第二個變數為程式要比對的數字範圍,命名為RngCheck(一般會習慣將Range簡寫為Rng),因此種變數為範圍物件,故設定為As Range

第三個變數為迴圈的遞增整數,一般常用i、m、n等簡單的英文字母命名,本範例使用i,資料類型亦設為As Byte。(如下圖)

20230209_P28_1

下表介紹了VBA中各種變數的資料類型及其所佔的記憶體,此表擷取自Leila專家的Youtube頻道影片,各位不妨點開觀賞學習,另也推薦Leila專家的VBA課程給大家。

20230209_P29

3.定義變數

針對數值(Value)的變數,定義變數的語法為:

Let 變數名稱 = XXXX
其中Let可省略不寫,習慣上均省略。

另針對物件(Object)的變數,定義變數的語法為:

Set 變數名稱 = XXXX
一定要寫出Set,不然會出現異常提示

此範例的第一個變數InputValue,定義為:Let InputValue = Activesheet.Range("B2"),Activesheet.Range("B2")意即為目前工作表的儲存格B2;

第二個變數RngCheck則定義為:Set RngCheck = Activesheet.Range("B7", "B16"),Activesheet.Range("B7", "B16")意即為目前工作表的儲存格範圍B7:B16。(如下圖)

20230209_P30

下圖為若定義物件RngCheck沒有使用Set的話,執行程式會出現的異常訊息。

20230209_P40

完成宣告變數及定義變數後,接下來的主程式碼就可以利用變數來進行程式編寫,可簡化程式碼及提升程式的效能。

PS 於程式碼最右邊若要註記說明,可使用「' + 說明」的方式,字體會自動變為綠色,此註記不會影響到程式碼的執行。

4.主程式碼編寫

編寫程式碼其實不難,幾乎所有VBA語法問題都可以在Google後得到解答,關鍵在於你是否有想清楚此程式執行的步驟與邏輯,以本範例來說,請各位先想一想此程式執行的步驟為何?

20230209_P31

此程式執行的步驟應為:

將InputValue變數於RngCheck範圍內的儲存格一個一個進行比對,若比對結果相等,則將此儲存格變為黃色及跳出程式,若比對結果不相等,則繼續跳至下一個儲存格進行比對。

將上述步驟以程式碼講解則為:

寫一個迴圈(最多10次的迴圈),迴圈中設定邏輯If RngCheck的值=InputValue,則將儲存格變黃色並跳出程式,否則執行下一個迴圈。

了解程式執行的步驟後,就可較容易地開始進行編寫。

20230209_P32

 於VBA裡有好幾種迴圈的語法,如For...NextDo...LoopDo Until...Loop等,本範例小編使用For...Next的語法,於上圖中可以看到迴圈的程式碼為:

For i = 1 To 10

Next i

上述程式碼:i = 1 To 10是定義迴圈的次數,在執行完第10次迴圈後,才會跳出此迴圈,繼續執行接下來的程式碼。(程式編寫過程如下動圖)

20230209_G3

另外,於迴圈中我們使用If語法進行邏輯確認,完整的If的語法為:

If ....Then
ElseIf ...Then (可多個ElseIf)
Else ...
End If

因此範例僅有一個邏輯,故只需使用If ...Then ...End If即可,小編先以口語化說明程式碼:

If RngCheck的儲存格 = InputValue 的話 Then
RngCheck的儲存格變黃色,及跳出程式
End If

實際程式碼如下圖:

20230209_P33

接著讓小編來說明一下RngCheck.Cells(i, 1)的意思,因為RngCheck為一個儲存格範圍,若要利用迴圈中的遞增整數變數i,來動態地表示RngCheck中某一個儲存格,可利用.Cells方法(Method),.Cells的參數為:.Cells(列位, 欄位),此範例中列位為變數i,欄位固定為1,故表示為:

RngCheck.Cells(i, 1)

當邏輯確認:RngCheck.Cells(i, 1) = InputValue成立時,則將儲存格變為黃色,儲存格變色的方法(Method)為.Interior.Color,黃色為RGB(255, 255, 0),故儲存格變黃色的程式碼為:

RngCheck.Cells(i, 1).Interior.Color = RGB(255, 255, 0)

變色後接著跳出程式(巨集),語法為Exit Sub。(程式編寫過程如下影片)

巨集編寫到這裡已可算是完成,但考量到若使用者輸入的數字沒有在1~10的範圍內,那在使用者執行巨集後,會發現什麼也沒改變,此種使用者體驗較差,故應該再增加一個訊息視窗的程式碼,於迴圈執行完後接著執行。

於VBA中此訊息視窗的語法為MsgBox (Msg為Message之意),使用方式:

MsgBox "你要傳達的訊息"

執行完MsgBox後,才會結束巨集(End Sub)。(如下圖)

20230209_P34

5.偵錯

任何一個人在編寫程式的過程中,幾乎不可能一次寫出100%完美的程式,故「偵錯(Debug)」在巨集編寫中是一個很重要的流程。偵錯的方法有好幾種,本篇文章將介紹最基本的一種:逐行(Step Into),意即依程式碼一行一行地執行,各位可使用快捷鍵F8,按一次F8就執行一行。

20230209_P35

於以下影片中,小編分別於儲存格B2輸入3及11兩種狀況下進行偵錯(測試程式),讓大家了解實際上偵錯的過程長什麼樣子(搭配快捷鍵F8)

另外,快捷鍵F5或下圖標示處的功能為執行程式(Run Sub),若各位不想一行一行地偵錯,可直接按F5執行程式查看結果。

20230209_P36

以上就完成了巨集編寫的流程說明。

完成了巨集編寫後,讓我們回到Excel中插入一個程式執行按鈕(Button),步驟為:Tab Developer -> Insert -> Button。(如下圖)

20230209_P37

再以滑鼠右鍵點擊按鈕 -> Assign Macro...,以指定巨集給此按鈕。

20230209_P38_1

接著跳出指定巨集(Assign Macro)視窗,因本範例只編寫了一個巨集:CheckNumber_1to10,故選擇CheckNumber_1to10後,按OK離開視窗。

20230209_P39

完成按鈕設定後,就可以讓使用者便利地執行此巨集。(如下動圖)

20230209_G2_1

總結及補充:

本篇文章先介紹了VBA簡介、.xlsm檔案打開的安全事項及VBA編輯器,接著介紹了VBA 巨集的編寫流程及於Excel中插入巨集按鈕的方法,相信各位讀到這裡應已對VBA有了初步的認知。

因文章篇幅考量,本篇文章沒有介紹事件(Event)及表單(UserForm)的巨集如何編寫,但因為小編覺得表單功能很酷,故在此先給各位參考一下小編曾做過的表單(使用者介面)。

1.生產日報數據修改表單:

20230209_P15

2.DCS(分散式控制系統)的模擬器表單:

20230209_P16

各位看到以上兩張表單照片應該會覺得蠻特別的,小編還記得第一次成功地做出表單是相當興奮、具有成就感的,未來將再與各位分享表單的製作流程。

另外,之前已學過VBA的讀者可能會發現:為什麼本篇文章沒有介紹「錄製巨集」的功能,很多VBA課程會第一個介紹它,其實是因Microsoft 錄製巨集的功能被公認為不太完善、好用,使用上還有不少小技巧要注意,小編個人也是較少使用,有時僅是利用錄製巨集所得到的程式碼,再Google做進一步的查詢及進行程式碼測試。

最後提醒大家,在Excel Power Query動態陣列公式等Power功能出現以後,許多原先要用VBA 巨集才能辦到的事情(如資料整理ETL、進階篩選等),現在都可在Excel中直接達成,意即在Excel Power功能出現之後,VBA的程式碼可以大幅簡化,因而能讓更多的人進行VBA編寫及維護,這是很重要的轉變!因為使用VBA的其中一個缺點就是較難維護及修改,例如於業界中,一個VBA很厲害的人離職了,那可能有很多巨集的檔案就因此無人再用了呢,建議各位要想著如何結合Excel新功能來最有效率地編寫VBA巨集。

這篇文章對您有幫助嗎?

平均評分 4.3 / 5. 7

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

1 Comment

  1. Alice on 2023-02-21 at 23:40

    對新手學習VBA很有幫助

發表迴響