19
程式的執行與偵錯 6-1 巨集的安全性設定 6-2 指定執行巨集的位置或物件 6-3 程式 ( 巨集 ) 除錯技巧 6-4 進行偵錯工作 6-5 其他偵錯視窗 6

程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Embed Size (px)

Citation preview

Page 1: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

程式的執行與偵錯

6-1 巨集的安全性設定

6-2 指定執行巨集的位置或物件

6-3 程式 (巨集 )除錯技巧

6-4 進行偵錯工作

6-5 其他偵錯視窗

6

Page 2: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

跟我學 Excel VBA應用6-2

Excel舊版中的 高、中、低安全性層級,在 Excel 2007~2010中已經被 Office

信任中心 的 巨集設定 所取代,使用者可視需要調整其安全性設定,其安全性等級說

明如下:

停用所有巨集 (不事先通知 ):如果不信任巨集,請點選這個選項,停用所有巨集及有關巨集的安全性提醒。文件中的所有巨集以及有關巨集的安全性提

醒都會停用。如果文件中包含未簽章的巨集,但確實信任這些巨集,則可將

這些文件放入信任位置,處於信任位置的文件不需要經過 信任中心 安全性系統的檢查,即可直接執行。

逐步學會 Excel VBA之後,所撰寫的巨集可能愈來愈複雜,如何在設計巨集的

過程中,迅速解決所碰到的錯誤或問題,是一項重要的課題。另外,已完成的巨集應

該如何讓使用者輕鬆使用,也是必須知道的事情,本章將分別加以說明。

6-1 巨集的安全性設定如果當在某一部電腦中,發現無法執行 Excel檔案內的巨集,可能是此電腦針對

巨集已將安全性設定為高等級。因此,必須先執行 開發人員 >程式碼 >巨集安全性

指令,變更此項設定,然後重新啟動 Excel,就能順利執行檔案中的巨集。

Page 3: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Chapter 6 程式的執行與偵錯 6-3

停用所有巨集 (事先通知 ):如果要停用巨集,但是希望在巨集出現時收到安全性提醒,請點選這個選項,如此就可以個別選擇啟用巨集的時機,這是預

設值。

除了經數位簽章的巨集外,停用所有巨集:這個設定與 停用所有巨集 (事先通知 ) 選項相同,差別在於:如果巨集是由受信任的發行者進行數位簽章,就可以在信任這個發行者的情況下執行該巨集。如果尚未信任這個發行者,則

會收到通知,這樣就可以選擇啟用經簽章的巨集或信任這個發行者,而所有

未經簽章的巨集都會停用,停用時不會發出通知。

啟用所有巨集 (不建議使用,會執行有潛在危險的程式碼 ):點選這個選項會允許執行所有巨集。這個設定會讓電腦容易受到可能的惡意程式碼攻擊,因

此不建議使用。

信任存取 VBA專案物件模型:僅限開發人員使用。

基於目前網際網路的快速發展,病毒也大行其道,所以各種防護措施也愈來愈

緊。巨集的應用也被有心人士加以變造,成為病毒來源,所以巨集可能包含病毒,請

謹慎執行。另外,還可以採取下列防範措施:

在電腦上執行最新的防毒軟體。

將您的巨集安全性層級設定提高。

在 信任中心 對話方塊中,選擇 受信任的發行者 標籤,查閱 發行者 欄位是否有未知或不安全的名稱。

Page 4: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

跟我學 Excel VBA應用6-4

使用數位簽章。

新增或刪除 信任位置。

確認信任的文件。

Page 5: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Chapter 6 程式的執行與偵錯 6-5

決定是否停用 增益集。

進一步設定 ActiveX 的使用限制。

設定不得閱覽程式密碼

針對自己所撰寫的 Excel VBA巨集,如果不希望讓使用者任意修改其內容,或

檢視程式碼,可以使用密碼鎖住專案,這樣就不能做檢視或編輯。

Page 6: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

