一、學好 AutoLISP 的關鍵、 基本結構與語法:單元二:AutoLISP的關鍵、基本結構及語法
1. AutoLISP 程式語言的特質
A.語法簡單
B.功能函數強大
C.撰寫的環境不挑剃
D.直譯式程式,『即寫即測、即測即用』
E.橫跨 AutoCAD 各作業平台,悠然自得 (註:以上五點,讀者可以參考上一章的剖析!!!)
2.學好 AutoLISP 的關鍵:充份掌握『語法結構』&『功能函數』的搭配!!!
3.重要的 AutoLISP 的基本語法結構規則1: 以括弧組成運算式,、相對稱左右括弧數一定要成雙成對
規則2: 運算式型態:(運算元 運算子 運算子 運算子)
1.1 運算元包括『功能函數』&『自定函式』
1.2 運算子(引數)包括:
A.整數(Integer) 如 8,-17,500,9999 .....
B.實數(Real) 如 8.5,-17.456 .....
C.字串(String) 如 "AutoCAD","123"
D.串列(List) 如 ("a" "b" "c"),(x y)
E.圖元名稱代碼 如 <entity name: 6000f262>
F.檔案代碼 如 <file:#12438>.....
G.選擇群集代碼 如 <Selection set:1>
規則3:運算式中的『運算子』,可以是另一『運算式』或『副程式』
規則4: 多重的括弧運算式,運算的先後順序是『由內而外、由左而右』
規則5: 以檔案型態存在的 AutoLISP 程式(ASCII 檔案),其副檔名必須是.lsp
規則6: 撰寫的環境,只要是一般的文書編輯軟體、記事本,可編輯 ASCII 檔案者都適用
規則7: 以 defun 功能函數定義新的指令或新的功能函式
規則8: 新定義的功能函式名稱,若為『C:函式名』,則此函式可為 AutoCAD新指令
規則9: 載入 AutoLISP 程式的作法:=> 指令:後直接鍵入 (load "LISP主檔名")
規則10: AutoLISP 程式中,在『分號 ;』後的內容均為註解,程式不處理,適時的增加註解,將使程式更具可看性、學習性及完整性
規則11: AutoLISP 最常用的變數型態是『整數』、『實數』、『字串』、『點串列』四種,變數的型態依據設定值而自動定義,變數會一直儲存該值,直到被重新設定值或繪圖結束自動消失
規則12:以 setq 功能函數設定變數值 (setq 變數名稱 設定值)
規則13:欲在 AutoCAD 的環境中,查看一變數值,指令:下鍵入『!變數名』即可
規則14:以(defun C:函式名(引數 / 變數) ........)程式中,程式中的變數若在『/』右邊變數內,則稱為『區域變數』,否則為『整體變數』
充份掌握『語法結構』&『功能函數』的搭配!!! 其時這個關鍵亦是學習其它程式語言的關鍵.
- 『語法結構』AutoLISP 的語法結構規定的並不多,變數不用事先定義及宣告,讀者可熟記下一單元有關重要的 AutoLISP基本語法結構,十四條設計上要求的『規則』
- 『功能函數』AutoLISP 之所以能功能如此強大,都有賴功能函數,其成員共約200個:
- 一般性函數170個
- ADS 定義特殊函數9個
- 配合 DCL 交談框設計函數 22個
各功能函數在使用上要求配合的運算子(引數)型態,均有其規定,當然,您可不能亂給!
例如:
指令:(+ 1 2 3 "ABC")
傳回:error : bad argument type (引數型態錯誤)
因為『+』函數不接受字串,而 "abc" 正是字串
指令:(rtos "abc")
傳回:error : bad argument type (引數型態錯誤)
因為『rtos』函數只接受實數轉字串
詳細內容可參考下一章『快速瀏覽 AutoLISP 功能函數』至於各功能函數詳細的語法與實例應用,讀者請參閱本書『第三篇AutoLISP功能函數詳解』
三、重要的 AutoLISP 的基本語法結構:
規則1:以括弧組成運算式,左右括弧數一定要成雙成對、相對稱請依序在『指令:』列 (或指令:) 後面直接鍵入以下運算式
指令:(+ 1 2 3 4 5) 傳回加總和15
指令:(max 14.5 8.9 35) 傳回最大值35
指令:(menucmd "p1=*") 顯示拉下POP1
指令:(getint "Enter Real:") 傳回Enter Real:要求輸入一個實數
指令:(setq a (* 12.5 4)) 傳回相乘值 50,同時設定給『變數 a』
指令:!a 回應50 (註:! 號可用來查詢變數值)
指令:(min 75 a 63) 回應最小值50 (因為變數值a代表50)
錯誤的範例:
指令:(setq a (* 12.5 4)
1> 傳回1>表示少了一個括弧
1> ) 此時,只要再補上一個 ) 即可
指令:(setq a (* 12.5 4
2> 傳回2>表示少了二個括弧
2> )) 此時,只要再補上二個 ) 即可
規則2:運算式型態 (運算元 運算子 運算子 運算子 ...)或 (函數(式) 引數 引數 引數 ...)
或 (函數(式) 元素 元素 元素 ...)
1.1 運算元包括『功能函數』&『自定函式』功能函數: 如上練習中的
+、max、menucmd、getint、 setq、*、min,詳細內容可參考下一章『快速瀏覽 AutoLISP 功能函數』&『第三篇 AutoLISP功能函數詳解』自定函式: 由設計者自行定義的新函式或副程式
1.2 運算子(又稱引數或元素)包括:
A.整數(Integer): 如8,-17,500,9999…
正常範圍: 2的16次方,介於-32768與+32767之間
特殊範圍: 若以 float 函數將其轉為實數,則範圍2的32次方, 介於-2147483648與+2147483647之間
B.實數(Real): 如8.5,-17.456…
正常範圍: 帶有小數點的數,精度可達 14 位有效數字
C.字串(String): 如 "AutoCAD","123","Enter Real:","7.5",…
正常範圍: 以雙引號內夾『字元』為認定,字元數不受限制
D.串列(List): 如 ("a" "b" "c"),(x y),(x y z),("a" 8 3.5),....
正常範圍: 以左右括號內夾『元素』為認定,元素型態非常彈性
使用頻率: 在 AutoLISP 程式設計中應用非常高
範例說明 : ("a" 8 3.5 kk (1 2))
表示此串列內有五個元素 "a"表示字串a、8表示整數8、3.5表示實數3.5、kk表示變數kk、(1 2)表示串列(1 2)
2D 點座標(x y) 表示法 => 以二實數形成串列 3D 點座標(x y z) 表示法 => 以三實數形成串列 E.圖元名稱代碼:如 <entity name: 6000f262> ...
使用範圍: AutoCAD 會自動賦予圖元指向代碼,透過此代碼可找到圖元的資料庫記錄
範例說明: (setq en (entlast))
傳回 <entity name: 60000062>
(entget en) 可找到圖元的資料庫串列
F.檔案代碼: 如<file:#12438>…
使用範圍: 開啟(open)檔案作讀檔(r)、寫檔(w)使用時,所產生的代碼,如下:
範例說明:
(setq ffr (open "test.txt" "r")) 回應 <file:#24138>
(setq ffw (open "abc.txt" "w")) 回應 <file:#34812>
G.選擇群集代碼: 如<Selection set:1>、<Selection set:1>…
規則3 :運算式中的『運算子』,可以是另一『運算式』或『副程式』功能函數使用語法:使用範圍: 一個或數個圖元所形成的選擇集
範例說明:
(setq ss (ssget))
選取物件: (可選擇物體)
選取物件: (可選擇物體)
選取物件: (按 [ENTER] 鍵)
回應 <Selection set:1>
規則4:多重的括弧運算式,運算的先後順序是『由內而外、由左而右』(strcat 字串1 字串2 字串3 ....) 字串結合功能函數
(getstring 提示) 要求鍵入一個字串
(rtos 實數) 將實數轉換成字串
範例說明1: (strcat "abc" "123" "LISP") 傳回:"abc123LISP"
範例說明2: (strcat "abc" (getstring "Enter String:" ) (rtos 123.45))
執行結果: Enter String: 鍵入任一字串,假設是鍵入 *HELLO*
回應 "abc*HELLO*123.45"
本例中的strcat函數在語法中要求的『運算子』必須是『字串』型態
『運算子1』= "abc" 是正常的字串運算子
『運算子2』= 運算式 (getstring "Enter String:") 傳回結果是一字串 "*HELLO*"
『運算子3』= 運算式 (rtos 123.45) 傳回結果是一字串 "123.45"
範例說明: 請將10.25 + 17 - 13.2 / 7的結果,設定給變數kk,並轉換成AutoLISP 的運算式
解法技巧A: 1:運用『二分法、加括號』:(10.25 + 17) - (13.2 / 7) 2:運算元往前提: kk = (- (10.25 + 17) (13.2 / 7)) 3:運算元再往前提:kk = (- (+ 10.25 17) (/ 13.2 7)) 4:轉換完成: (setq kk (- (+ 10.25 17) (/ 13.2 7)))
解法技巧B:
1:運用『二分法、加括號』:(10.25 + (17 - (13.2 / 7)))
2:運算元往前提: kk = (+ 10.25 (17 - (13.2 / 7)))
3:運算元再往前提:kk = (+ 10.25 (- 17 (/ 13.2 7)))
4:轉換完成: (setq kk (+ 10.25 (- 17 (/ 13.2 7))))
規則5:以檔案型態存在的AutoLISP程式(ASCII檔案),其副檔名必須是.LSP
規則6:撰寫的環境,只要是一般的文書編輯軟體,可編輯 ASCII 檔案者都適用
規則7:以 defun 功能函數定義新的指令或新的功能函式 (註:引數及區域變數可省略)如:PE2、PE3、DW3、書中仙、漢書、EDIT、記事本....等
規則8:新定義的功能函式名稱,若為『C:函式名』,則此函式可為 AutoCAD 新指令程式結構型態:(defun 函式名稱(引數/區域變數)
: :
: : 程式內容
: :
)
(註:引數及區域變數可省略)
規則9: 載入AutoLISP程式的作法:指令:後直接鍵入 (load "LISP主檔名")程式結構型態: (defun C:KK(引數/區域變數)
: :程式內容
: :
: :
)
則載入此 LISP 程式後,可在 指令: 後直接鍵入新定義的 KK 指令
註:load 與字串間的空格,可有可無
註:load 與雙引號間的空格,可有可無 (load"LISP主檔名")
範例: 在 c:\lsptools 目錄下有一LISP程式tt.lsp,而您目前的工作目錄在c:\dwg下
- 若『環境設定』之『支援檔案搜尋路徑』有指定到c:\lsptools目錄,則欲使用載入tt.lspà 指令:後鍵入 (load "tt") 即可
- 若『環境設定』之『支援檔案搜尋路徑』無指定到c:\lsptools目錄,則鍵入 (load"tt") 後,會出現錯誤訊息如下:
無法開啟「tt.lsp」做輸入錯誤: 載入失敗(LOAD "tt")*取消*
規則10:AutoLISP 程式中,在『分號 ;』後的內容均為註解,程式不處理,適時的增加註解,將使程式更具可看性、學習性及完整性此時您可鍵入:
指令:(load "c:\\lsptools\\tt") 或
指令:(load "c:"/lsptools/tt)
不可鍵入: (load "c:\lsptools\tt")
因為『\』在 AutoLISP 結構語法中已經用於『跳脫碼控制』了
規則11:AutoLISP 最常用的變數型態是『整數』、『實數』、『字串』、『點串列』四種,變數的型態依據設定值而自動定義,變數會一直儲存該值,直到被重新設定值或繪圖結束自動消失 規則12:以 setq 功能函數設定變數值 (setq 變數名稱 設定值)範例: pp.lsp 內容如下:
;本程式功能可快速畫門、窗
;設計者:QQ博士
;版權所有,歡迎使用
(defun c:pp()
: :
; 以下為畫門副程式
: :
; 以下為畫窗副程式,
: :
: :
)
規則13:欲在 AutoCAD 的環境中,查看一變數值,指令:下鍵入『!變數名』即可範例:
(setq a 100) ;變數 a 值設定成整數 100
(setq b 123.56) ;變數b值設定成實數123.56
(setq c "Good morning!!!") ;變數 c 值設定成字串
(setq pt1 (getpoint "Enter POINT:")) ;變數 pt1 值設定成點串列
(setq pt2 (list a b))
;此時,a值是100,b值是123.56變數pt2值設定成點串列(100 123.56)
(setq pt3 '(297 210)) ;變數 pt3 值設定成點串列 (297 210)
注意: 直接設定成點串列時,不能省略單引號『'』否則會被誤認 (297 210)又是一個運算式, 297是運算元而出錯!
規則14:以(defun C:函式名(引數 / 變數) ........)程式中,程式中的變數若在『/』右邊變數內,則稱為『區域變數』,否則為『整體變數』(註:在 AutoLISP 中,未賦予值的變數,其值皆回應 nil)範例:
指令:(setq aa (+ 100 75)) 傳回:175
指令:!aa 傳回:175
指令:(setq pp (list 90 50)) 傳回:(90 50)
指令:!pp 傳回: (90 50)
指令:!ww 傳回:nil 空值無設定
『區域變數』於此程式執行完畢後,其值自動消失
『整體變數』於此程式執行完畢後,其值仍然存在
範例: test.lsp 內容如下
(defun c:tt(/ sa sb sc)
(setq sa 100)
(setq sb 20)
(setq sc 10)
(setq sd (+ sa sb sc))
)
回到: 指令:鍵入(load"tt") 傳回:c:tt
指令:tt 傳回:130
指令:!sa 傳回:nil (屬區域變數)
指令:!sb 傳回:nil (屬區域變數)
指令:!sc 傳回:nil (屬區域變數)
指令:!sd 傳回:130 (屬整體變數)