AutoCAD
AutoLISP 跑不動?常見的 7 個原因與檢查方式
從網路下載或自己寫的 LISP,載入後沒反應、畫出來的位置不對,或命令列跳出看不懂的 error 訊息? 以下依錯誤現象整理 7 個最常見的原因,每一項都附上檢查方式。
本文目錄(8 節)
1. 載入時被擋下:信任的位置
AutoCAD 2014 起加入 SECURELOAD 系統變數,用來限制從哪些資料夾載入程式。 LISP 檔不在「信任的位置」時,AutoCAD 會跳出安全性警告;若 SECURELOAD 設為 2,則會直接不載入。
檢查方式
- 在命令列輸入
SECURELOAD,看目前的值(0 不限制、1 警告、2 只載入信任位置) - 到「選項 → 檔案 → 信任的位置」,把放 LISP 的資料夾加進去
- 公司電腦若由 IT 統一設定,請確認是否被群組原則鎖定
建議把公司共用的 LISP 集中放在一個資料夾,統一加入信任的位置,不要散落在各人桌面。
2. 畫出來的位置不對:物件鎖點干擾
程式用 command 呼叫指令並傳入座標時,如果物件鎖點(OSNAP)是開著的, 點位會被「吸」到附近的端點或中點,畫出來的圖就偏掉了。這種錯誤不會有任何錯誤訊息,最難察覺。
改法
執行前先記下 OSMODE,暫時關閉,結束時再還原:
(defun c:DrawBox (/ oldOsmode)
(setq oldOsmode (getvar "OSMODE"))
(setvar "OSMODE" 0)
(command "_.RECTANG" '(0 0) '(100 50))
(setvar "OSMODE" oldOsmode)
(princ)
)要注意:程式中途出錯時,後面的還原不會被執行,完整的做法還需要搭配錯誤處理函式(*error*)把設定還原。
3. 指令選項沒反應:語系版本差異
在非英文版的 AutoCAD 中,指令的選項關鍵字可能是當地語言。程式裡直接寫英文選項, 換到不同語系的版本就可能無法辨識。
在指令與選項前加上底線 _,可以強制使用英文的原始名稱; 再加上句點 .,則會使用 AutoCAD 內建的指令,避免指令被重新定義過:
(command "_.ZOOM" "_Extents")4. bad argument type:選取集是 nil
最常見的錯誤訊息之一:
; error: bad argument type: lselsetp nil
意思是某個函式預期拿到選取集,實際上拿到的是 nil。 通常是 ssget 沒有選到任何物件(使用者直接按 Enter,或篩選條件寫錯), 後面卻直接拿去用 sslength、ssname。
改法
(if (setq ss (ssget '((0 . "INSERT"))))
(progn
;; 有選到圖塊才處理
(princ (strcat "\n選到 " (itoa (sslength ss)) " 個圖塊"))
)
(princ "\n沒有選到圖塊。")
)同樣的道理適用於 entsel、getpoint 等所有可能回傳 nil 的函式。
5. no function definition:函式沒有載入
; error: no function definition: VLAX-ENAME->VLA-OBJECT
表示程式呼叫了一個目前沒有被定義的函式,常見原因有三種:
- 缺少
(vl-load-com):使用vla-、vlax-開頭的函式前,習慣上要先執行這一行 - 函式在另一個檔案:程式呼叫了共用函式庫裡的函式,但那個 LISP 檔沒有一起載入
- 拼錯字或版本不支援:例如在 AutoCAD LT 使用了不支援的 ActiveX 函式(詳見AutoCAD LT 能用 LISP 嗎?)
6. 時好時壞:變數沒有區域化
defun 的參數列中,斜線 / 後面列出的是區域變數。 沒有列進去的變數都是全域變數,會被其他 LISP 程式讀到或覆蓋,造成「單獨執行正常、跟其他程式一起用就出錯」。
;; 不建議:ss、i 都是全域變數
(defun c:CountBlk () ...)
;; 建議:把用到的變數列在 / 後面
(defun c:CountBlk (/ ss i) ...)7. 中文變亂碼:檔案編碼
提示文字或圖層名稱裡的中文變成亂碼,通常是 LSP 檔的存檔編碼與 AutoCAD 讀取的方式不一致。 舊版 AutoCAD 以系統的 ANSI 編碼(繁體中文環境為 Big5)讀取;較新的版本支援 Unicode, 實際行為與版本及 LISPSYS 設定有關。
檢查方式
- 用文字編輯器確認檔案目前是 UTF-8 還是 Big5(ANSI)
- 確認使用者的 AutoCAD 版本,同一份檔案要給不同版本使用時,先在最舊的版本上測試
怎麼找到錯在哪一行
- 在關鍵位置印出變數:用
(princ var)確認每一步拿到的值是否符合預期,最簡單也最有效 - 使用除錯工具逐步執行:舊版可用 Visual LISP 編輯器(
VLIDE);AutoCAD 2021 起可搭配 Visual Studio Code 的 AutoCAD AutoLISP 擴充功能設定中斷點 - 縮小範圍:把程式拆成小段分別測試,先確認選取、再確認計算、最後才執行修改圖面的部分
常見問題
Q:LISP 載入後輸入指令沒有反應,要先檢查什麼?
先看命令列有沒有錯誤訊息,再確認檔案是否真的載入成功(APPLOAD 載入後命令列會顯示結果),以及指令名稱是否和程式裡 defun c: 後面的名稱一致。
Q:同一個 LISP 在同事電腦可以用,我的不行,可能是什麼原因?
常見原因是 AutoCAD 版本或語系不同、信任的位置設定不同、物件鎖點與系統變數設定不同,或同事的電腦另外載入了程式需要的其他 LISP 檔。