跟我學 Excel VBA應用6-6

1 開啟活頁簿之後,切換至 VB編輯視窗;點選 工具 > VBA Project屬性 指令。

設定專案密碼

2 出現 VBAProject-專案屬性 對話方塊,選擇 保護 標籤,勾選 鎖定專案以供

檢視 核取方塊。

3 分別在 密碼 與 確認密碼 欄位中,輸入相同的密碼,按【確定】鈕完成設定。

1

2

3

4

5

Page 7: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Chapter 6 程式的執行與偵錯 6-7

6-2 指定執行巨集的位置或物件在前一小節的練習中,每次要執行巨集時,都要經過好幾個動作,相當繁瑣!事

實上已將巨集指定在特別的物件上,例如:工具鈕、快取圖案 或 圖表⋯等。

6-2-1 將巨集指定到工具鈕針對常用的巨集,可以將其指定到 快速存取工具列 中的工具鈕,如此即可快速

執行此巨集。這一節要透過以「好好玩」巨集,說明其操作步驟。

將巨集指定到工具鈕

1 開啟這一章的範例檔案 ch06_VBA.xlsm,點選 快速存取工具列 旁邊的下拉式清

單鈕,再點選 其他命令 指令。

Page 8: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

跟我學 Excel VBA應用6-8

2 出現 Excel選項 對話方塊,選擇 快速存取工具列 標籤,在 由此選擇命令 清單

中選擇 巨集 項目。

3 在對應的巨集清單中,選擇所要的巨集名稱,例如:「好好玩」。

4 按【新增】鈕,將此巨集名稱加到右側的清單中。

5 按【修改】鈕,出現 修改按鈕 對話方塊,在 符號 清單中選擇喜愛的按鈕圖示,

按【確定】鈕,完成指定巨集工具鈕指令的工作。

1

2

3

4

5

1

2

Page 9: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Chapter 6 程式的執行與偵錯 6-9

現在,如果要執行「好好玩」巨集,只要使用滑鼠點選 快速存取工具列 上,剛

剛設定的工具鈕,即會立即執行該工具鈕所指定的巨集。

6-2-2 將巨集指定至工作表中的物件工作表中的物件有許多類型,包含了 快取圖案、圖表、美工圖案、自訂按鈕 ⋯

等。如果要將巨集指定到這些物件,其作法與 6-2-1節大同小異,請參考下面說明。

將巨集指定到圖案上

1 選取要指定巨集的物件,將滑鼠指到此物件上。

2 按一下滑鼠右鍵,點選 指定巨集 指令。

Page 10: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

跟我學 Excel VBA應用6-10

3 出現 指定巨集 對話方塊,選擇要設定的 巨集名稱,例如:「好好玩」,按【確定】

鈕,完成工作。

4 若要執行「好好玩」巨集,請使用滑鼠點選剛剛設定的圖形物件 (出現小手 ),即

會執行指定的巨集。

1

2

Page 11: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Chapter 6 程式的執行與偵錯 6-11

6-3 程式 (巨集 )除錯技巧撰寫程式並不難,但要寫出令人激賞的程式則要有天份,所以凡人只要求其平順

易用即可。因此,在撰寫程式之前,必須先想好流程控制,另外盡可能使用簡潔的畫

面,避免冗長的陳述式。還有,不要以為天下所有人都像您這麼聰明,拿到程式一看

就懂、上手就跑,所以程式一定要做好防呆措施。

程式設計者在剛完成一個程式雛型,或是進度告一段落時,都會迫不及待地想趕

快測試一下!若能正常運作的確令人高興,如果出現錯誤也不必懷疑個人的能力,所

謂好的程式設計師,只是較具經驗而能夠盡量避免錯誤的發生罷了!想要程式從不出

錯,是跟登天一樣的難,只要能找到錯誤加以修正,就非常棒了!

6-3-1 程式錯誤的類型設計一個應用程式時,需要考量當程式發生錯誤時,應該採取什麼措施來處理,

