VBA Exit Sub用法:提前結束程式,搭配If判斷的Excel實例教學

VBA Exit Sub可以讓程式執行到一半就提前結束。贊贊小屋在Excel匯率工作表遇到重複建立的問題,請ChatGPT說明Exit Sub的作法,再搭配If判斷,回到Excel實際程式逐行解讀,並看出只檢查最後一張工作表的限制。

VBA Exit Sub用法特色圖:條件判斷分成兩條路徑,條件成立時執行Exit Sub結束目前Sub,條件不成立時繼續執行,標題為「VBA Exit Sub用法」與「提前結束程式,搭配If判斷」

一、Excel匯率表出現今天的工作表已經存在

贊贊小屋先從Excel的執行結果看起。這個活頁簿裡已經有「最新匯率」和以今天日期命名的「261029」工作表,畫面上是各幣別的匯率資料,中間跳出一個「Microsoft Excel」訊息視窗,文字是「今天的工作表已經存在!」,按下「確定」後程式就結束,不會再新增另一張同名的工作表。

這段提示不是Excel自己判斷出來的,而是贊贊小屋的VBA程式裡寫好的訊息。程式先把今天的日期轉成六位數字,和最後一張工作表的名稱比對,兩者相同就視為今天的工作表已經存在,顯示這句話,接著用Exit Sub結束,後面新增工作表的程式碼不會再執行。

重複執行巨集時,最怕的就是同樣的動作被做了第二次。以匯率備份為例,每天要新增一張以日期命名的工作表,如果同一天不小心再按一次巨集,沒有任何防護就會嘗試再建立同名工作表。所以這個例子要處理的是「在什麼條件下應該停止」,而不只是「怎麼新增工作表」。不過這個畫面只能說明這一次執行時,程式判斷到今天的工作表已經存在;不同的工作表排列方式下判斷是否都正確,還得看完整的程式內容才能回答。

Excel出現訊息視窗「今天的工作表已經存在!」,工作表標籤有「最新匯率」與「261029」 第一節重點卡:最後一張工作表名稱與今天日期相同時顯示提醒並執行Exit Sub,不同時嘗試新增工作表

二、從原本的ChatGPT對話建立新分支

這個問題的起點,是贊贊小屋先前在ChatGPT討論的「VBA 合併 Sub 錯誤」。那段對話中,ChatGPT把流程整理成兩步:第一步下載臺灣銀行匯率並更新「最新匯率」工作表,第二步複製工作表並命名成今天日期,例如261028,最後顯示完成。回覆的最後還提醒了一個VBA觀念:Sub是一個獨立的程序,不能靠註解End Sub把兩個程序黏在一起,想讓多個程序依序執行,應該使用另一個主程序呼叫它們。這個問題在VBA兩個Sub有完整整理。

這個回覆讓贊贊小屋想進一步弄清楚程式中的Exit Sub。這時不必另開新對話重新交代背景,而是在這則回覆下方點選「⋯」,選單出現「分支至新對話」,點下去就能延續原本的討論內容,另外開一條專門研究Exit Sub的對話。左側的對話列表中可以看到原本的「VBA 合併 Sub 錯誤」,分支建立後會多出新的項目。

一個實際的VBA工作常常同時牽涉好幾個語法概念,例如兩個Sub怎麼組合、工作表重複時怎麼停止。把它們放在同一個對話裡,之後回頭看紀錄時容易混在一起;分支出來之後,原本的對話仍然保留,新的對話只處理這一次想學的語法,學習的焦點會比較清楚。

在ChatGPT回覆下方點選「⋯」,選單出現「分支至新對話」 第二節重點卡:從原本的「VBA合併Sub錯誤」對話建立新分支,保留原本對話並展開Exit Sub學習路線

三、重新命名VBA學習對話

分支建立後,左側「最近項目」多了一筆「分支 · VBA 合併 Sub 錯誤」。贊贊小屋把游標移到這個項目上,點選右邊的「⋯」,選單依序列出「重新命名」「釘選」「分享」「封存」「刪除」「移至專案」,這次選的是最上面的「重新命名」。

新分支預設用「分支 ·」加上原對話名稱,看不出這個對話現在在談什麼。重新命名後,這條對話就成了「Exit Sub 作用」,一眼就知道裡面是Exit Sub的學習紀錄。

把實際工作的問題和單一語法的研究分開命名,之後想複習Exit Sub時,不必在一長串VBA對話裡逐一點開找,原本處理匯率程式的對話也不會被語法討論蓋住。

ChatGPT左側對話選單列出「重新命名」「釘選」「分享」「封存」「刪除」「移至專案」,分支對話已送出Exit Sub的提問 第三節重點卡:對話名稱從「分支 · VBA 合併 Sub 錯誤」重新命名為「Exit Sub 作用」

