View
257
Download
1
Category
Preview:
Citation preview
程式的執行與偵錯
6-1 巨集的安全性設定
6-2 指定執行巨集的位置或物件
6-3 程式 (巨集 )除錯技巧
6-4 進行偵錯工作
6-5 其他偵錯視窗
6
跟我學 Excel VBA應用6-2
Excel舊版中的 高、中、低安全性層級,在 Excel 2007~2010中已經被 Office
信任中心 的 巨集設定 所取代,使用者可視需要調整其安全性設定,其安全性等級說
明如下:
停用所有巨集 (不事先通知 ):如果不信任巨集,請點選這個選項,停用所有巨集及有關巨集的安全性提醒。文件中的所有巨集以及有關巨集的安全性提
醒都會停用。如果文件中包含未簽章的巨集,但確實信任這些巨集,則可將
這些文件放入信任位置,處於信任位置的文件不需要經過 信任中心 安全性系統的檢查,即可直接執行。
逐步學會 Excel VBA之後,所撰寫的巨集可能愈來愈複雜,如何在設計巨集的
過程中,迅速解決所碰到的錯誤或問題,是一項重要的課題。另外,已完成的巨集應
該如何讓使用者輕鬆使用,也是必須知道的事情,本章將分別加以說明。
6-1 巨集的安全性設定如果當在某一部電腦中,發現無法執行 Excel檔案內的巨集,可能是此電腦針對
巨集已將安全性設定為高等級。因此,必須先執行 開發人員 >程式碼 >巨集安全性
指令,變更此項設定,然後重新啟動 Excel,就能順利執行檔案中的巨集。
Chapter 6 程式的執行與偵錯 6-3
停用所有巨集 (事先通知 ):如果要停用巨集,但是希望在巨集出現時收到安全性提醒,請點選這個選項,如此就可以個別選擇啟用巨集的時機,這是預
設值。
除了經數位簽章的巨集外,停用所有巨集:這個設定與 停用所有巨集 (事先通知 ) 選項相同,差別在於:如果巨集是由受信任的發行者進行數位簽章,就可以在信任這個發行者的情況下執行該巨集。如果尚未信任這個發行者,則
會收到通知,這樣就可以選擇啟用經簽章的巨集或信任這個發行者,而所有
未經簽章的巨集都會停用,停用時不會發出通知。
啟用所有巨集 (不建議使用,會執行有潛在危險的程式碼 ):點選這個選項會允許執行所有巨集。這個設定會讓電腦容易受到可能的惡意程式碼攻擊,因
此不建議使用。
信任存取 VBA專案物件模型:僅限開發人員使用。
基於目前網際網路的快速發展,病毒也大行其道,所以各種防護措施也愈來愈
緊。巨集的應用也被有心人士加以變造,成為病毒來源,所以巨集可能包含病毒,請
謹慎執行。另外,還可以採取下列防範措施:
在電腦上執行最新的防毒軟體。
將您的巨集安全性層級設定提高。
在 信任中心 對話方塊中,選擇 受信任的發行者 標籤,查閱 發行者 欄位是否有未知或不安全的名稱。
跟我學 Excel VBA應用6-4
使用數位簽章。
新增或刪除 信任位置。
確認信任的文件。
Chapter 6 程式的執行與偵錯 6-5
決定是否停用 增益集。
進一步設定 ActiveX 的使用限制。
設定不得閱覽程式密碼
針對自己所撰寫的 Excel VBA巨集,如果不希望讓使用者任意修改其內容,或
檢視程式碼,可以使用密碼鎖住專案,這樣就不能做檢視或編輯。
跟我學 Excel VBA應用6-6
1 開啟活頁簿之後,切換至 VB編輯視窗;點選 工具 > VBA Project屬性 指令。
設定專案密碼
2 出現 VBAProject-專案屬性 對話方塊,選擇 保護 標籤,勾選 鎖定專案以供
檢視 核取方塊。
3 分別在 密碼 與 確認密碼 欄位中,輸入相同的密碼,按【確定】鈕完成設定。
1
2
3
4
5
Chapter 6 程式的執行與偵錯 6-7
6-2 指定執行巨集的位置或物件在前一小節的練習中,每次要執行巨集時,都要經過好幾個動作,相當繁瑣!事
實上已將巨集指定在特別的物件上,例如:工具鈕、快取圖案 或 圖表⋯等。
6-2-1 將巨集指定到工具鈕針對常用的巨集,可以將其指定到 快速存取工具列 中的工具鈕,如此即可快速
執行此巨集。這一節要透過以「好好玩」巨集,說明其操作步驟。
將巨集指定到工具鈕
1 開啟這一章的範例檔案 ch06_VBA.xlsm,點選 快速存取工具列 旁邊的下拉式清
單鈕,再點選 其他命令 指令。
跟我學 Excel VBA應用6-8
2 出現 Excel選項 對話方塊,選擇 快速存取工具列 標籤,在 由此選擇命令 清單
中選擇 巨集 項目。
3 在對應的巨集清單中,選擇所要的巨集名稱,例如:「好好玩」。
4 按【新增】鈕,將此巨集名稱加到右側的清單中。
5 按【修改】鈕,出現 修改按鈕 對話方塊,在 符號 清單中選擇喜愛的按鈕圖示,
按【確定】鈕,完成指定巨集工具鈕指令的工作。
1
2
3
4
5
1
2
Chapter 6 程式的執行與偵錯 6-9
現在,如果要執行「好好玩」巨集,只要使用滑鼠點選 快速存取工具列 上,剛
剛設定的工具鈕,即會立即執行該工具鈕所指定的巨集。
6-2-2 將巨集指定至工作表中的物件工作表中的物件有許多類型,包含了 快取圖案、圖表、美工圖案、自訂按鈕 ⋯
等。如果要將巨集指定到這些物件,其作法與 6-2-1節大同小異,請參考下面說明。
將巨集指定到圖案上
1 選取要指定巨集的物件,將滑鼠指到此物件上。
2 按一下滑鼠右鍵,點選 指定巨集 指令。
跟我學 Excel VBA應用6-10
3 出現 指定巨集 對話方塊,選擇要設定的 巨集名稱,例如:「好好玩」,按【確定】
鈕,完成工作。
4 若要執行「好好玩」巨集,請使用滑鼠點選剛剛設定的圖形物件 (出現小手 ),即
會執行指定的巨集。
1
2
Chapter 6 程式的執行與偵錯 6-11
6-3 程式 (巨集 )除錯技巧撰寫程式並不難,但要寫出令人激賞的程式則要有天份,所以凡人只要求其平順
易用即可。因此,在撰寫程式之前,必須先想好流程控制,另外盡可能使用簡潔的畫
面,避免冗長的陳述式。還有,不要以為天下所有人都像您這麼聰明,拿到程式一看
就懂、上手就跑,所以程式一定要做好防呆措施。
程式設計者在剛完成一個程式雛型,或是進度告一段落時,都會迫不及待地想趕
快測試一下!若能正常運作的確令人高興,如果出現錯誤也不必懷疑個人的能力,所
謂好的程式設計師,只是較具經驗而能夠盡量避免錯誤的發生罷了!想要程式從不出
錯,是跟登天一樣的難,只要能找到錯誤加以修正,就非常棒了!
6-3-1 程式錯誤的類型設計一個應用程式時,需要考量當程式發生錯誤時,應該採取什麼措施來處理,
以便程式仍可持續運作,不會掛在那裡!大致上可以將執行 VBA程式時,經常會碰
到的錯誤分為二大類:一為 編譯錯誤,另一為 執行期間錯誤。
編譯錯誤
編譯錯誤 指的是程式在撰寫時所發生的錯誤,在 Excel VBA程式編輯視窗中撰
寫程式時,只要按 鍵跳到下一行,VBA會自動進行語法的檢查,一旦發現程式
有錯誤的語法,會自動以紅色字標示,並顯示語法錯誤的訊息對話方塊。
處理語法錯誤這類問題並不困難,設計者只要按照提示,將輸入錯誤的部份更正
即可。若是對於哪裡出錯不是很清楚,也可以按下鍵盤上的 鍵,搜尋 VBA所提
供的線上說明,找到所要的解答。
執行期間錯誤
執行期間錯誤 又分成二種:一種是 VBA執行到中途出現錯誤訊息,程式無法再
繼續執行;另外一種比較麻煩的情況是程式仍然可以執行,但是卻出現非預期的結
果。如何找出 執行期間錯誤,也是程式設計時的重點,常見 執行期間錯誤 有以下
幾種:
跟我學 Excel VBA應用6-12
運算錯誤:不同的資料型態執行不適合的運算,導致錯誤產生,例如:誤將字串資料執行運算。
溢位錯誤:資料處理時超出各種資料型態的限制,特別是超出數值資料的範圍而產生溢位。在以下的例子中,可以看到宣告為整數型態的變數,由於指
定給它的數值超過整數範圍 (-32,768 ~ 32,767),執行時將會產生溢位的錯誤訊息。
屬性值錯誤:在程式中設定物件屬性值時,使用了錯誤屬性,程式執行時即會出現錯誤訊息。例如:將 Range物件的 Value屬性誤輸入為 Vare,撰寫 VBA 時沒有偵測出此錯誤,進入執行模式時,VBA 顯示錯誤訊息對話方塊,通知您使用了沒有定義的屬性。
Chapter 6 程式的執行與偵錯 6-13
I/O錯誤:在程式中存取周邊的檔案或資料時,該檔案或資料已經不存在,造成 I/O錯誤。
邏輯錯誤:可能是流程控制撰寫錯誤,或是函數與副程式參數傳遞錯誤,造成程式產生無法預期的結果,或是產生無窮迴圈而當機。
針對這些比較棘手的問題,VBA提供一些偵錯工具以協助程式設計者找出這些
程式的錯誤,請參考以下幾個小節的說明。
6-3-2 事先防範 --Is函數任何計劃在執行之前,都要防患於未然。同樣地,在設計程式時,事先防範也是
最高指導原則,於程式產生錯誤之前,搶先一步對可能的錯誤因素先行排除。Is函
數家族的運用可以幫您這個大忙,其重要成員包含下列幾項:
跟我學 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
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陳述式,任何執行錯誤都會顯示錯誤訊息,並且中
止執行程式。
跟我學 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,
所以在執行程式時,如已經有一頁同名稱
的工作表,則會產生錯誤發生,並會出現
如右圖所示的錯誤訊息。
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能夠幫您偵測錯誤,並在回應之前,依照程式設計師的方式處理,這也就是所
謂的「捕捉錯誤」。
跟我學 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,來捕捉錯誤,並提供錯誤訊息
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
Recommended