以便程式仍可持續運作,不會掛在那裡!大致上可以將執行 VBA程式時,經常會碰

到的錯誤分為二大類:一為 編譯錯誤,另一為 執行期間錯誤。

編譯錯誤

編譯錯誤 指的是程式在撰寫時所發生的錯誤,在 Excel VBA程式編輯視窗中撰

寫程式時,只要按 鍵跳到下一行,VBA會自動進行語法的檢查,一旦發現程式

有錯誤的語法,會自動以紅色字標示,並顯示語法錯誤的訊息對話方塊。

處理語法錯誤這類問題並不困難,設計者只要按照提示,將輸入錯誤的部份更正

即可。若是對於哪裡出錯不是很清楚,也可以按下鍵盤上的 鍵,搜尋 VBA所提

供的線上說明,找到所要的解答。

執行期間錯誤

執行期間錯誤 又分成二種:一種是 VBA執行到中途出現錯誤訊息,程式無法再

繼續執行;另外一種比較麻煩的情況是程式仍然可以執行,但是卻出現非預期的結

果。如何找出 執行期間錯誤,也是程式設計時的重點,常見 執行期間錯誤 有以下

幾種:

Page 12: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

跟我學 Excel VBA應用6-12

運算錯誤:不同的資料型態執行不適合的運算,導致錯誤產生,例如:誤將字串資料執行運算。

溢位錯誤:資料處理時超出各種資料型態的限制,特別是超出數值資料的範圍而產生溢位。在以下的例子中,可以看到宣告為整數型態的變數,由於指

定給它的數值超過整數範圍 (-32,768 ~ 32,767),執行時將會產生溢位的錯誤訊息。

屬性值錯誤:在程式中設定物件屬性值時,使用了錯誤屬性,程式執行時即會出現錯誤訊息。例如:將 Range物件的 Value屬性誤輸入為 Vare,撰寫 VBA 時沒有偵測出此錯誤,進入執行模式時,VBA 顯示錯誤訊息對話方塊,通知您使用了沒有定義的屬性。

Page 13: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Chapter 6 程式的執行與偵錯 6-13

I/O錯誤:在程式中存取周邊的檔案或資料時,該檔案或資料已經不存在,造成 I/O錯誤。

邏輯錯誤:可能是流程控制撰寫錯誤,或是函數與副程式參數傳遞錯誤,造成程式產生無法預期的結果,或是產生無窮迴圈而當機。

針對這些比較棘手的問題,VBA提供一些偵錯工具以協助程式設計者找出這些

程式的錯誤,請參考以下幾個小節的說明。

6-3-2 事先防範 --Is函數任何計劃在執行之前,都要防患於未然。同樣地,在設計程式時,事先防範也是

最高指導原則,於程式產生錯誤之前,搶先一步對可能的錯誤因素先行排除。Is函

數家族的運用可以幫您這個大忙,其重要成員包含下列幾項:

Page 14: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

跟我學 Excel VBA應用6-14

IsDate:用來判斷運算式可否轉換為日期資料。如果運算式是一個有效日期,IsDate傳回 True。Microsoft Windows的有效日期範圍是,100年 1月 1日至 9999年 12月 31日。

IsDate的函數範例

   Sub IS_DATE_函數 ( )

   Dim MyDate, YourDate, NoDate

   MyDate = "October 19, 1997"

   MyCheck = IsDate(MyDate) ' 傳回 True。

   If MyCheck = True Then Range("A1").Value = MyDate

   YourDate = #8/6/97#

   MyCheck = IsDate(YourDate) ' 傳回 True。

   If MyCheck = True Then Range("A2").Value = YourDate

   NoDate = "Hello"

   MyCheck = IsDate(NoDate) ' 傳回 False。

   If MyCheck = True Then Range("A3").Value = NoDate

   Range("A1:A3").Select

   Selection.NumberFormatLocal ="yy""年 ""m""月 ""d""日 """

   End Sub