四、詢問ChatGPT了解Exit Sub的基本作用

Exit Sub的作用,是立即結束目前正在執行的Sub,後面的程式碼不再執行。贊贊小屋在新的分支對話中輸入的問題是:

傳給ChatGPT的問題Exit Sub 作用是什麼?可以用一個簡單的範例介紹嗎?就是一般經典教科書的那種範例。

ChatGPT的回答先給出定義:Exit Sub的作用,是立即結束目前正在執行的Sub程序,不再繼續執行後面的程式碼,並把它比喻成教科書裡的「提前結束指令」。接著在「一、經典範例」底下提供第一個簡單的程式,先顯示「第一步:開始執行」,遇到Exit Sub就結束,第二個訊息不會出現:

VBA程式|ExitSub範例()Sub ExitSub範例()
    MsgBox "第一步:開始執行"
    Exit Sub
    MsgBox "第二步:繼續執行"
End Sub

這個範例最容易看出Exit Sub的效果:第一個MsgBox之後就是Exit Sub,所以程式停在這裡,「第二步:繼續執行」那一行不會被執行。要注意的是,ChatGPT這一小節的標題寫的是「判斷成績是否及格」,但程式內容其實只是兩個訊息,真正的成績判斷在下一個範例才出現;贊贊小屋這次也沒有另外執行這段程式,只是用它理解Exit Sub的順序。

Exit Sub既不是暫停,也不是關閉Excel,它只是結束目前這個Sub。依照Microsoft Learn的Exit statement說明,Exit Sub會立即離開它所在的Sub程序,程式接著從呼叫這個Sub的敘述後面繼續執行。所以Exit Sub離開的範圍是「這一個Sub」,而不是整個Excel或整個巨集環境。

ChatGPT回答Exit Sub立即結束目前正在執行的Sub,並提供先顯示「第一步:開始執行」再遇到Exit Sub的範例程式 第四節重點卡:第一個MsgBox後執行Exit Sub離開目前Sub,第二個MsgBox不會執行

五、利用成績判斷了解If搭配Exit Sub

第一個範例的Exit Sub是無條件結束,實務上更常見的是有條件地結束。ChatGPT在回答的第二個範例用成績判斷說明:成績低於60分就顯示不及格,然後直接結束程序;成績達到60分,就繼續執行後面的程式。對應的程式如下:

VBA程式|成績判斷()Sub 成績判斷()
    Dim 成績 As Integer
    成績 = 50
    If 成績 < 60 Then
        MsgBox "不及格!"
        Exit Sub
    End If
    MsgBox "恭喜及格!"
End Sub

程式把成績設定為50。進入If判斷後,50小於60,條件成立,先顯示「不及格!」,再執行Exit Sub,所以最後那行「恭喜及格!」不會出現。如果把成績改成60以上,If條件不成立,程式會跳過中間的區塊,直接顯示「恭喜及格!」。這裡同樣是從程式內容推演執行順序,贊贊小屋沒有另外執行成績判斷程式。

If...Then負責判斷「要不要進入這個區塊」,Exit Sub負責「進入區塊之後離開整個Sub」。兩者合在一起,就成了「條件符合時,後面都不用做了」的寫法。這也是Exit Sub在實務上最常見的樣子:先把不該繼續的情況擋在前面,後面的主要程式就不用再層層包在If裡面。

ChatGPT提供的成績判斷範例:成績低於60分時顯示「不及格!」並執行Exit Sub 第五節重點卡:成績低於60分時顯示不及格並Exit Sub,否則顯示恭喜及格並繼續執行

六、比較Exit Sub與End Sub的不同

Exit Sub和End Sub的差別在於:Exit Sub是在執行途中提前離開目前的Sub,End Sub則是標示Sub結束的位置。接下來ChatGPT用一張表整理了幾個容易混淆的指令:Exit Sub是「立即結束目前的 Sub 程序」,End Sub是「標示 Sub 程序的結束位置」,Exit Function則是「立即結束目前的 Function 程序」。回答緊接著強調最重要的觀念:Exit Sub不是暫停,也不是跳過一行,而是直接結束整個目前的Sub。

ChatGPT隨後引用贊贊小屋先前在VBA錯誤處理中討論的匯率程式作為例子,這段程式碼是:

VBA程式片段|If Not ws Is NothingIf Not ws Is Nothing Then
    MsgBox "今天的工作表已經存在!"
    Exit Sub
End If

並解釋:如果今天的工作表已經存在,就顯示提醒,並停止複製程序,避免重複建立工作表。ChatGPT也說,這是Exit Sub在實際VBA工作中最常見的用途之一。

