2012-12-24

由簡化繁的程式設計

寫程式的時候,通常一行就可以完成某個執行程序,這樣類型的程式,自己用當然OK,不過若你把程式拿給第三方使用,他保證跟你說 "爛"....


為何他會說爛?因為他不會照著你心裡想的操作步驟做,當然也就發生所謂不預期的錯誤而讓程式當在那裡。這也就我常說的"防笨機制"。

就拿樓梯級高的計算做比方好了,高度(H)填160,階數(N)填10,當然算出來的級高(Sh)=16,不過使用者操作時,在含有眾多文字框的表單中,我們並不能保證使用者在階數(N)會填入大於零的整數,或是填上字母或帶小數點的階數(有這樣的樓梯??),當程式執行到
Sh=H/N 這行,當然就"噹!"一聲,彈出使用者不太瞭解的程式錯誤訊息,當然被冠上爛程式也就不為過。

所以我們會在該計算前,先宣告變數來鎖定變數特性
DIM N as Integer
然後又用
If N<=0 then
    N值小於零的錯誤處理及警告
end if
拉拉雜雜的一堆檢核,才會來到程式的主軸: Sh=H/N

這樣還不夠,有一些錯誤是系統相容度或當案權限(註:尤其win7以後,檔案的讀寫有權限的要求)的問題,所以每個可能發生錯誤的程序(Procedure),我們還要有
 On Error Resume Next
或者
On Error Goto XXXX
的作法,來攔截非預期的錯誤。

這個問題在AutoCAD中的VBA中似乎更多。

以選點(GetPoint)這個方法來說好了,當使用者轉入Autocad要選取某點的資料,當然你對著要選取的點按左鍵,可以順利獲取點位資訊,但是若使用者這時候按下滑鼠右鍵,或是鍵盤的Esc鍵做取消,這時候程式就當了,當然這之前的所有操作內容都將會消失,你需要重頭再來一遍。

進入AutoCAD操作中,確實有兩個情況,1. 使用者真的要取消這個動作,2.資料真的錯誤。
這兩個部份在GetPoint作業中都需要考慮到。
其中第一種,就需要利用winAPI程式來做攔截,比如
Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
 利用攔截的數據來判斷使用者的意圖。
至於第二種,就只是簡單的數據判斷罷了。

第二個問題是是否重複定義的問題,以Group為例好嚕,
若我們一般想建立名為"000"的Group物件,你的作法會是:

Dim acadGp as AcadGroup
Set acadGp = ThisDrawing.Groups.Add("000")
不過,若第二次建立Group,使用者又以000做名稱,這時候就會又是錯誤當機。
我們還需要在程式之前,利用
For Each acadGp in thisDwawing.Groups
    檢核acadGp.Name是否已存在.....及處理方式
Next

一個好的程式,不是不容許有錯誤訊息,而是如何讓錯誤訊息不致造成程式死當而須重新操作,或許你會覺得抓蟲的時間比程式主體,花得更多更多的時間。





2 則留言:

  1. Mark您好
    好久沒看到新的文章,感謝分享

    回覆刪除
  2. 抓蟲跟測試的時間通常都比撰寫主功能還要花更多時間XD

    回覆刪除