IsNumeric:用來判斷運算式的結果是否為數字。

IsEmpty:用來判斷變數是否已經初始化。

IsMissing:用來判斷引數是否傳遞。

IsMissing的函數範例

  Sub IS_MISSING_函數 ( )

  Dim ReValue

   ' 下列陳述式呼叫使用者自訂函數。

   ReValue = ReFun() ' 不給引數。

   If ReValue = NoArgu Then Range("A1").Value = "空白 "

   ReValue = ReFun(3) ' 給予引數 3

   Range("A2").Value = ReValue

  End Sub

Page 15: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Chapter 6 程式的執行與偵錯 6-15

  Function ReFun(Optional x)

   If IsMissing(x) Then

   ReFun = NoArgu '如果引數沒有傳入 ,則傳回 NoArgu

   Else

   ReFun = x * 2 '如果有引數傳入 ,傳回其兩倍的值

   End If

  End Function

IsNull:用來判斷變運算式是否未含任何資料。

IsArray:用來判斷變數是否為一個陣列。

IsError:用來判斷運算是否為一個錯誤值。

IsObject:用來判斷運算是否為一個物件。

6-3-3 On Error陳述式 --捕捉錯誤透過 Is函數家族的處理,較容易判斷程式的執行狀況,是否已偏離常軌。但卻

不容易即刻進行某些修正處理。因此,配合 On Error陳述式的使用,會如虎添翼有

效地處理錯誤。

語法:On Error Goto 標記 (行號 )

   On Error Goto 0

   On Error Resume Next

On Error陳述式,可以用來啟動一個錯誤處理「程序區塊」,此程序區塊即在原

程序中的某一位置。當然它也可以停止執行此錯誤處理程序。

On Error GoTo標記 (行號 ):是指當錯誤發生時,去執行位於標記 (行號 )的處理程序。

On Error GoTo 0:是停止目前現行程序內,任何已啟動的錯誤處理程序。

On Error GoTo Resume Next:則是於錯誤發生時,立刻繼續執行發生錯誤的下一行陳述式。

提示

如果沒有適當的使用 On Error陳述式,任何執行錯誤都會顯示錯誤訊息,並且中

止執行程式。

Page 16: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

跟我學 Excel VBA應用6-16

Err 物件

進入實例說明之前,先認識一下 Err物件。當 VBA程式出現錯誤時,一般都會

伴隨出現一個 Err物件,並會附賦予一個錯誤號碼。如果沒有任何錯誤,則其錯誤編

碼為 0,Err物件的表示法如下:

語法:Err.方法

   Err.屬性

為了避免中斷程式,可以加上 On Error Resume Net,讓程式忽略此錯誤,繼

續到下一行執行。因此以 Err.Number陳述式來判斷是否為零,以便繼續進行工作;

如果 Err.Number不為零,則表示有同名稱的工作表,程式予以增加序號,重複執行

Err.Number的判斷。

Sub On_Error_用法 1( )

   Dim StBase As String, myInc As Integer

   Dim mySheet As Worksheet

   Set mySheet = Worksheets.Add

   StBase = "測試 "

   myInc = 1

   mySheet.Name = StBase & myInc

End Sub

Excel工作表中,新增一頁工作表,並且將其命名為「測試 2」⋯依序增加其編號

提示

Err物件與 Error陳述式雖性質不同,但同時使用會造成無法預期的結果。

整個範例重點在於工作表名稱的命

名,由於每執行 1次,便要求自動加 1,

所以在執行程式時,如已經有一頁同名稱

的工作表,則會產生錯誤發生,並會出現

如右圖所示的錯誤訊息。

Page 17: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Chapter 6 程式的執行與偵錯 6-17