很多初學者第一次看到Exit Sub和End Sub會以為兩者差不多,但它們是兩種不同的角色:End Sub是程序結構的一部分,每個Sub最下面都有,用來標示這個Sub到此為止;Exit Sub則是執行流程中的一個動作,可以出現在Sub中間,同一個Sub裡也能出現多次。Microsoft Learn也特別提醒,不要把Exit和End混為一談,Exit並不是用來標示程式結構結束的位置。Function要提前離開時使用的是Exit Function,不能拿Exit Sub替代。

另外,ChatGPT這幾個程式碼區塊的左上角標示的是「Visual Basic .NET」,而贊贊小屋實際使用的是Excel的VBA編輯器。兩者語法很接近,但不是同一種語言,所以把ChatGPT給的程式貼進Excel之前,還是要以VBA編輯器實際能不能執行為準。

ChatGPT整理Exit Sub、End Sub、Exit Function三個指令的差別,並引用匯率程式中If Not ws Is Nothing的片段 第六節重點卡:比較Exit Sub、End Sub與Exit Function三個指令的不同角色

七、在Excel VBA使用Exit Sub避免重複新增工作表

最後回到Excel。贊贊小屋按Alt+F11開啟「Microsoft Visual Basic for Applications」,視窗標題是「VBA 兩個 Sub - 複製.xlsb - [Module5 (程式碼)]」。左側「專案 - VBAProject」中有三張工作表:「工作表1」「工作表2 (最新匯率)」和「工作表4 (261029)」,下面的「模組」資料夾有Module1到Module5,目前打開的是Module5,右側就是實際使用的程式:

VBA程式|ExitSub範例()Sub ExitSub範例()

    If Worksheets(Worksheets.Count).Name = Format(Date, "yymmdd") Then
        MsgBox "今天的工作表已經存在!"
        Exit Sub
    End If

    Worksheets.Add.Name = Format(Date, "yymmdd")

End Sub

這段程式逐行來看:第一行If Worksheets(Worksheets.Count).Name = Format(Date, "yymmdd") Then,Worksheets.Count是活頁簿裡的工作表數量,把它放進Worksheets()就取得最後一張工作表,再用.Name讀它的名稱;Format(Date, "yymmdd")用的是Format函數,它把電腦的今天日期轉成六位數字,其中yy是年份的後兩位、mm是兩位數的月份、dd是兩位數的日期,例如今天是2026年10月29日,結果就是「261029」。兩邊相同,表示最後一張工作表已經是今天的日期,就顯示「今天的工作表已經存在!」,再用Exit Sub結束。不相同時,程式略過If區塊,執行Worksheets.Add.Name = Format(Date, "yymmdd"),新增一張工作表並命名成今天日期。

這個寫法有一個明確的限制:它只檢查「最後一張」工作表的名稱,並沒有搜尋整本活頁簿。如果今天的工作表存在,但不在最後一張的位置,程式就會誤以為還沒有,而嘗試再新增。想避免這種情況,可以改成逐一檢查每一張工作表的名稱,這是另一種做法,不是贊贊小屋這次實際執行的程式。

這個限制和最後一行的Worksheets.Add有關。依照Worksheets.Add方法的說明,沒有指定Before或After時,新工作表會插在目前作用中的工作表之前,而且新增的工作表會成為作用中工作表。也就是說,新增出來的工作表不一定排在最後一張,「只看最後一張」的判斷能不能成立,取決於新工作表實際落在哪個位置。這次的畫面中,「261029」剛好是最後一個工作表標籤,所以判斷成立;但文章開頭看到的提示訊息只能證明這一次的工作表排列讓判斷成立,不能代表所有情況都正確。

Excel VBA編輯器Module5中的ExitSub範例程式,以最後一張工作表名稱與今天日期比較後決定是否新增工作表 第七節重點卡:兩種工作表排列的概念示意,說明只檢查最後一張工作表不等於搜尋全部工作表

Exit Sub讓VBA程式在適當時機結束

這次從匯率工作表出現的提示訊息開始,贊贊小屋請ChatGPT把Exit Sub拆成經典範例、成績判斷與Sub、End Sub的比較,最後再回到自己的程式逐行看一遍。Exit Sub雖然只有一行程式碼,卻能讓VBA依照實際條件決定要不要繼續往下執行。

看懂語法只是第一步,更重要的是看懂整段程式的判斷範圍:條件是什麼、檢查了哪些地方、沒有檢查哪些地方。像這次只檢查最後一張工作表,雖然足夠處理贊贊小屋目前的使用方式,也提醒我們,在Excel裡真正用到工作時,還是要把條件寫得和實際情況一致。

總結卡:了解語法、設定條件、確認判斷範圍,學會Exit Sub還要確認判斷條件涵蓋真正需要處理的情況
發布日期:
分類:AI工具、ChatGPT VBA