忽略錯誤的程式碼範例

  Sub On_Error_用法 1( )

   Dim StBase As String, myInc As Integer

   Dim mySheet As Worksheet

  

   Set mySheet = Worksheets.Add

   StBase = "測試 "

   myInc = 1

   On Error Resume Next

   mySheet.Name = StBase & myInc

   Do Until Err.Number = 0

   Err.Clear

   myInc = myInc + 1

   mySheet.Name = StBase & myInc

   Loop

  End Sub

提示

在 Do Until程式區塊中,Err.Clear目的是將 Err. Number設為 0。

這個範例還要注意二件事情:首先,就是 On Error陳述式的位置,它必須放在

會產生錯誤發生之前的地方;其次,是當 On Error錯誤處理被啟動後就會持續作用,

直到離開整個程序 (End Sub),如要終止 On Error處理,請使用 On Error GoTo 0

陳述式予以關閉。

捕捉錯誤

如果只是為自己寫一個程式,當錯誤發生時讓 VBA出現錯誤訊息倒是蠻好的,

這樣可以了解錯誤發生的原因與所在位置。但如果是為別人設計程式,樣子就不太好

看!因為他們可能無法判斷是什麼問題,而接下去也可能不知道該如何處理,還好!

VBA能夠幫您偵測錯誤,並在回應之前,依照程式設計師的方式處理,這也就是所

謂的「捕捉錯誤」。

Page 18: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

跟我學 Excel VBA應用6-18

設定自己的 Error Number

從前面的範例中,可以得到一項訊息:當 Excel VBA於執行過程中,每次遇到

錯誤即會出現一個錯誤訊息對話方塊,並標示 Error Number。那麼可不可以在設計

程式時,也利用此項功能,設定自己的 Error Number呢?當然沒問題,但是在設定

號碼時,應該避免使用內建的號碼 (內建的 Error Number請參考附錄 A),1~1000

未使用的錯誤代碼都是保留給 Visual Basic 以後使用的。在這裡建議您使用 50,000

至 65,353之間的號碼,其他數字就留給原應用程式使用,以免混淆!設定自己的

Error Number時,建議配合 On Error陳述式一起使用,將欲設定的 Error Number

放在程式中,當產生錯誤時,仍會進入錯誤處理區塊執行相關工作。

Sub On_Error_用法 2( )

   On Error GoTo 錯誤報告

   aa = 12 / 0

   On Error GoTo 0

   mySheet.Name = StBase & myInc

   Range("A1").Value = "OK!"

   Exit Sub

   錯誤報告 :

   MsgBox "煩請通知江高舉先生 ,此錯誤代碼 : " & _

   "Error Number= " & Err.Number & _

   vbCrLf & vbCrLf & vbCrLf & Err.Description

   Resume Next

   End Sub

如果在程序中含有錯誤處理「程序區塊」,則執行此處誤處理之後,可依您的要

求,返回原錯誤陳述式,或回到原錯誤的下一行繼續執行程式。另外別忘了,在進入

錯誤處理的「程序區塊」前,加入 Exit Sub陳述式,以避免在無錯誤狀態亦進入錯

誤處理區塊。

使用 On Error GoTo,來捕捉錯誤,並提供錯誤訊息

Page 19: 程式的執行與偵錯 6epaper.gotop.com.tw/pdf/ACI018900.pdf · 6-2 跟我學Excel VBA 應用 Excel 舊版中的 高、中、低安全性層級,在Excel 2007~2010中已經被Office

Chapter 6 程式的執行與偵錯 6-19

自訂 Error Number

Sub Error_ Code ( )

   On Error GoTo 錯誤報告

   n = 1

   For i = 1 To 10000

   n = n + 1

   If n > 10 Then

   Error 50000

   End If

   Next i

   Exit Sub

   錯誤報告 :

   i = 10000

   errmsg = " For_Loop 運算次數太多了 "

   MsgBox "煩請通知江高舉先生 ,此錯誤代碼 : " & _

   vbCrLf & vbCrLf & " Error Number= " & _

   Err.Number & vbCrLf & vbCrLf & errmsg

   Resume Next

   End Sub