Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 108

By Ngọc Nguyễn 2013 Page 1 of 108

Để viết lisp mình dùng phương pháp giống như chơi trò xếp gạch, nghĩa là các đoạn đã viết
thành công mình sẽ lưu lại thành kiểu từ điển sau đó thì xếp nó lại với nhau theo nhu cầu
của mình. Xin chia sẽ với các bạn bộ từ điển viết lisp của mình.

Đoạn mở đầu cho tất cả các lisp:


(defun c:tenlenh ()
(command "undo" "be")
Trong đó tenlenh là cái mà bạn gỏ vào thanh command để thực thi lệnh lisp.

Đoạn kết thúc cho tất cả các lisp:


(command "undo" "be")
(princ)
)

Còn tất cả các đoạn bên dưới thì ghép vào giữa hai đoạn trên thì coi như bạn viết được lisp rồi
đó.
By Ngọc Nguyễn 2013 Page 2 of 108

Hướng dẫn viết lisp bài 1

Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!
*Để chọn 1 điểm (để làm gì thì tùy bạn) dùng dòng sau:
(setq a (getpoint "Chon diem: "))
Trong đó: 
-a: là điểm xác định bằng cách pick chuột.
-Chon diem: là dòng chữ sẽ hiển thị trên dòng lệnh khi chạy lệnh.

*Để thực hiện 1 lệnh cad trong lisp thì gỏ đúng trình tự mà lệnh cad chạy, lưu ý "" là thay cho
enter. 
Ví dụ:(command ".line" a b "")
Tác dụng:
-Thực hiện lệnh line, chọn điểm a, chọn điểm b, enter.
-Bạn thấy chưa giống y như vẽ cad thôi có gì đâu.
*Bây giờ ví dụ gọn gọn nhé: 
Bắt đầu bằng cái lisp vẽ đoạn thẳng nhé.
(defun c:doanthang ()
(setq a (getpoint "Chon diem: "))
(setq b (getpoint "Chon diem: "))
(command ".line" a b ""))
-Bạn lưu đoạn trên ra file vdt.lsp-Khởi động CAD.-Gỏ lệnh AP. Chọn đến file vdt.lsp load nó
lên.
-Rồi bạn chỉ cần nhập lệnh doanthang nó hỏi bạn Chon diem bạn chọn 1 điểm nó lại hỏi Chon
diem bạn lại chọn nó vẽ ra đoạn thẳng qua 2 điểm bạn vừa chọn. 
-Khớ khớ chắc bạn kiu lisp gì mà mắc cười vậy. Đừng nôn nóng cái này là bước đầu mà từ từ rồi
bạn sẽ thấy cái hay của lisp đem lại.
By Ngọc Nguyễn 2013 Page 3 of 108

Hướng dẫn viết lisp bài 2


Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!
Đây là những gì hiển thị trên dòng lệnh khi chạy lệnh doanthang.
Command: doanthang
Chon diem: Chon diem: 
nil

*Phân tích: 
-Hai câu hỏi của lisp là Chon diem và Chon diem dính liền nhau trên 1 hàng và cuối cùng xuất
hiện chữ nil không được đẹp mắt lắm.
-Khi bạn chọn điểm thứ nhất trên màn hình lisp sẽ tiếp tục chọn điểm thứ hai nhưng không xuất
hiện “dây tóc” nối điểm thứ nhất với con trỏ như thường thấy ở lệnh line của cad làm việc chọn
điểm thứ hai không được bài bản cho lắm.
*Khắc phục:Sửa đoạn lisp lại như sau:
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(princ))
Bây giờ load lại và thực hiện lệnh doanthang sẽ thấy:
Command: DOANTHANG
Chon diem:
Chon diem:
Hai câu hỏi của lisp đưa ra xuống hàng đàng hoàn.Chữ nil cuối lệnh đã biến mất.Có dây tóc giúp
việc chọn điểm thứ hai trực quan hơn.
*Phân tích:\n sẽ làm cho các nội dung phía sau đó nhảy xuống hàng.
Thêm chữ a sau getpoint sẽ làm xuất hiện dây tóc nối con trỏ với điểm a
(princ) sẽ ghi ra 1 dòng trắng giúp triệt tiêu các thông báo lòng thòng khi chạy lisp còn dư.
By Ngọc Nguyễn 2013 Page 4 of 108

Hướng dẫn viết lisp bài 3

Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!
Cũng với đoạn trên nhưng bây giờ không vẽ đường thẳng nửa mà vẽ đường tròn:
Thay dòng(command ".line" a b "")
Bằng dòng(command ".circle" a b)
Bạn để ý nhé dòng vẽ line có "" sau khi chọn a và b còn vẽ circle thì không. Vì khi vẽ line sau
khi nhập hai điểm sẽ tiếp tục lệnh line muốn kết thúc phải enter, còn circle thì chỉ cần chọn tâm
và bán kính là kết thúc lệnh nên không có enter để kết thúc.
-Để thấy cái lợi của lisp bạn lưu đoạn sau thành file lsp rồi chạy thử.
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(command ".circle" a b)(command ".circle" b a)
(princ))
Sẽ thấy sau khi chọn 2 điểm trên màn hình lisp sẽ vẻ ra:
-Đường thẳng từ a đến b.
-Đường tròn tâm a bán kính ab.
-Đường tròn tâm b bán kính ab.
**Kinh nghiệm rút ra:
-Từ 1 kiểu dữ liệu nhập vào lisp có thể làm nhiều việc (đây mới là sử dụng nguyên gốc hai điểm
a và b chưa kể đến tính toán và cho ra điểm mới phục vụ mục đích nào đó).
-Sau khi dử liệu được nhập (điểm a và b) có thể dùng vào mọi việc không cần đến thứ tự ví dụ
nhập a trước nhưng vẫn có thể dùng b trước như dòng vẽ circle thứ 2.
By Ngọc Nguyễn 2013 Page 5 of 108

Hướng dẫn viết lisp bài 4


Từ 2 điểm a và b lisp sẽ làm được rất nhiều việc. 
-Giới thiệu 1 số hàm đối với 1 điểm:

(setq xa (car a)) tọa độ x của điểm a


(setq ya (cadr a)) tọa độ y của điểm a
(setq za (caddr a)) tọa độ z của điểm a
-Giới thiệu 1 số hàm đối với 2 điểm:
(setq daiab (distance a b)) khoảng cách từ a đến b
(setq gocab (angle a b)) góc mà đoạn ab tạo với trục x
-Giới thiệu hàm tính toán:Cú pháp các hàm toán học hơi ngược với cách thông thường:(dấu
sốđầu sốsau) nghĩa là nếu muốn có a+b thì viết (+ a b) đối với + - * / điều như vậy.
**Từ hai điểm a và b kết hợp các hàm trên chúng ta bắt đầu cho việc tính toán cho ra những kết
quả phục vụ cho việc mình cần.
-Tìm điểm nằm chính giữa a và b:
+Ngoài việc xác định 1 điểm bằng cách pick điểm thông qua hàm getpoint như trên thì 1 điểm
trong lisp còn biểu diển như sau:
(setq c (list xc yc zc))
Trong đó:Xc, yc, zc lần lượt là tọa độ x, y,z của điểm c các giá trị này được xác định kiểu gì
cũng được. Trong trường hợp này xác định từ các giá trị của điểm a và b. Để đơn giản mình chỉ
tính toán trên mặt phẳng xy khi nào lisp vẽ phối cảnh mình hãy đưa giá trị z vào từ bây giờ 1
điểm chỉ cần biểu diển bằng x và y nên xác định điểm c như sau: (setq c (list xc yc))
(setq xab (+ xa xb)) xác định 1 biến tạm bằng tổng x điểm a và x điểm b
(setq yab (+ ya yb)) xác định 1 biến tạm bằng tổng y điểm a và y điểm b
(setq xc (/ xab 2)) xác định x điểm c bằng cách lấy xab chia 2
(setq yc (/ yab 2)) xác định y điểm c bằng cách lấy yab chia 2
(setq c (list xc yc)) xác định điểm c bằng x và y vừa tính được.

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(command ".circle" a b)
(command ".circle" b a)
(setq xa (car a))
(setq ya (cadr a)) 
(setq xb (car b))
(setq yb (cadr b)) 
By Ngọc Nguyễn 2013 Page 6 of 108

(setq xab (+ xa xb)) 


(setq yab (+ ya yb)) 
(setq xc (/ xab 2)) 
(setq yc (/ yab 2)) 
(setq c (list xc yc)) 
(command ".circle" c a)
(princ))
*Bây giờ chạy thử đoạn trên bạn sẽ thấy có thêm 1 vòng tròn tâm là trung điểm đoạn ab đường
kính bằng ab.
*Hai hàm: distance và angle trong bài này chưa xài tới nhưng nhân tiện nói về đểm mình nói
luôn bạn hãy ghi nhớ cho sau này.
By Ngọc Nguyễn 2013 Page 7 of 108

Hướng dẫn viết lisp bài 5


Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!
Đoạn lisp trên mình viết rất cơ bản làm từng bước 1 để bạn làm quen, thực chất bạn có thể làm
gọn lại bằng cách gộp các đoạn lại với nhau.

-Cụ thể đoạn


(setq xa (car a))
(setq xb (car b))
(setq xab (+ xa xb)) 
-Có thể thay bằng
(setq xab (+ (car a) (car b))) 
-Tương tự sau khi gộp bước 1 từ đoạn:
(setq xa (car a))
(setq ya (cadr a)) 
(setq xb (car b))
(setq yb (cadr b)) 
(setq xab (+ xa xb)) 
(setq yab (+ ya yb)) 
(setq xc (/ xab 2)) 
(setq yc (/ yab 2)) 
(setq c (list xc yc)) 
-Ta có
(setq xab (+ (car a) (car b))) 
(setq yab (+ (cadr a) (cadr b))) 
(setq c (list (/ xab 2) (/ yab 2))) 
-Tương tự sau khi gộp bước 2 ta có
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2))) 
*Đoạn lisp bây giờ còn như sau:
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")(command ".circle" a b)
(command ".circle" b a)
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2))) 
(command ".circle" c a)
(princ))
*Chạy thử kết quả giống y như trước nhưng ngắn được 1 số dòng. Nếu mới bắt đầu viết gộp quá
rối thì bạn cứ viết từng bước như cũ đến khi nào rành rành thì bắt đầu gộp lại.
*Mới có pick 2 điểm mà đã đủ thứ chuyện vậy đó. Tất nhiên cái hình mà lisp này vẽ ra giống y
By Ngọc Nguyễn 2013 Page 8 of 108

như cái mạng nhện vậy chẳng để làm gì cả nhưng khi đã nắm vấn đề thì bạn muốn làm gì mà chả
được.

Hướng dẫn viết lisp bài 6


Bây giờ bỏ bớt cái hình tròn tâm b đường kính ab đi. 
Áp dụng lệnh Array với cái hình tròn tâm a đường kính ab. 
Cho nó Array thành 8 đối tượng quanh điểm c nhé.
-Cú pháp lệnh Array như sau:
+Vì trong lệnh Array có hỏi chọn đối tượng nhưng mình muốn nó chọn tự động cái hình tròn thì
làm sao? Giải pháp đưa ra là lựa chọn last nghĩa là chọn đối tượng mới tạo ra muốn vậy cái
đường tròn này mình đừng vẽ vội mà chỉ vẽ nó trước khi thực hiện lệnh Array thôi.
(command ".circle" a b)
(command ".array" "last" "" "p" c "8" "" "")
+Giải thích dòng trên: gọi lệnh Array, gỏ last để chọn đối tượng vừa tạo trước đó, enter kết thúc
chọn đối tượng, gõ p để chọn kiểu Array là Polar, chọn điểm tâm quay là c, gỏ 8 để xác định số
lượng tạo ra là 8, enter hai lần để kết thúc lệnh Array.

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2))) 
(command ".circle" c a)
(command ".circle" a b)
(command ".array" "last" "" "p" c "8" "" "")
(princ))

*Chạy thử đoạn trên. Khớ khớ đẹp chưa có nguyên cái bông rồi nhưng sao nhiều cánh quá á?
Yên tâm sẽ có cách cho bạn quyết định số lượng cánh của cái bông này…….
By Ngọc Nguyễn 2013 Page 9 of 108

Hướng dẫn viết lisp bài 7

**Bây giờ thêm 1 dòng giúp bạn quyết định số lượng sẽ Array.
-Để nhập 1 chuổi vào lisp dùng dòng sau:
(setq sl (getstring 5"\nSo luong:"))
-Bạn lưu ý con số 5 này nhé, nếu không có nó thì khi nhập chuổi nút Space sẽ tương đương với
enter nghĩa là kết thúc quá trình nhập chuổi, còn có nó thì Space là khoảng trắng. 

Tùy theo nhu cầu chuổi cần nhập mà quyết định có số 5 này hay không.
-Để thấy lisp làm việc từng bước mình thêm dòng hỏi số lượng này vào sau dòng vẽ line và
circle. 
Sau khi bạn nhập số lượng vào thì thực hiện lệnh array như vậy thú vị hơn là chọn 2 điểm và hỏi
số lượng hết rồi mới vẽ 1 lần xong lun.
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2)))
(command ".circle" c a)
(command ".circle" a b)
(setq sl (getstring "\nSo luong:"))
(command ".array" "last" "" "p" c sl "" "")
(princ))
Chạy thử sẽ thấy sau khi chọn 2 điểm trên màn hình lisp sẽ vẻ ra:
-Đường thẳng từ a đến b.
-Đường tròn tâm c đường kính ab.
-Đường tròn tâm a bán kính ab. Lúc này lisp dừng lại và hỏi số lượng bạn nhập vào lisp tiếp tục
array cái hình tròn này ra theo số mà bạn nhập vào và kết thúc lệnh.
By Ngọc Nguyễn 2013 Page 10 of 108

Hướng dẩn viết lisp bài 8:

**Rồi bây giờ bỏ hết nấy cái Circle và Array đi mình đi vào viết text.
-Phần viết text bằng lisp là rất phiền phức ví dụ để viết text dùng dòng sau:
(command ".TEXT" "m" c 250 0 "tailieukythuat.com")
-Giải thích: gọi lệnh text nhập m để định kiểu canh lề là Middle chọn điểm viết ra là c độ lớn text
là 250 góc quay là 0 nội dung là tailieukythuat.com.
+Trường hợp Text style hiện hành có Text Height bằng 0 thì không cấn đề gì.
+Trường hợp Text style hiện hành có Text Height khác 0 thì lệnh text sẽ bỏ qua phần hỏi Text
Height (độ lớn) nên với cú pháp trên số 250 sẽ được gán cho góc quay của text, số 0 gán cho nội
dung text và một mớ lỗi.
-Giải pháp: Phải đảm bảo Text style hiện hành có Text Height bằng 0 bằng cách< trước khi thực
hiện lệnh viết text phải có dòng tạo Text style như sau:
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
+Mục đích tạo Text style có tên tlkt fonts VNI.HELVE (bạn thích font nào thì chọn font đó),
Text Height bằng 0, các cái đằng sau bạn cứ chấp nhận vậy đi khỏi suy nghỉ (nói chung để kết
thúc việc tạo kiểu chử bằng lisp thì phải đủ cú pháp như vậy)
+Sau khi tạo ra Text style này sẽ hiện hành và đoạn viết text phía sau sẽ đảm bảo chạy đúng.

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" c 250 0 "tailieukythuat.com")
(princ)
)

Chạy đoạn trên sẽ thấy sau khi chọn 2 điểm sẽ vẽ ra:


+ Line ab.
+ Text tailieukythuat.com tại trung điểm ab.
By Ngọc Nguyễn 2013 Page 11 of 108

Hướng dẩn viết lisp bài 9:

**Bây giờ áp dụng dòng nhập chuổi đế nhập độ lớn và nội dung dòng text nhé:

(setq dl (getstring "\nDo lon:"))


(setq nd (getstring 5"\nNoi dung:"))

Bạn để ý nhé:
+Dòng hỏi độ lớn không có số 5 vì độ lớn không cần nhập khoảng cách.
+Dòng hỏi nội dung có số 5 vì nội dung có thể có chứa khoảng cách.

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(setq dt (getstring "\nDo lon:"))
(setq nd (getstring 5"\nNoi dung:"))
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" c dt 0 nd)
(princ)
)

Tới bây giờ nếu đã nắm được hết những điều mình đã viết trên thì bạn có thể viết được khối thứ
rồi đấy. Cứ ngồi suy nghĩ và thử viết vài đoạn xem. Khi mà chạy cái lisp do chính mình viết thì
cảm giác sướng ghê lắm cứ thử xem!

*Mình ra cái đề bài để chủ nhật bạn viết thử nhé, thứ 2 mình sẽ có đáp án:
-Đề: hỏi chọn 2 điểm, hỏi độ lớn, viết ra tại điểm thứ 2 dòng text có độ lớn vừa nhập, nội dung là
giá trị khoảng cách hai điểm.
-Gợi ý:
+Dùng hàm distance để lấy khoảng cách giữa 2 điểm.
By Ngọc Nguyễn 2013 Page 12 of 108

Hướng dẩn viết lisp bài 10:

*Đáp án bài trước đây:


(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(setq dt (getstring "\nDo lon:"))
(setq nd (distance a b))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" b dt 0 nd)
(princ)
)
Bạn chạy thử sẽ thấy 1 vấn đề to đùng thế này: Cái dòng text khoảng cách này sau dấu phẩy là 1
lô xích sông rất nhiều số lẻ nhưng mình lại không thích thế chỉ mún sau dấy phẩy là 3 số lẻ thôi
thì làm nào ??????
-Giới thiệu bạn 1 hàm quyết định số lẻ sau dấu phẩy nhé: Hàm rtos cú pháp như sau.
(setq ndlc (rtos nd 2 3))
Trong đó số 3 là số lẻ sau dấu phẩy.
-Thêm dòng này vào là kết quả ưng ý ngay:

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(setq dt (getstring "\nDo lon:"))
(setq nd (distance a b))
(setq ndlc (rtos nd 2 3))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" b dt 0 ndlc)
(princ)
)
By Ngọc Nguyễn 2013 Page 13 of 108

Hướng dẩn viết lisp bài 11:

*Bây giờ trước dòng text thể hiện khoảng cách này bạn muốn thêm chử L= ví dụ
L=3621.025 thì sao???
-Giải pháp dùng hàm ghép chuổi, hàm: strcat cú pháp như sau:
(setq ndthem (strcat "L=" ndlc))
Trong đó phần trong ngoặc kép là phần muốn thêm vào chuổi.

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(setq dt (getstring "\nDo lon:"))
(setq nd (distance a b))
(setq ndlc (rtos nd 2 3)) 
(setq ndthem (strcat "L=" ndlc))
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2))) 
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" b dt 0 ndthem)
(princ)
)

Với bây nhiêu thứ bạn có thể viết được cái lisp đánh cao độ rồi đấy. Linh hoạt 1 chút với vài hàm
tính toán + - * / là xong ngay. (Phần viết lisp đánh cos mình sẽ quay lại sau, đến khi nào nói đến
các hàm điều kiện đã).

Nhân nói về text và chuổi mình cung cấp thêm 1 vài hàm liên quan:
(setq so (getreal "\nNhap so: ")) nhập vào 1 chuổi dạng số có thể dùng để tính toán bằng các hàm
+-*/.

(setq nd (getstring "\nNoi dung:")) nhập vào 1 chuổi dạng text có thể là số nhưng không dùng để
tính toán được.

(setq sochu (strlen chuoicandem)) lấy ra giá trị số lượng ký tự của chuổi chuoicandem.

(setq chuoicon (substr chuoime vitridoc sokytudoc)) lấy chuoicon từ chuoime vị trí lấy bắt đầu từ
vitridoc với số lượng trích bằng sokytudoc. Ví dụ
(setq chuoicon (substr "www.tailieukythuat.com" 5 14)) thì chuoicon = tailieukythuat

(setq ndhoa (strcase ndgoc)) làm chuổi ndgoc trở thành ký tự viết hoa toàn bộ. Ví dụ:
(setq kyhieu (strcase (getstring 5"\nTen truc: "))) lúc này chuổi nhập vào dù bạn gỏ hoa hay
By Ngọc Nguyễn 2013 Page 14 of 108

thường điều thành chử hoa hết. (cái này áp dụng cho lisp đánh trục kích thước vì trục kích thước
thì các chữ luôn viết hoa).

Hướng dẩn viết lisp bài 12:

*Trong từng trường hợp cụ thể bạn có thể định chiều cao chử cho phù hợp với mục đích của bạn
bằng cách mặc định độ lớn hoặc hỏi nhập độ lớn. Nhưng khi bạn muốn dùng text để hiển thị 1
thông báo gì đó thì làm sao?
Lúc này phải giải quyết 2 vấn đề:
-Độ lớn của text so với màn hình hiện hành là đảm bảo cho người dùng đọc được thông báo của
bạn.
-Sau 1 thời gian nhất định text này phải bị xóa đi.
Mình cung cấp hai hàm để giải quyết:
(setq dolon (getvar "viewsize")) đo kích thước chiều cao màn hình và gán cho biến dolon.
(command "DELAY" "1000" "") dừng lisp trong thời gian nhất định (cứ 1000 là 1 giây, hồi máy
cũ thì mình thấy đúng vậy còn cái máy bây giờ mới nó chạy như giặc vậy mình cũng không rỏ là
bao lâu nhưng gán đến 10000 thì nó không chịu nửa) sau đó chạy tiếp các dòng lisp phía dưới.

Bây giờ mình viết 1 đoạn lisp vui vui thế này nhé:

(defun c:tlkt ()
(setq a (getpoint "\nChon diem viet: "))
(setq b (getpoint a"\nChon diem den: "))
(setq dolon (getvar "viewsize")) 
(setq dolonchu (/ dolon 30))
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2))) 
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" a dolonchu 0 "tailieukythuat.com")
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".ERASE" "last" "")
(princ)
)

Giải thích:
-Chọn điểm đầu tiên là a, điểm thứ hai là b.
By Ngọc Nguyễn 2013 Page 15 of 108

-Đo độ cao màn hình gán cho dolon.


-Lấy dolon chia cho 30 gán cho biến dolonchu.
-Từ a và b suy ra điểm c là trung điểm ab.
-Tạo text Style và viết dòng chử tại điểm a độ lớn bằng dolonchu nội dung tailieukythuat.com. 
-Dừng 1 lát.
-Move cái text đó từ a đến c.
-Dừng 1 lát.
-Lại Move cái text đó từ a đến c. Lúc này cái text đang nằm ở c nên nó sẽ được chuyển đến b.
-Dừng 1 lát.
-Xóa cái text đó đi.
By Ngọc Nguyễn 2013 Page 16 of 108

Hướng dẩn viết lisp bài 13:

Vấn đề là bây giờ bạn muốn cái text đi từ từ thôi nghĩa là khoảng cách di chuyển nhỏ lại nhưng
lại mới biết cách xác định trung điểm từ hai điểm. Sau đây mình trình bày thêm 1 cách xác định
1 điểm bằng lisp nửa. Hàm Polar cú pháp như sau:
(setq c (polar a goc dodai)) xác định điểm c từ điểm a với goc và dodai.
Cũng cái lisp trên nhưng bây giờ mổi lần move cái text đi bằng 1/10 khoảng cách ab thôi:

(defun c:tlkt ()
(setq a (getpoint "\nChon diem viet: "))
(setq b (getpoint a"\nChon diem den: "))
(setq dolon (getvar "viewsize")) 
(setq dolonchu (/ dolon 30))
(setq daiab (distance a b)) 
(setq dodai (/ daiab 10))
(setq gocab (angle a b)) 
(setq c (polar a gocab dodai)) 
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" a dolonchu 0 "tailieukythuat.com")
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "") 
(command ".ERASE" "last" "")
(princ)
)

Giải thích:
-Chọn điểm đầu tiên là a, điểm thứ hai là b.
By Ngọc Nguyễn 2013 Page 17 of 108

-Đo độ cao màn hình gán cho dolon.


-Lấy dolon chia cho 30 gán cho biến dolonchu.
-Do khoảng cách từ a tới b gán cho biến daiab.
-Chia daiab cho 10 gán cho biến dodai.
-Đo góc ab tạo với trục x gán cho biến gocab.
-Dùng hàm Polar xác định điểm c từ điểm a, đi theo góc gocab với khoảng cách dodai
-Tạo text Style và viết dòng chử tại điểm a độ lớn bằng dolonchu nội dung tailieukythuat.com. 
-Dừng 1 lát.
-Move cái text đó từ a đến c.
-Làm hai bước trên 10 lần.
-Dừng 1 lát.
-Xóa cái text đó đi.
By Ngọc Nguyễn 2013 Page 18 of 108

Hướng dẩn viết lisp bài 14:

Dòm lại cái lisp bài trên bạn sẽ thấy đoạn lặp đi lặp lại 10 lần là quá dài cần có giải pháp thích
hợp hơn. Giới thiệu với bạn 1 vòng lặp đơn giản nhất: Vòng lặp Rpeat cú pháp như sau:

(repeat solan
Nội dung cần lặp lại
)
Như vậy đoạn lisp sẽ sửa lại như sau.

(defun c:tlkt ()
(setq a (getpoint "\nChon diem viet: "))
(setq b (getpoint a"\nChon diem den: "))
(setq dolon (getvar "viewsize")) 
(setq dolonchu (/ dolon 30))
(setq daiab (distance a b)) 
(setq dodai (/ daiab 10))
(setq gocab (angle a b)) 
(setq c (polar a gocab dodai)) 
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" a dolonchu 0 "tailieukythuat.com")
(repeat 10
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
)
(command "DELAY" "5000" "") 
(command ".ERASE" "last" "")
(princ)
)
By Ngọc Nguyễn 2013 Page 19 of 108

Hướng dẩn viết lisp bài 15:


Bây giờ bạn lại muốn số lần move text là do bạn nhập vào kia. Áp dụng hàm getreal xem nào:

(defun c:tlkt ()
(setq a (getpoint "\nChon diem viet: "))
(setq b (getpoint a"\nChon diem den: "))
(setq so (getreal "\nSo lan di chuyen: ")) 
(setq dolon (getvar "viewsize")) 
(setq dolonchu (/ dolon 30))
(setq daiab (distance a b)) 
(setq dodai (/ daiab so))
(setq gocab (angle a b)) 
(setq c (polar a gocab dodai)) 
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" a dolonchu 0 "tailieukythuat.com")
(setq sol (fix so))
(repeat sol
(command "DELAY" "5000" "") 
(command ".MOVE" "last" "" a c)
)
(command "DELAY" "5000" "") 
(command ".ERASE" "last" "")
(princ)
)

Nếu bạn thay dòng:


(setq so (getreal "\nSo lan di chuyen: ")) 
Bằng dòng:
(setq so (getstring "\nSo lan di chuyen: ")) 
Thì lisp sẽ lổi ngay mặc dù bạn vẩn nhập vào là số nhưng chuổi thu được bằng hàm getstring
không dùng để tính toán với các hàm + - * / được nên dòng
(setq dodai (/ daiab so))
Sẽ không lượng giá được, xuất hiện lổi và xẹtttttttttttttt lisp hỏng. Đây là điểm rất cần lưu ý trong
viết lisp.
-Bạn thấy có 1 dòng lạ nửa:
(setq sol (fix so))
Vì vòng lặp repeat đòi hỏi đối số là số nguyên nghĩa là không có phẩy phiếc gì hết. Trong khi
bạn nhập số lần di chuyển bằng hàm getreal kết quả lại là số thực ví dụ nhập 10 thì thực chất nó
biểu diển trong lisp là dạng 10,000000000000000000000000000000... Bạn dùng hàm fix sẽ làm
By Ngọc Nguyễn 2013 Page 20 of 108

mất toàn bộ các ký tự sau dấu phẩy lúc này mới dùng kết quả thu được này cung cấp cho vòng
lặp repeat được.

Hướng dẩn viết lisp bài 16:


*Bây giờ dùng cái lisp trên sửa lại như sau:
Chọn 1 hoặc nhiều đối tượng có sẳn trên màn hình. Chọn điểm gốc a, chọn điểm đến b, hỏi số
lần di chuyển. Move cái đối tượng vừa chọn từ a đến b từ từ với số đoạn di chuyển là số lần vừa
nhập.
-Cần biết cú pháp để chọn đối tượng bằng lisp:
(Setq doituong (Ssget))
-Khi dùng dòng trên các đối tượng được chọn sẽ gán cho biến doituong. Để cho đẹp thêm dòng
(princ "\nChon doi tuong") trước dòng chọn đối tượng để ghi dòng Chon doi tuong ra dòng lệnh
trước khi chọn đối tượng.

(defun c:tlkt ()
(princ "\nChon doi tuong")
(Setq doituong (Ssget))
(setq a (getpoint "\nChon diem goc: "))
(setq b (getpoint a"\nChon diem den: "))
(setq so (getreal "\nSo lan di chuyen: ")) 
(setq daiab (distance a b)) 
(setq dodai (/ daiab so))
(setq gocab (angle a b)) 
(setq c (polar a gocab dodai)) 
(setq sol (fix so))
(repeat sol
(command "DELAY" "5000" "") 
(command ".MOVE" doituong "" a c)
)
(princ)
)

Khi dùng dòng (Setq doituong (Ssget)) để chọn đối tượng thì tất cả các kiểu đối tượng được quét
qua sẽ chọn hết nhưng có đôi lúc bạn có nhu cầu chỉ chọn 1 kiểu đối tượng nào đó thôi ví dụ:
line, dimension, hatch, insert. . . thì dùng dòng sau:
(setq doituong (ssget '((0 . "text"))))
-Lúc này trong vùng quét của bạn chỉ nhận các đối tượng có kiểu nằm trong ngoặc kép (dòng
trên cụ thể là đối tượng kiểu text) là được chọn thôi .
By Ngọc Nguyễn 2013 Page 21 of 108

Hướng dẩn viết lisp bài 17:

*Khi chọn đối tượng lại nảy sinh vấn đề nếu lisp hỏi chọn đối tượng mà không có đối tượng nào
được chọn hết lúc này doituong có giá trị là nil mà lisp vẩn tiếp tục chạy thì sẽ phát sinh lổi. Nên
cần có hàm điều kiện kiểm tra nếu doituong khác nil thì tiếp tục chạy nếu doituong là nil thì báo
là không có đối tượng nào và kết thúc lệnh:
-Hàm If là hàm điều kiện nếu như mà là thì. Cú pháp như sau:

(if (điều kiện 1) (PROGN

thì làm công tác 1


)
)
(IF (điều kiện 2) (PROGN
Thì làm công tác 2
)
)

*Các hàm so sánh:


< nhỏ hơn.
> lớn hơn.
<= nhỏ hơn hoặc bằng.
>= lớn hơn hoặc bằng.
= bằng.
/= không bằng.

Bây giờ áp dụng vào lisp trên để kiểm tra đối tượng chọn có giá trị hay không để đưa ra quyết
định kết thúc lệnh hay thực hiện lệnh.

(defun c:tlkt ()
(princ "\nChon doi tuong")
(Setq doituong (Ssget))
(if (= doituong nil) (PROGN
(princ "\nKhong tim thay doi tuong nao!")
)
)
(IF (/= doituong nil) (PROGN
(setq a (getpoint "\nChon diem goc: "))
(setq b (getpoint a"\nChon diem den: "))
(setq so (getreal "\nSo lan di chuyen: ")) 
By Ngọc Nguyễn 2013 Page 22 of 108

(setq daiab (distance a b)) 


(setq dodai (/ daiab so))
(setq gocab (angle a b)) 
(setq c (polar a gocab dodai)) 
(setq sol (fix so))
(repeat sol
(command "DELAY" "5000" "") 
(command ".MOVE" doituong "" a c)
)
)
)
(princ)
)

-Chạy lệnh:
+Chọn 1 vùng trống nào đó lisp sẽ kết thúc và báo: Khong tim thay doi tuong nao!.
+Chọn có đối tượng lisp sẽ thực hiện như lisp lúc nảy.
By Ngọc Nguyễn 2013 Page 23 of 108

Hướng dẩn viết lisp bài 18:

*Hàm If ứng dụng rất nhiều nhé bạn cần hết sức linh hoạt trong việc dùng nó để tạo tương tác
giữa người dùng với lisp.
-Quay tuốt lại cái lisp array cái vòng tròn nhé: Bây giờ sau khi chọn điểm a và b, vẽ đường thẳng
ab, vẽ đường tròn tâm c đường kính ab, vẽ đường tròn tâm a bán kính ab, thêm chức năng hỏi có
muốn array cái đường tròn này ra không nếu nói có thì array còn nói không thì kết thúc lệnh.

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2))) 
(command ".circle" c a)
(command ".circle" a b)
(setq traloi (strcase (getstring "\nBan co nuon array hay không? Y/N:")))
(if (= traloi "N") (PROGN
)
)
(IF (= traloi "Y") (PROGN
(setq sl (getstring "\nSo luong:"))
(command ".array" "last" "" "p" c sl "" "")
)
)

(princ)
)

Bạn để ý dòng (setq traloi (strcase (getstring "\nBan co nuon array hay không? Y/N:"))) dùng
hàm strcase trước hàm getstring để đảm bảo chuổi nhận được khi nhập vào luôn luôn là viết hoa
vì hàm if kiểm tra mình để kiểm tra giá trị traloi là viết hoa như vậy thì khi bạn nhập chử Y là
thường hay là hoa thì kết quả hàm if mới thực hiện việc array cái vòng tròn được.

*Đấy bây giờ bạn thấy mấy cái lisp giống lisp rồi đó nghen làm việc có trình tự lớp lang có hỏi
có trả lời đây là giao tiếp với lisp đó. Ngon hen!
By Ngọc Nguyễn 2013 Page 24 of 108

Hướng dẩn viết lisp bài 19:

Bây giờ sau khi thực hiện lisp bạn dùng lệnh undo sẽ thấy nó undo từng chút từng chút chứ
không giống lệnh của cad xíu nào vì trong lisp mình thực hiện một mớ lệnh nó sẽ từ từ undo từng
lệnh một. Việc này gây phiền phức nếu trong lisp mình dùng rất nhiều lệnh bạn muốn lisp undo
cũng giống như lệnh cad kìa. Cách làm như sau: Thêm hai dòng sau vào lisp.
+Thêm dòng sau vào sau dòng mở đầu:
(defund c:lenh ()
(command "undo" "be")
+Thêm dòng sau trước dòng kết thúc:
(command "undo" "end")
(Princ)
)

-Lúc này sau khi thực lisp bạn thực hiện lệnh undo nó sẽ undo nguyên tiến trình lisp thực hiện. 
-Từ đây trở đi sẽ kết nạp thêm hai dòng này vào phần mở đầu và kết thúc lisp nhé.
By Ngọc Nguyễn 2013 Page 25 of 108

Hướng dẩn viết lisp bài 20:

*Các lisp từ trước tới giờ nếu bạn chạy thử trên bản vẽ trống trơn thì chạy ngon nhưng bạn thử
chạy trên bản vẽ có nhiều đối tượng rồi thì sẽ có khi chạy không đúng vì khi thực hiện các lệnh
vẽ có chọn các điểm sẽ bị ảnh hưởng bởi chế độ bắt điểm tự động nên bắt sang các điểm không
đúng với tính toán dẩn đến các hình vẽ sẽ không đúng ý.
-Cách giải quyết là tắt chế độ bắt điểm tự động đi. Cú pháp như sau:
(setvar "osmode" 0)
-Nhưng người dùng lisp của mình sẽ bực mình vì khi dùng lisp của mình thì mình tắt mất bắt
điểm tự động của họ. Trong viết lisp việc thay đổi các thiết lập mặc định của người ta là không
nên. Giải pháp là lưu thiết lập của họ lại bằng 1 biến tạm sau đó trả lại họ. Cách làm như sau:
+Lưu bắt điểm tự động (setq luubatdiem (getvar "osmode"))
+Trả lại bắt điểm tự động (setvar "osmode" luubatdiem)
-Như vậy trong lisp sau khi đã cung cấp dử liệu đầu vào như bắt điểm mình tiến hành lưu bắt
điểm lại, tắt bắt điểm đi, thực hiện các thao tác vẽ, tính toán, trả lại bắt điểm trước khi kết thúc
lệnh.
Ví dụ lisp sau khi thêm phần undo và bắt điểm:
(defun c:doanthang ()
(command "undo" "be")
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)
(command ".line" a b "")
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2))) 
(command ".circle" c a)
(command ".circle" a b)
(setq traloi (strcase (getstring "\nBan co nuon array hay không? Y/:")))
(if (= traloi "N") (PROGN
)
)
(IF (= traloi "Y") (PROGN
(setq sl (getstring "\nSo luong:"))
(command ".array" "last" "" "p" c sl "" "")
)
)
(setvar "osmode" luubatdiem)
(command "undo" "end")
(princ)
)
By Ngọc Nguyễn 2013 Page 26 of 108

Hướng dẩn viết lisp bài 21:

*Đến lúc này kiến thức về lisp của bạn đã đủ để viết lisp đánh cos cao độ rồi. Mình làm mẫu để
bạn có thể quen dần với cách đặt và giải quyết vần đề bằng lisp nhé.
*Đặt vấn đề:
-Khi vẽ bạn có nhu cầu đánh cao độ cho các mặt đứng, mặt cắt. Cách thông thường là bạn có sẳn
cái BLOCK rồi chèn vào COPY để tại các vị trí cần thiết xong đo và sửa các gía trị của text cho
phù hợp. Cái phiền là bạn phải đo, tính theo tỉ lệ vẽ từ đó mới có giá trị điền vào các text, còn
phải thêm dấu phía trước giá trị text nửa. Ví dụ +3.600. 
-Giải quyết vấn đề bằng cách làm các công việc sau:
a/Tạo 1 BLOCK có tên caodo.dwg lưu vào thư mục nào đó (ở đây mình dùng
C:\tailieukythuat\dwg\caodo.dwg). Khi tạo Block này bạn nên tạo ở Layer 0 có màu là bylayer,
để khi chèn vào nó đi theo các thông số của layer hiện hành. Điểm chèn BLOCK nằm đúng mũi
tên của BLOCK.
b/Viết lisp với các chức năng sau:
+Hỏi 1 mét vẽ bằng bao nhiêu: (dùng getreal)
+Hỏi chọn điểm đánh cao độ: (dùng getpoint)
+Hỏi chọn cao độ 0.000: (dùng getpoint) lúc này lưu chế độ bắt điểm lại và gán chế độ bắt
điểm bằng 128 (bắt vuông góc).
+Chèn BLOCK caodo.dwg vào điểm đánh cao độ vừa chọn. Lúc này gán chế độ bắt điểm bằng
0.
+Tính toán tọa độ để viết text căn cứ vào tọa độ điểm vừa chèn.
+Đo khoảng cách từ điểm đánh cao độ đến điểm có cao độ 0.000.
+Chia khoảng cách đo được cho giá trị vẽ 1 mét.
+Làm tròn sau dấu phẩy là 3 chử số: (dùng rtos)
+Lấy giá trị y của điểm đánh cos trừ cho giá trị y của điểm cao độ 0.000
+Nếu giá trị này >0 thì gán dấu phía trước của text là dấu +.
+Nếu giá trị này <0 thì gán dấu phía trước của text là dấu -.
+Nếu giá trị này =0 thì gán dấu phía trước của text là dấu .
+Viết text gồm dấu phía trước và giá trị cao độ tại điểm vừa tính được.
-Dưới đây là hình minh họa về hình dáng BLOCK cao độ, các thông số về tọa độ viết text so với
điểm chèn, độ lớn text mình sử dụng trong đoạn lisp mẫu.

(defun c:cos ()
(command "undo" "be")
(setq motmet (getreal "\nMot met ban ve bang bao nhieu: ")) 
(setq luubatdiem (getvar "osmode"))
By Ngọc Nguyễn 2013 Page 27 of 108

(setq a (getpoint "\nChon diem muon danh cos: "))


(setvar "osmode" 128)
(setq b (getpoint a"\nChon cao do 0.000: "))
(setvar "osmode" 0)
(setq daiab (distance a b)) 
(setq giatri (/ daiab motmet))
(setq c (list (- (car a) 250) (+ (cadr a) 410)))
(setq trenduoi (- (cadr a) (cadr b)))
(if (= trenduoi 0) (PROGN
(setq dau "%%p ")
)
)
(if (> trenduoi 0) (PROGN
(setq dau "+ ")
)
)
(if (< trenduoi 0) (PROGN
(setq dau "- ")
)
)
(setq noidung (strcat dau (rtos giatri 2 3)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" c 250 0 noidung)
(command "INSERT" "c:\\tailieukythuat\\dwg\\caodo.dwg" a 1 1 0)
(setvar "osmode" luubatdiem)
(command "undo" "end")
(princ)
)

Bạn để ý dòng dùng INSERT block caodo.dwg nhé phần đường dẩn đến file phải dùng \\ để thể
hiện thư mục vì khi đọc lisp sẽ bỏ bớt một dấu \. Hoặc bạn thể hiện bằng dấu xẹt ngược cũng
được:
(command "INSERT" "c:\\tailieukythuat\\dwg\\caodo.dwg" a 1 1 0)
(command "INSERT" "c:/tailieukythuat/dwg/caodo.dwg" a 1 1 0)
By Ngọc Nguyễn 2013 Page 28 of 108

Hướng dẩn viết lisp bài 22:

Khi bạn thực hiện lisp trên nếu tại thư mục C:\tailieukythuat\dwg\ lại không tồn tại file
caodo.dwg thì sẽ xuất hiện lổi tại dòng insert, lisp báo ra 1 mớ lổi dòm không ưng xíu nào. Mình
nên kiểm tra file C:\tailieukythuat\dwg\caodo.dwg có tồn tại hay không. Nếu có thì thực hiện
lệnh nếu không thì thông báo không tìm thấy và bỏ qua câu lệnh insert.
-Hàm findfile sẽ giúp bạn kiểm tra file có tồn tại hay không, nếu không hàm trả về giá trị nil, Kết
hợp hàm if để đưa ra quyết định trong 2 trường hợp: tìm thấy và không tìm thấy

(defun c:cos ()
(command "undo" "be")
(setq motmet (getreal "\nMot met ban ve bang bao nhieu: ")) 
(setq luubatdiem (getvar "osmode"))
(setq a (getpoint "\nChon diem muon danh cos: "))
(setvar "osmode" 128)
(setq b (getpoint a"\nChon cao do 0.000: "))
(setvar "osmode" 0)
(setq daiab (distance a b)) 
(setq giatri (/ daiab motmet))
(setq c (list (- (car a) 250) (+ (cadr a) 410)))
(setq trenduoi (- (cadr a) (cadr b)))
(if (= trenduoi 0) (PROGN
(setq dau "%%p ")
)
)
(if (> trenduoi 0) (PROGN
(setq dau "+ ")
)
)
(if (< trenduoi 0) (PROGN
(setq dau "- ")
)
)
(setq noidung (strcat dau (rtos giatri 2 3)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" c 250 0 noidung)
(setq timfile (findfile "c:\\tailieukythuat\\dwg\\caodo.dwg"))
(if (= timfile nil) (PROGN
(princ "\nKhong tim thay file caodo.dwg")
)
By Ngọc Nguyễn 2013 Page 29 of 108

)
(if (/= timfile nil) (PROGN
(command "INSERT" "c:\\tailieukythuat\\dwg\\caodo.dwg" a 1 1 0)
)
)
(setvar "osmode" luubatdiem)
(command "undo" "end")
(princ)
)
By Ngọc Nguyễn 2013 Page 30 of 108

Hướng dẩn viết lisp bài 23:

Bài trước mình đã giới thiệu vòng lặp repeat là vòng lặp đơn giản nhất. Hôm nay mình giới thiệu
tiếp vòng lặp có điều kiện. Hàm WHILE.
-Cú pháp như sau:
(while (điều kiện)
(các thao tác lặp lại)
)
-Cách dùng đơn giản nhất như sau:
(while
(các thao tác lặp lại)
)
Đoạn trên có tác dụng nếu nhấn enter thì vòng lặp sẽ dừng lại nếu không các thao tác sẽ được lặp
lại. Ví dụ với lisp sau:
-Đây là lisp nguyên mẫu:
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(princ)
)
-Tác dụng hỏi chọn 2 điểm và vẽ đoạn thẳng qua 2 điểm, kết thúc lệnh. Bây giờ bạn muốn lisp
tiếp tục hỏi chọn điểm và tiếp tục vẽ đoạn thẳng khi nào nhấn enter thì kết thúc lệnh (giống lệnh
line của cad)

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(setq a b)
(while
(setq b (getpoint a"\nChon diem tiep theo : "))
(command ".line" a b "")
(setq a b)
)
(princ)
)
-Hai đoạn lisp trên mình tạm thời bỏ qua phần lưu bắt điểm và undo để bạn dể nhận ra sự thay
đổi.
-Bạn lưu ý dòng (setq a b) có tác dụng sau khi vẽ đoạn thẳng từ a tới b thì gán điểm b cho biến a
By Ngọc Nguyễn 2013 Page 31 of 108

lúc này điểm b trở thành điểm a sau đó chọn tiếp điểm b lại vẽ từ a tới b, lại gán b cho a cứ như
vậy. Khi bạn enter thì vòng lặp kết thúc, kết thúc lệnh.
-Tương tự bạn có thể sửa lại lisp đánh cos làm cho chọn được nhiều điểm đánh cao độ trong 1
lần gọi lệnh như sau:

(defun c:cos ()
(command "undo" "be")
(setq motmet (getreal "\nMot met ban ve bang bao nhieu: ")) 
(setq luubatdiem (getvar "osmode"))
(setq a (getpoint "\nChon diem muon danh cos: "))
(setvar "osmode" 128)
(setq b (getpoint a"\nChon cao do 0.000: "))
(setvar "osmode" 0)
(setq daiab (distance a b)) 
(setq giatri (/ daiab motmet))
(setq c (list (- (car a) 250) (+ (cadr a) 410)))
(setq trenduoi (- (cadr a) (cadr b)))
(if (= trenduoi 0) (PROGN
(setq dau "%%p ")
)
)
(if (> trenduoi 0) (PROGN
(setq dau "+ ")
)
)
(if (< trenduoi 0) (PROGN
(setq dau "- ")
)
)
(setq noidung (strcat dau (rtos giatri 2 3)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" c 250 0 noidung)
(setq timfile (findfile "c:\\tailieukythuat\\dwg\\caodo.dwg"))
(if (= timfile nil) (PROGN
(princ "\nKhong tim thay file caodo.dwg")
)
)
(if (/= timfile nil) (PROGN
(command "INSERT" "c:\\tailieukythuat\\dwg\\caodo.dwg" a 1 1 0)
)
)
By Ngọc Nguyễn 2013 Page 32 of 108

(setvar "osmode" luubatdiem)


(while
(setq a (getpoint b"\nChon diem muon danh cos : "))
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)
(setq daiab (distance a b)) 
(setq giatri (/ daiab motmet))
(setq c (list (- (car a) 250) (+ (cadr a) 410)))
(setq trenduoi (- (cadr a) (cadr b)))
(if (= trenduoi 0) (PROGN
(setq dau "%%p ")
)
)
(if (> trenduoi 0) (PROGN
(setq dau "+ ")
)
)
(if (< trenduoi 0) (PROGN
(setq dau "- ")
)
)
(setq noidung (strcat dau (rtos giatri 2 3)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" c 250 0 noidung)
(setq timfile (findfile "c:\\tailieukythuat\\dwg\\caodo.dwg"))
(if (= timfile nil) (PROGN
(princ "\nKhong tim thay file caodo.dwg")
)
)
(if (/= timfile nil) (PROGN
(command "INSERT" "c:\\tailieukythuat\\dwg\\caodo.dwg" a 1 1 0)
)
)
(setvar "osmode" luubatdiem)
)
(command "undo" "end")
(princ)
)
By Ngọc Nguyễn 2013 Page 33 of 108

Hướng dẩn viết lisp bài 24:

Nhìn cái lisp trên bạn sẽ thấy có hai đoạn nội dung giống y hệt nhau dẫn đến lisp quá dài. Cách
giải quyết: Cứ cái đoạn nào có nội dung giống nhau mà lại xuất hiện nhiều lần thì làm như sau:
(defun doanlap ()
Nội dung đoạn
)
Lưu ý sau defun không có c:
Sau đó cứ chổ nào cần nguyên cái đoạn đó chỉ cần thay bằng dòng
(doanlap) là được. Ví dụ lisp đánh cos sửa lại như sau:

(defun vonglapcos ()
(setvar "osmode" 0)
(setq daiab (distance a b)) 
(setq giatri (/ daiab motmet))
(setq c (list (- (car a) 250) (+ (cadr a) 410)))
(setq trenduoi (- (cadr a) (cadr b)))
(if (= trenduoi 0) (PROGN
(setq dau "%%p ")
)
)
(if (> trenduoi 0) (PROGN
(setq dau "+ ")
)
)
(if (< trenduoi 0) (PROGN
(setq dau "- ")
)
)
(setq noidung (strcat dau (rtos giatri 2 3)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" c 250 0 noidung)
(setq timfile (findfile "c:\\tailieukythuat\\dwg\\caodo.dwg"))
(if (= timfile nil) (PROGN
(princ "\nKhong tim thay file caodo.dwg")
)
)
(if (/= timfile nil) (PROGN
(command "INSERT" "c:\\tailieukythuat\\dwg\\caodo.dwg" a 1 1 0)
By Ngọc Nguyễn 2013 Page 34 of 108

)
)
(setvar "osmode" luubatdiem)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:cos ()
(command "undo" "be")
(setq motmet (getreal "\nMot met ban ve bang bao nhieu: ")) 
(setq luubatdiem (getvar "osmode"))
(setq a (getpoint "\nChon diem muon danh cos: "))
(setvar "osmode" 128)
(setq b (getpoint a"\nChon cao do 0.000: "))
(Vonglapcos)
(while
(setq a (getpoint b"\nChon diem muon danh cos : "))
(setq luubatdiem (getvar "osmode"))
(Vonglapcos)
)
(command "undo" "end")
(princ)
)
By Ngọc Nguyễn 2013 Page 35 of 108

Hướng dẩn viết lisp bài 25:

Có nhiều trường hợp bạn cần làm việc với một vài file để phục vụ 1 nhu cầu nào đó của lisp.
Giới thiệu các hàm liên quan:
*Hàm getfiled làm xuất hiện hộp thoại chọn file Cú pháp:
(getfiled tieude tenfile duoi kieu) trong đó:
-tieude: là nội dung dòng chử xuất hiện trên tiêu đề hộp thoại.
-tenfile: là tên file hoặc đường dẩn mặc định xuất hiện sẵn trong hộp thoại.
-duoi: là phẩn mở rộng của file.
-kieu: là kiểu hộp thoại open hay save:
+1: Hộp thoại save.
+8: Hộp thoại open.
-Lưu ý các thông số trên điều phải được xác định, tham số nào không sử dụng phải gán cho nó
giá trị rổng "".
-Dù hộp thoại là save hay open thì kết quả của hàm getfiled là một chuổi dạng đường dẩn, làm gì
với nó do mình quyết định.
-Ví dụ: Lisp chọn 1 file để insert vào bản vẽ:

(defun c:chen ()
(command "undo" "be")
(setq filechen (getfiled "Chon flie de chen" "" "dwg" 8))
(setq a (getpoint "\nChon diem chen: "))
(command "INSERT" filechen a 1 1 0)
(command "undo" "end")
(princ)
)
By Ngọc Nguyễn 2013 Page 36 of 108

Hướng dẩn viết lisp bài 26:

Sau khi có đường dẩn 1 file thì có thể làm rất nhiều việc với nó: Ví dụ copy, delete .v.v. Mình có
thể thực hiện các lệnh dos từ dòng lệnh lisp bằng cách gọi lệnh shell trước khi gọi lệnh dos.
Để chắc ăn có 1 số bạn trẻ bây giờ không học dos như lớp già tụi mình hồi xưa mình đưa ra 1 số
ví dụ dùng lệnh dos để các bạn tham khảo:
1/Tạo thư mục tailieukythuat trong ổ đĩa c
(command "SHELL" "MD C:\\tailieukythuat" )
2/Copy file duy.txt trong thư mục D:\\tailieukythuat vào thư mục C:\\tailieukythuat
(command "SHELL" "copy D:\\tailieukythuat\\duy.txt C:\\tailieukythuat" )
3/Copy tất cả các file trong thư mục D:\\tailieukythuat vào thư mục C:\\tailieukythuat
(command "SHELL" "copy D:\\tailieukythuat\\*.* C:\\tailieukythuat" )
4/Copy file duy.txt trong thư mục D:\\tailieukythuat vào thư mục hiện hành của cad
(command "SHELL" "copy D:\\tailieukythuat\\duy.txt " )
5/Copy tất cả các file trong thư mục D:\\tailieukythuat vào thư mục hiện hành của cad
(command "SHELL" "copy D:\\tailieukythuat\\*.* " )
6/Xóa file duy.txt trong thư mục D:\\tailieukythuat 
(command "SHELL" "del D:\\tailieukythuat\\duy.txt" )
7/Xóa tất cả các file trong thư mục D:\\tailieukythuat 
(command "SHELL" "del D:\\tailieukythuat\\*.*" )

Đấy ứng dụng lệnh dos vào lisp chủ yếu để tạo thư mục, copy file, xóa file. Có 1 cái hạn chế là
không xóa thư mục được nhưng bây nhiêu là đủ dùng rồi.
By Ngọc Nguyễn 2013 Page 37 of 108

Hướng dẩn viết lisp bài 27:

*Đọc dữ liệu từ file txt. Gồm 3 bước:


-Mở file (hàm open).
-Đọc dữ liệu từ file (hàm read-line).
-Đóng file (hàm close)

*Viết dữ liệu vào file txt. Gồm 3 bước:


-Mở file (hàm open).
-Viết dữ liệu vào file (hàm write-line). 
-Đóng file (hàm close)

*Hàm Open dùng mở 1 file để đọc hoặc viết dữ liệu vào file. Cú pháp:
(open tenfile kieumo) trong đó:
-tenfile: là đường dẩn đầy đủ của file. Ví dụ “D:\\tailieukythuat\\duy.txt”
-kieumo: là ký tự viết thường “a” “r” “w” dùng xác định kiểu mở file:
+”a” mở file tenfile để chép dữ liệu nối tiếp vào cuối file. Nếu tìm thấy file con trỏ nằm cuối file,
dữ liệu chép vào sẽ nối vào cuối file. Nếu không tìm thấy file tenfile sẽ được tạo mới, con trỏ
nằm đầu file.
+”r” mở file tenfile để đọc dữ liệu. Con trỏ nằm tại vị trí dòng đầu tiên của file. Nếu không tìm
thấy file này hàm trả về nil.
+”w” mở file tenfile để chép dữ liệu vào file này. Nếu tìm thấy dữ liệu trong file sẽ bị chép đè
lên. Nếu không tìm thấy file tenfile sẽ được tạo mới, con trỏ nằm đầu file.

*Khi open 1 file bạn cấp cho nó 1 tên đại diện. Nhớ rằng file phải được đóng bằng hàm close
trước khi thoát khỏi acad nếu không file có nguy cơ bị văng đi đâu đó không tìm ra.

-Ví dụ mở file C:\\tailieukythuat\\duy.txt viết dòng tailieukythuat.com và đóng file lại như sau:

(setq tenfile (open “C:\\tailieukythuat\\duy.txt” “a”))


(setq noidungviet “tailieukythuat.com”)
(write-line noidungviet tenfile)
(close tenfile)

-Ví dụ mở file C:\\tailieukythuat\\duy.txt đọc dòng dầu tiên và đóng file lại như sau:

(setq tenfile (open “C:\\tailieukythuat\\duy.txt” “r”))


(setq noidungdoc (read-line tenfile))
(close tenfile)
By Ngọc Nguyễn 2013 Page 38 of 108

-Lưu ý khi thực hiện xong hàm read-line thì con trỏ sẽ nhảy xuống dòng kế tiếp nên muốn đọc
nội dung dòng thứ n của file C:\\tailieukythuat\\duy.txt thì mình dùng hàm repeat n lần với dòng
(setq noidungdoc (read-line tenfile)). Ví dụ đọc dòng thứ 3 và gán cho biến noidungdoc:

(setq tenfile (open “C:\\tailieukythuat\\duy.txt” “r”))


(repeat 3
(setq noidungdoc (read-line tenfile))
)
(close tenfile)
By Ngọc Nguyễn 2013 Page 39 of 108

Hướng dẩn viết lisp bài 28:

*Trong khi viết lisp đôi khi có các dữ liệu nhập vào lặp lại cứ mỗi lần lisp hỏi lại phải nhập vào.
Cách hay hơn là dữ liệu nào nhập vào rồi thì ghi nhớ lại cho lần sau nếu cần giá trị khác thì nhập
vào còn nếu vẫn dùng giá trị cũ thì chỉ cần enter là có giá trị cũ để dùng.
-Sau đây là đoạn lisp giúp cho bạn có thêm 2 hàm có tác dụng lưu giữ giá trị nhập vào. Mình tìm
thấy nó trong 1 đĩa cd ko biết rỏ tác giả và cũng không tìm hiểu cách làm việc của nó cứ biết tác
dụng và ứng dụng vào công việc thôi. Bạn cũng vậy nhé cứ lưu đoạn này lại sau đó dùng theo
cách mình hướng dẩn.

;---------------------------------------
(defun nstr (stri def)
(princ stri)
(princ "<")
(princ " ")
(princ def)
(princ ">")
(princ ":")
(princ " ")
);defun nstr
;--------------------
(defun nstr1 (stri)
(princ stri)
(princ "<")
(princ "Nhap vao")
(princ ">")
(princ ":")
(princ " ")
);defun nstr1
;---------------------
(defun nint (prompt def / temp)
(if def
(setq temp (getint (nstr prompt def)))
(setq def (getint (nstr1 prompt)))
);if def
(if temp
(setq def temp)
def
);if temp
);defun nint
By Ngọc Nguyễn 2013 Page 40 of 108

;---------------------
(defun dnint (prompt def / temp)
(if def
(setq temp (getreal (nstr prompt def)))
(setq def (getreal (nstr1 prompt)))
);if def
(if temp
(setq def temp)
def
);if temp
);defun nint
;--------------------
(defun ndist (po prompt def / temp) ;nhan kh/cach va luu gia tri mac dinh
(if def
(setq temp (getdist po (nstr prompt def)))
(setq def (getdist po (nstr1 prompt)))
)if def
(if temp
(setq def temp)
def
);if temp
);defun ndist
;-----------------------------------

Cách dùng:
-Hàm ndint: lưu giữ giá trị số. Giá trị số này được nhập từ bàn phím.

(setq giatri (dnint "\nTi le chinh "giatri1))


(setq giatri1 giatri)

Ví dụ đoạn lisp scale với tỉ lệ scale được lưu lại.

(Defun c:sclt (a)


(command "undo" "be")
(Prompt "\nChon doi tuong muon chinh ti le")
(setq dtthu (ssget))
(setq a (getpoint "\nChon tam phong: "))
(setq tilechinh (dnint "\nTi le chinh "tiledchinh1))
(setq tiledchinh1 tilechinh)
(command "scale" dtthu "" (list (car a)(cadr a)) tilechinh)
(command "undo" "end")
By Ngọc Nguyễn 2013 Page 41 of 108

(Prin I)
)

*Cách dùng:
-Hàm ndist: lưu giữ giá trị khoảng cách. Giá trị này được chuyễn thành số, giá trị này có thể
được nhập từ bàn phím.

(setq giatri (ndist a "\nDo cao khoi muon ve "giatri1))


(setq giatri1 giatri) 
Trong đó a là điểm đã được xác định.
Ví dụ đoạn lisp vẽ box với cao độ khối được lưu lại.

(Defun c:khoi (a)


(command "undo" "be")
(setq a (getpoint "\nDiem thu nhat:"))
(setq b (getcorner a"\nDiem thu hai: ")) 
(setq dckhoive (ndist a "\nDo cao khoi muon ve "cckhoive1))
(setq cckhoive1 dckhoive)
(command "box" (list (car a) (cadr a) (caddr a)) (list (car b) (cadr b) (caddr b)) dckhoive)
(command "undo" "end")
(Prin I)
)

Bạn lưu ý đoạn định nghĩa hai hàm này chỉ cần load lên 1 lần trong 1 phiên làm việc thì các lisp
có dùng 2 hàm này điều chạy được cả nhé.
By Ngọc Nguyễn 2013 Page 42 of 108

Hướng dẩn viết lisp bài 29:

Một chức năng hay của lisp là có thể thao tác lặp lại một vài thao tác trên từng đối tượng của tập
hợp chọn.
Ứng dụng vòng lặp While.
Ví dụ bạn có tập hợp tapdoituong gồm các text hình thành từ 
(setq tapdoituong (ssget '((0 . "text"))))
Bây giờ bạn muốn vẽ 1 hình tròn tâm tại điểm chèn text bán kính 100.
Việc vẽ 1 hình tròn bằng lisp khi biết tâm và bán kính bằng lisp thì đơn giản rồi.
(command "circle" diemve 100)
Vấn đề là làm lần lượt cho từng text trong cả tập hợp chọn.
Dùng hàm sslength để lấy ra số lượng đối tượng trong tập hợp chọn 
(setq sodoituong (sslength tapdoituong))
Hàm ssname lấy ra đối tượng thứ thutu trong tập hợp tapdoituong
(setq doituong (ssname tapdoituong thutu))
Đầu tiên cho thutu = 0 sau đó áp dụng vòng lặp While với điều kiện thutu< sodoituong, cuối
vòng lặp cho thutu = thutu+1 đến khi thutu= sodoituong thì vòng lặp sẽ dừng lại.

Đoạn lisp như sau:


(defun c:vht ()
(command "undo" "be")
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)

(Princ "\nChon cac text :")


(setq tapdoituong (ssget '((0 . "text"))))
(setq thutu 0)
(setq sodoituong (sslength tapdoituong))

(while (< thutu sodoituong)


(setq doituong (ssname tapdoituong thutu))
(setq laynoidung (entget doituong))
(setq diemve (cdr (assoc 10 laynoidung)))
(command "circle" diemve 100)
(setq thutu (+ thutu 1))
)
(command "undo" "end")
(setvar "osmode" luubatdiem)
(Princ)
)
By Ngọc Nguyễn 2013 Page 43 of 108

Bạn chạy thử lisp này chọn các text nó sẽ vẽ các hình tròn vào điểm chèn của từng text.
Đoạn sau giúp lấy ra điểm chèn của text:
(setq laynoidung (entget doituong))
(setq diemve (cdr (assoc 10 laynoidung)))
Bài sau mình sẽ nói về cách lấy các thông tin về đối tượng cad bằng lisp, có bao hàm cả hai dòng
trên. Bài này bạn chấp nhận nó đã nhé.
*Để thực hành mình ra 1 đề bài bạn viết thử nhé.
Viết lisp hỏi chọn các text, hỏi chọn điểm canh lề, move các text được chọn sao cho điểm canh lề
của text thẳng hàng theo phương thẳng đứng.
*Gợi ý:
-Cơ bản đoạn lisp như trên. 
-Sau khi chọn đối tượng thêm phần hỏi chọn điểm canh lề. (diemchuan)
-Sau khi lấy được điểm canh lề text (trường hợp này là diemve). Bỏ dòng vẽ hình tròn mà thay
bằng dòng move.
-Move từng text từ điểm canh lề (diemve) đến điểm mới. Điểm mới xác định bằng cách lấy giá
trị x của diemchuan và y của diemve.
*Sẽ có đáp án trong bài tới.
By Ngọc Nguyễn 2013 Page 44 of 108

Hướng dẩn viết lisp bài 30:

Đáp án đây. Hy vọng bạn đã hoàn thành giống như sau:

(defun c:vht ()
(command "undo" "be")
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)

(Princ "\nChon cac text :")


(setq tapdoituong (ssget '((0 . "text"))))
(setq diemchuan (getpoint "\nChon diem canh le: "))
(setq thutu 0)
(setq sodoituong (sslength tapdoituong))

(while (< thutu sodoituong)


(setq doituong (ssname tapdoituong thutu))
(setq laynoidung (entget doituong))
(setq diemve (cdr (assoc 10 laynoidung)))

(setq xmoi (car diemchuan))


(setq ymoi (cadr diemve))
(setq diemmoi (list xmoi ymoi))

(command "move" doituong "" diemve diemmoi)


(setq thutu (+ thutu 1))
)
(command "undo" "end")
(setvar "osmode" luubatdiem)
(Princ)
)

**Sau đây mình nói về cách lấy thông tin của đối tượng bằng lisp:
Giả sử rằng bạn có đối tượng (doituong) bạn có được bằng cách nào thì tùy. Muốn lấy thông tin
từ nó bạn phải làm việc giống như là mở cửa bước vào trong phòng. Dùng hàm enteget:
(setq laynoidung (entget doituong))
Khi đã vào phòng thì có nhiều thứ để lấy. Mổi thông tin của đối tượng có 1 con số đại diện ví dụ
điểm canh lề thứ nhất của text là số 10. Dùng hàm cdr và assoc sẽ lấy được thông tin tương ứng
với con số đó.
By Ngọc Nguyễn 2013 Page 45 of 108

(setq diemve (cdr (assoc 10 laynoidung)))


Mình sẽ gỏ lại bảng các số đại diện như từ điển bạn cần thông số gì thì vào tra nhé. (Một vài cái
hay dùng thôi chứ nhiều lắm mình gỏ không nổi, bạn mua sách về lisp sẽ có bảng này).

CHUNG:
Layer của đối tượng: 8
Kiểu của đối tượng: 0
Màu của đối tượng: 62
Tên dạng đường: 6

TEXT:
Nội dung text: 1
Độ lớn text: 40
Style: 7
Điểm canh lề thứ nhất: 10

BLOCK: (INSERT) Lưu ý block thì trong từ điển của cad là đối tượng INSERT
Tên BLOCK: 2
Điểm chèn: 10
Góc quay: 50
Tỉ lệ theo trục X: 41
Tỉ lệ theo trục Y: 42
Tỉ lệ theo trục Z: 43

LINE:
Điểm đầu: 10
Điểm cuối: 11

CIRCLE:
Tọa độ tâm: 10
Bán kính: 40

PLINE: (LWPOLYLINE)
Độ rộng: 43
Số lượng đỉnh: 90

DIMENSION:
Style: 3

Vậy cách lấy thông tin text như sau:


By Ngọc Nguyễn 2013 Page 46 of 108

Nội dung text: (setq noidung (cdr (assoc 1 laynoidung)))


Độ lớn text: (setq dolon (cdr (assoc 40 laynoidung)))
Style: (setq style (cdr (assoc 7 laynoidung)))
Điểm canh lề thứ nhất: (setq diemve (cdr (assoc 10 laynoidung)))
By Ngọc Nguyễn 2013 Page 47 of 108

TRÒ CHOI XEP HINH


Lưu bắt điểm tự động : 
(setq luubatdiem (getvar "osmode"))

Trả lại bắt điểm tự động: 


(setvar "osmode" luubatdiem)

Lưu tên layer hiện hành : 


(setq luulayer (getvar "clayer"))

Trả lại layer hiện hành : 


(setvar "clayer" luulayer)

Lưu bán kính lệnh fillet hiện hành : 


(setq luubankinh (getvar "filletrad"))

Trả lại bán kính lệnh fillet hiện hành : 


(setvar "filletrad" luubankinh)

Lưu kiểu chử hiện hành : 


(setq luukieuchu (getvar "TEXTSTYLE"))

Trả lại kiểu chử hiện hành : 


(setvar "TEXTSTYLE" luukieuchu)

Đoạn chọn điểm a bằng clik chuột trái:


(setq a (getpoint "\nChon diem: "))

Đoạn chọn điểm b bằng clik chuột trái có đường dẩn hướng nối với điểm a:
(setq b (getpoint a"\nChon diem: "))

Đoạn lấy khoảng cách từ a đến b:


(setq daiab (distance a b)) 
Đoạn lấy góc mà đoạn ab tạo với trục x: (giá trị thu được là radian)
(setq gocab (angle a b)) 

Đoạn đổi giá trị góc từ radian sang độ:


(setq gocdo (* 180 (/ gocradian pi)))

Đoạn vẽ line từ a tới b:


By Ngọc Nguyễn 2013 Page 48 of 108

(command ".line" a b "")

Đoạn vẽ circle tâm a bán kính a b:


(command ".circle" a b)

Đoạn chọn 1 nhóm đối tượng lưu thành biến doituong:


(setq doituong (ssget))

Đoạn chọn 1 nhóm đối tượng bằng cách chọn pline bao quanh lưu thành biến doituong:
(setq plst (acet-geom-vertex-list (car (entsel "\n Chon pline gioi han"))))
(setq doituong (ssget "wp" plst))

Đoạn move nhóm đối tượng doituong từ a tới b:


(command ".move" doituong "" a b)

Đoạn move nhóm đối tượng vừa chọn trước đó từ a tới b:


(command ".move" "previous" "" a b)

Đoạn move đối tượng vừa được tạo mới nhất từ a tới b:
(command ".move" "last" "" a b)

Đoạn làm xuất hiện bảng chọn color của cad và trả về giá trị mau là số từ 1 đến 225.
(princ "\nChon mau lop :")(setq mau (acad_colordlg 7))

Đoạn lưu giá trị là số: Biến kết quả để dùng là biến giatri
(if (= giatri nil)
(setq giatri1 5.0)
(setq giatri1 giatri)
)
(setq giatri (GETREAL (strcat "\nNhap so can luu: <" (rtos giatri1 2 2) ">")))
(if (= giatri nil)
(setq giatri giatri1)
)

Đoạn lưu kết quả là chử: Biến kết quả để dùng là giatric
(if (= giatric nil)
(setq giatric1 "mau")
(setq giatric1 giatric)
)
(setq giatric (GETSTRING (strcat "\nNhap chu can luu: <" giatric1 ">")))
(if (= giatric "")
By Ngọc Nguyễn 2013 Page 49 of 108

(setq giatric giatric1)


)

Mới học được đoạn lưu số và chử coi bộ ngắn hơn chút nửa:
-Lưu giá trị số
(or gtso (setq gtso 180))
(setq gtso (cond ((getreal (strcat "\nNhap so < " (rtos gtso 2 2) " >:")))(gtso)))

-Lưu giá trị chuổi


(or gtchuoi (setq gtchuoi "noidung"))
(setq gtchuoi (cond ((getstring (strcat "\nNhap chu < " gtchuoi " >:")))(gtchuoi)))
By Ngọc Nguyễn 2013 Page 50 of 108

Cách làm 1 bộ lisp di động.

*Bạn có trong tay một bộ lisp ưng ý và dùng đã quen. Đôi lúc bạn ngồi 1 máy khác cảm thấy rất
bất tiện, cài lisp của mình vào thì sợ ảnh hưởng đến người khác.
*Mình cũng bị tình trạng này và đến nay đã tìm ra cách giải quyết nên khoe với mọi người. Cách
này mình gọi là lisp di động.
-Nhiều bạn sẽ nghỉ lisp thì để đâu cũng không quan trọng chỉ cần load lên thôi có gì phải tinh
vi,,,,,,,,,,, Vấn đề là lisp nhiều khi không đơn thuần chỉ là các file lisp mà còn rất nhiều thứ kèm
theo ví dụ:
+File dwg dùng chèn vào phục vụ nhu cầu nào đó của lisp.
+File dcl dùng hiển thị hộp thoại.
+Các file sld dùng cho hộp thoại và các mục đích trang trí, minh họa khác.
Nói chung là có rất nhiều loại file kèm theo cần phải dùng trong ứng dụng lisp.

-Thông thường người viết lisp có hai cách ứng xử với các file này:
+Chỉ đích danh file với đầy đủ đường dẩn ví dụ:
(command ".INSERT" "C:\\tienich\\dwg\\cott.dwg" (list (car a)(cadr a)) 1 1 0)
+Chỉ tên file không có đường dẩn và tạo Support File Search Path đến thư mục chứa file ví dụ:
(command ".INSERT" "cott.dwg" (list (car a)(cadr a)) 1 1 0)
Và Add thư mục C:\\tienich\\dwg\\ vào Support File Search Path.
-Cả hai trường hợp trên phù hợp khi lisp nằm cố định trên máy. Bây giờ bạn chép tất cả vào CD
hoặc USB để đem nó đi máy khác thì đường dẩn sẽ không còn ổn định (mổi máy mổi khác) Tôi
xin trình bày cách mà tôi áp dụng cho ứng dụng lisp của mình như sau:

-Tổ chức một thư mục tổng (tôi đặt tên tienich).Bên trong là các thư mục con theo từng loại file
(để dể kiểm soát) ví dụ tôi đặt như sau:
+DWG
+DCL
+LENH
+FLIEHETHONG
-Tạo 1 file bất kỳ tốt nhất nên là file có định dạng đặt biệt chút cho đở nhầm lẩn (trường hợp của
tôi là fileDUY.ICO). Đặt file này trong thư mục tổng ví dụ: tienich\\duy.ico. Tác dụng của file
này tôi sẽ trình bày phía dưới.
-Cải tạo tất cả các dòng trong lisp có liên quan đến file bên ngoài như sau:

(start_image "img_1")
(slide_image 0 0 (dimx_tile "img_1")(dimy_tile "img_1") (strcat odiachay
"\\tienich\\dcl\\lgoduy.sld"))
(end_image)
By Ngọc Nguyễn 2013 Page 51 of 108

(setq DCL_ID (load_dialog (strcat odiachay "\\tienich\\dcl\\VEKHOIDAC.DCL")))

(command "INSERT" (strcat odiachay "\\tienich\\dwg\\cos") (list (car p0cos)(cadr p0cos)) 1 1 0)


Nghĩa là cần phải xác định biến odiachay thì các dường dẩn đến file mới hoàn thiện.
-Tạo file lisp để khi load lên sẽ làm tất cả các bước sau:
+Xác định biến odiachay.
+Load tất cả các file lsp cần load.
Nội dung như sau:

(setq vitrifilekiemtraduongdan (getfiled "DE XAC DINH DUONG DAN BAN HAY CHON
FILE DUY.ICON " "" "ico" 0))
(setq dodaiduongdantienichdocduoc (strlen vitrifilekiemtraduongdan))
(setq dodaiduongdantienichdocduoctru (- dodaiduongdantienichdocduoc 16))
(setq tenodiachay (substr vitrifilekiemtraduongdan 1 dodaiduongdantienichdocduoctru))
(setq odiachay tenodiachay)
(load(strcat odiachay "/tienich/lenh/thuvienndung"))
(load(strcat odiachay "/tienich/lenh/thuvienchitiet"))
(load(strcat odiachay "/tienich/lenh/tienichchonht"))
(load(strcat odiachay "/tienich/lenh/thongke"))

Phần màu xanh dùng để load các file lisp.


Phần màu cam dùng xác định biến odiachay cách làm việc như sau:
+Hiển thị hộp thoại open file với tiêu đề DE XAC DINH DUONG DAN BAN HAY CHON
FILE DUY.ICON, định dạng file mặc định là file *.ico.
+Đọc ra đường dẩn đầy đủ của file DUY.ICO.
+Đếm số ký tự trong chuổi vừa thu được.
+Trừ số ký tự đi 16 (là số ký tự của chuỗi tienich\\duy.ico).
+Lấy giá ra chuỗi con của chuổi tên file đầy đủ từ vị trí đầu tiên đến vị trí thứ đã trừ đi 16.
Giá trị này chính là biến odiachay.

*Tất nhiên có nhiều cách hay hơn để làm việc lisp di động này nhưng mình làm được như vậy và
dùng thấy rất ổn nên giới thiệu lên đây mong giúp được cho nhửng bạn đang bị vướng vấn đề
như mình.
By Ngọc Nguyễn 2013 Page 52 of 108

Hướng dẩn viết DCL bài mở đầu:

Đến đây phần lisp coi như tạm đủ dùng, về cơ bản thì bây nhiêu đó nắm vững và ứng dụng linh
hoạt thì làm được ối chuyện. Phần hổ trợ thêm cho lisp mà gần gủi nhất là hộp thoại: Cái này chủ
yếu giải quyết khâu oai và màu mè. Kiến thức này của mình cũng ít nhưng cũng mạnh dạn làm
vài bài giúp các bạn có khái niệm cơ bản để có thể tự nghiên cứu chuyên thêm tuỳ vào khả năng
của mỗi người.

**Chương trình dùng viết hộp thoại: Tất cả các chương trình soạn thảo văn bản. Mình vẫn dùng
notepad. Lưu nó ra định dạng *.DCL là được.
**Trong 1 file *.DCL có thể chứa nhiều hộp thoại trong đó:
-Mở đầu bằng
tenhopthoai : dialog {
label = "noidungtieude";
-Kết thúc bằng
}

-Trong đó:
+ tenhopthoai là tên lisp dùng để gọi hộp thoại này (lưu ý đặt tên khác nhau cho các hộp thoại và
viết liên tục không khoảng cách)
+ Noidungtieude là nội dung hiển thị phía trên của hộp thoại (Cái này ưng viết sao cũng được có
thể có khoảng cách chủ yếu dùng báo tên hoặc chức năng hộp thoại này. Muốn bỏ trống thì label
= " ";

**Số dấu { và } trong 1 định nghĩa hộp thoại là bằng nhau.


**Hộp thoại chỉ là cái vỏ còn nội dung bên trong, hoạt động thế nào là do lisp quyết định. Trước
tiên cứ thiết kế hộp thoại cho ưng ý cái đã, từ từ tính tới nội dung.
*Mẹo: khi viết xong hộp thoại muốn nghía xem nó như nào mà chưa cần viết lisp để gọi hắn lên
thì bạn làm như sau:

-Khởi động cad.


-Vào Tools => Autolisp => Visual lisp editor. Nó khở động lên chương trình.
-Bạn vào File => Open và open cái file *.DCL muốn nghía lên.
-Vào Tools => Inter face tools => Preview DCL Editor. Nó sẽ hiện cái hộp thoại lên cho bạn
xem trước.
By Ngọc Nguyễn 2013 Page 53 of 108

**Mọi hộp thoại ít nhất phải có 1 nút dùng thoát khỏi hộp thoại mà ko thực hiện chức năng nào
như sau.
:button {
label = "Cancel";
key = "Cancel";
is_cancel = true;
}

**Bắt đầu là thủ tục để có 1 nút nhấn cho hộp thoại.

:button {
label = "Ten nut 1";
width = 0;
key = "btn_bieuthuc1";
}

Vậy hộp thoại đơn giản như sau:

tenhopthoai : dialog {
label = "noidungtieude";

:button {
label = "Cancel";
key = "Cancel";
is_cancel = true;
}

}
By Ngọc Nguyễn 2013 Page 54 of 108

Hình dáng như sau:

Hộp thoại này chỉ có duy nhất nút thoát khỏi hộp thoại. Kết hợp thêm 1 nút nửa để làm việc khác
như sau:

tenhopthoai : dialog {
label = "noidungtieude"; 

:button {
label = "Ten nut 1";
width = 0;
key = "btn_bieuthuc1";
}

:button {
label = "Cancel";
key = "Cancel";
is_cancel = true;
}

Hình dáng như sau:

Khi không nói gì thì các nội dung trong hộp thoại sẽ xếp từ trên xuống dưới. Muốn sắp xếp lại
thì dùng 2 cú pháp sắp sếp ( xem bài sau).
By Ngọc Nguyễn 2013 Page 55 of 108

Tạo PLINE trong lisp:

Vấn đề vướng khó chịu nhất của bà con (kể cả mình) khi viết lisp là làm việc với pline: 
-Trường hợp đơn giản nhất là vẽ 1 pline với số đỉnh bất kỳ sau đó lấy giá trị diện tích của nó
miễn cưỡng lắm thì viết như sau:
(DEFUN c:dtpl ( )
(setq a (getpoint "\nChon diem dau tien: "))
(setq b (getpoint a"\nChon diem tiep theo: "))
(command "pline" a b "")
(setq plhoinay (entlast))
(setq a b)
(while (setq b (getpoint a"\nChon diem tiep theo : ")) 
(command "pline" a b "")
(command "pedit" "m" "L" plhoinay "" "j" "0" "")
(setq plhoinay (entlast))
(setq a b)
)
(command "pedit" plhoinay "c" "")
(command "area" "object" "last")
(setq dientich (getvar "area"))
(alert (rtos dientich 2 2))
(princ)
)

Giải thích lisp trên như sau:

(setq a (getpoint "\nChon diem dau tien: "))


Hỏi chọn 1 điểm trên màn hình và gán cho biến a
(setq b (getpoint a"\nChon diem tiep theo: "))
Hỏi chọn 1 điểm trên màn hình và gán cho biến b
(command "pline" a b "")
Thực hiện lệnh pline vẽ từ a đến b, kết thúc lệnh pline
(setq plhoinay (entlast))
Gán pl vừa tạo cho biến hoinay
(setq a b)
Gán điểm b hiện tại thành điểm a
(while (setq b (getpoint a"\nChon diem tiep theo : "))
Khởi động vòng lặp tồn tại khi điều kiện biến điểm b được gán bằng pick điểm, nếu enter thì kết
thúc vòng lặp
(command "pline" a b "")
By Ngọc Nguyễn 2013 Page 56 of 108

Thực hiện lệnh pline vẽ từ a đến b, kết thúc lệnh pline.......lưu ý lúc này điểm a chính là điểm b
của đoạn trên đã được gán qua nhé
(command "pedit" "m" "L" plhoinay "" "j" "0" "")
Thực hiện lệnh pedit lựa chọn m, chọn pline vừa tạo, chọn pline tạo trong đoạn trước đã gán
cho biến plhoinay, chọn J để nối thành 1 pline liên tục
(setq plhoinay (entlast))
Gán pl vừa tạo cho biến hoinay
(setq a b)
Gán điểm b hiện tại thành điểm a
)
kết thúc vòng lặp nếu nhấn enter, lúc này sản phẩm là 1 đường pline hở
Đoạn bên dưới là thủ tục đóng kín pline và lấy giá trị diện tích và báo ra kết quả. Nhưng nếu
vùng muốn tính diện tích chứa cả cung tròn thì việt viết nhại theo lệnh pline là rất khó khăn và
cuối cùng mình cũng tìm ra giải pháp bắng cách lisp trả hẳn về cad thực hiện xong lệnh pline
xong thì lisp tiếp tục chạy.
By Ngọc Nguyễn 2013 Page 57 of 108

Hàm con: Tạo, gán gọi hộp thoại.

Bắt đầu loạt bài về tạo các hàm con và ứng dụng theo kiểu không giống ai của Du782006. Hôm
nay là loạt các hàm tạo, gán gọi hộp thoại.

(defun c:ght ()
(duy:vht_modau "Hop thoai thu nghiem")
(duy:vht_modaucotbao "Test thu cac chuc nang")
(duy:vht_dongtextg "Ung dung ham con:")
(duy:vht_dongtext "Tao, gan thao tac cho hop thoai")
(duy:vht_dongtext "bang aultolisp")
(duy:vht_ketthuccothang)
(duy:vht_modauhangbao "cac nut")
(duy:vht_nut "Ve circle" "tacdung1" "0")
(duy:vht_nut "Ve line" "tacdung2" "0")
(duy:vht_ketthuccothang)
(duy:vht_ketthuc "x" "---o0o-duy782006-o0o---")
(duy:vht_goihopthoai)
)

-Đoạn lisp trên sẽ phụ trách việc tạo gán, gọi làm cho xuất hiện hộp thoại như trên, nghĩa là gán
luôn chức năng khi nhấn vào nút sẽ thực hiện thao tác luôn. Tạm thời mình chỉ mới viết cho xuất
hiện các text, nà nút gọi lệnh các thứ khác sẽ từ từ làm tiếp.
-Cách ứng dụng:

A. Một hộp thoại tối thiểu sẽ có tên hộp thoại. 1 nút dùng thoát hộp thoại. Ở đây mình cung cấp
hàm duy:vht_modau và duy:vht_ket thuc chỉ cần 2 hàm này sẽ có 1 hộp thoại đơn giản nhất.

1. duy:vht_modau 
Tác dụng: bắt đấu 1 hộp thoại.
Cú pháp: (duy:vht_modau “tieu de”)
Trong đó “tieu de” do bạn nhập vào và hiển thị phía trên hộp thoại
By Ngọc Nguyễn 2013 Page 58 of 108

2. duy:vht_ketthuc
Tác dụng : kết thúc 1 hộp thoại bao gồm 1 nút thoát và 1 dòng giới thiệu tác giả
Cú pháp: (duy:vht_ketthuc “ten nut” “tacgia”)
Trong đó “ten nut” do bạn nhập vào và hiển thị trên nút thoát. “tac gia” do bạn nhập vào và hiển
thị là 1 text nằm phía trên nút thoát.

3. duy:vht_nutthoat
Tác dụng: tạo 1 nút tác dụng thoát hộp thoại
Cú pháp: (duy:vht_nutthoat “ten nut”)
Trong đó “ten nut” do bạn nhập vào và hiển thị trên nút thoát

4. duy:vht_ketthuckhongnut
Tác dụng: dùng kết thúc 1 hộp thoại mà ko kèm theo nút thoát
Cú pháp: (duy:vht_ketthuckhongnut “tac gia”)
Trong đó “tac gia” do bạn nhập vào và hiển thị là 1 text nằm phía dưới cùng hộp thoại.

5. duy:vht_dongtext
Tác dụng: dùng viết 1 dòng text canh lề trái lên hộp thoại
Cú pháp: (duy:vht_dongtext “noi dung”)
Trong đó “nội dung” do bạn nhập vào và hiển thị trên hộp thoại

6. duy:vht_dongtextg
Tác dụng: dùng viết 1 dòng text canh lề giữa lên hộp thoại
Cú pháp: (duy:vht_dongtextg “noi dung”)
Trong đó “nội dung” do bạn nhập vào và hiển thị trên hộp thoại

7. duy:vht_nut
Tác dụng: tạo 1 nút gọi lệnh lisp trên hộp thoại (lưu ý là gọi lệnh bạn nhé)
Cú pháp: (duy:vht_nut “ten nut” “ten lenh” “do rong”)
Trong đó “ten nut” do bạn nhập vào và hiển thị trên nút , “ten lenh” do bạn nhập khi nhấn vào
nút thì thoát hộp thoại và thực hiện hàm này. “do rong” do mình nhập vào tương ứng giá trị whit
khi thết kế hộp thoại mình ko thấy tác dụng cái này rỏ lắm nhưng cứ chuẩn bị cho nó đủ thông số
cấu tạo.

8. duy:vht_viettext
Tác dụng: tạo 1 ô cho phép bạn nhập text. Và nhận giá trị nhập cho biến “gia tri” cho phép chỉ
định giá trị mặc định nếu chưa tồn tại.
Cú pháp: (duy:vht_viettext “tieu de” “gia tri” “mac dinh” “do rong”)

9. duy:vht_modauhang
Tác dụng: sắp xếp các thứ sau nó thành hàng.

10. duy:vht_modaucot
Tác dụng: sắp xếp các thứ sau nó thành cột.

11. duy:vht_modauhangbao
By Ngọc Nguyễn 2013 Page 59 of 108

Tác dụng: sắp xếp các thứ sau nó thành hàng nằm trong 1 hình chử nhật.
Cú pháp (duy:vht_hangbang “tieu de”)
Trong đó tieu đề do bạn nhập vào và hiển thị phía trên bên phải hình chử nhật, nếu ko muốn hiển
thị gì thì nhập “”.

12. duy:vht_modaucotbao
Tác dụng: sắp xếp các thứ sau nó thành cột nằm trong 1 hình chử nhật.
Cú pháp (duy:vht_cotbang “tieu de”)
Trong đó tieu đề do bạn nhập vào và hiển thị phía trên bên phải hình chử nhật, nếu ko muốn hiển
thị gì thì nhập “”.

13. duy:vht_ketthuccothang
Tác dụng: kết thúc cột hoặc hàng tạo bằng 4 hàm phía trên

14. duy:vht_image
Tác dụng hiển thị 1 ảnh sld có sẳn.
Cú pháp: (duy:vht_anh “tieu de” “do rong” “do cao” “maunen” “duong dan” )
Trong đó: tieu de do bạn nhập vào gì cũng được miển trong 1 hộp thoại đừng có trùng nhau. Do
rong là độ rộng của ảnh. Do cao là độ cao của ảnh. Duong dan là đường dẩn đầy đủ có cả .sld của
ảnh. Mau nen là màu nến của ảnh (nếu muốn giống i màu hộp thoại thì nhập “-15”.

14. duy:vht_imagev
Tác dụng giống bên trên nhưng ko phải nhập dường dẩn mà là tên 1 ký hiệu mình chuẩn bị sắn
(cái này vẽ vector trực tiếp) 10 ký hiệu . Bạn gỏ lệnh GTKH để xem hình và tên dùng gọi hình
này.
Cú pháp: giống bên trên nhung thay “duong dan” bằng “kyhieu”
By Ngọc Nguyễn 2013 Page 60 of 108

15. duy:vht_goihopthoai
Tác dụng: hoàn tất quá trình tạo gán và gọi hộp thoại.

*Ở đây mình làm file tạo hộp thoại riêng và file vẽ ký hiệu riêng nếu bạn nào ko dùng ký hiệu có
sẳn thì ko cần load file ký hiệu cho nặng máy.

*Them 1 ứng dụng ăn non cho cái này là hàm tạo bảng thông báo với các ký hiệu kèm theo.
Cú pháp: (duy:vht_goithongbao “tieu de” “noi dung” “ky hieu” “do rong” “tacgia”)

Ví dụ:
(duy:vht_goithongbao “Chao ban” “Cam on ban a quan tam den chu de” “dau!” “4” “---
Duy782006---”)
Thì ra như sau:

Giới thiệu thêm 10 icon mới vẽ. Xem ten bằng lệnh GTKHF.
By Ngọc Nguyễn 2013 Page 61 of 108

*Lisp này mình sưu tầm chủ yếu là để học, có 2 điều mình học đc rong lisp này
-1.Cách ứng sử với từng đối tượng trong 1 nhóm đối tượng mà lâu nay mình viết hơi dài nay
theo kiểu ày thì tiết kệm kha khá.
-2. Cách lưu lại giá trị nhập vào như trên.
Bạn copy nội dung và tạo file lisp nhé!

(defun c:rb()
(defun ST:Geom-Center (ent / p1 p2)
(vla-getboundingbox (vlax-ename->vla-object ent) 'p1 'p2)
(setq p1 (vlax-safearray->list p1)
p2 (vlax-safearray->list p2) 
pt (mapcar '* (mapcar '+ p1 p2) '(0.5 0.5 0.5))
)
)
(or ang (setq ang 180))
(setq ang (cond ((getreal (strcat "\nGoc quay < " (rtos ang 2 2) " >:")))(ang)))
(foreach e (acet-ss-to-list (ssget))
(command ".rotate" e "" "_non" (ST:Geom-Center e) ang )
))
By Ngọc Nguyễn 2013 Page 62 of 108

Tạo block che khuất phần bên dưới

*Trong khi insert các block vào bản vẽ có nhiều khả năng bạn cần hatch vào vùng đã đặt các
block. Việc này thường không được ưng ý lắm. Hatch không chừa hẳn block ra ma dính lung
tung vào gây mất thẩm mỹ và bực mình cho người vẽ.

Ví dụ Tình trạng như hình dưới.

*Muốn khỏi bực mình vì cái vụ này thì có cách như sau:
-Cứ HATCH thoải mái xong đâu đó hết đi rồi hãy insert BLOCK vào. Và khi tạo BLOCK chúng
ta thêm đối tượng WIPEOUT cách làm như sau.
-Vẽ hình muốn tạo block ra hoặc chèn block sẳn có EXPLODE ra để tạo lại BLOCK.
-Vẻ đường PLINE bao quanh cái hình đó (lưu ý đường PLINE phải khép kín) như ảnh dưới.
Xong move cái PLINE vừa vẽ ra khỏi cái hình muốn tạo BLOCK.
By Ngọc Nguyễn 2013 Page 63 of 108

-Gỏ lệnh WIEPOUT


Command: WIPEOUT
Specify first point or [Frames/Polyline] : Bạn nhấn enter
Select a closed polyline: Bạn chọn PLINE vừa tạo ra
Erase polyline? [Yes/No] : y Bạn gỏ y enter để xóa PLINE gốc.

-COPY cái hình mốn tạo BLOCK để khít trên cái WIPEOUT vừa tạo ra.
-Bạn tạo BLOCK với cả hai đối tượng trên.
-Bây giờ cứ bạn INSERT cái BLOCK này để chổ nào thì nó sẽ che toàn bộ các đối tượng bên
dưới nó. Ngon lành chưa. Ví dụ kết quả như ảnh dưới.
By Ngọc Nguyễn 2013 Page 64 of 108
By Ngọc Nguyễn 2013 Page 65 of 108

Lisp đổi tên BLOCK được chọn.


0 nhận xét
*Lisp dùng đổi tên BLOCK được chọn thành tên mới do mình nhập vào.
-Tên lệnh: CTB.

(defun c:ctb ( )
(command "undo" "be")

(setq ddd (entsel "\nChon BBLOCK muon doi ten"))


(while
(or
(null ddd)
(/= "INSERT" (cdr (assoc 0 (entget (car ddd)))))
)
(princ "\nDoi tuong khong phai la Block! Chon lai")
(setq ddd (entsel "\nChon BLOCK muon doi ten"))
)

(setq DT (car ddd))


(setq DTM (entget DT))
(setq TENKHOI (cdr (assoc 2 DTM)))

(setq TENBLOCKMOIDAT (getstring 5"\nNhap ten BLOCK moi:")) 

(command "_BEDIT" TENKHOI "" "_BSAVEAS" TENBLOCKMOIDAT "_BCLOSE")

(setq DTM (subst (cons 2 TENBLOCKMOIDAT) (assoc 2 DTM) DTM))


(entmod DTM)

(command "undo" "end")


(Princ)) 
By Ngọc Nguyễn 2013 Page 66 of 108

Hoàn thiện Lisp tạo và chỉnh sửa menu.

1 nhận xét
Nay mình hoàn thiện lisp tạo nemu giúp các bạn ko rành vẩn tạo được menu bằng thao tác trực
quan và dể hiểu.
-Bạn load file này về và copy vào thư mục menu trong ổ E. (do mình gặp trở ngại trong việc xoá
file bằng lisp nên bị hạn chế phải thư mục cố định mới được).
-Load nó lên gỏ lệnh VMN thì sẽ có 1 menu mới cho bạn: Ban đầu nó có tên duy782006 (quảng
cáo tí) bạn dùng lệnh DTMN hoặc chọn trên menu để đổi tên theo ý bạn.
-Khi load lên nó sẽ xuất hiện menu sử dụng: 
+Ban đầu nó chỉ có 1 mục đó là giới thiệu lisp menu (trong quá trình biên tập bạn nên đổi nó
sang chức năng khác vì đây là mục khởi thuỷ mình tạo để có đường vào chức năng biên tập)
+Phía dưới menu sử dụng có chức năng gọi menu biên tập (mục này là cố định lisp không hổ trợ
chỉnh sửa mục này).
-Khi gọi menu biên tập lisp sẽ tắt menu sử dụng và thay menu biên tập vào:
+Menu biên tập có các mục giống hệt menu sử dụng trong phần hiển thị tiêu đề chỉ khác phía sau
có chử biên tập bạn chọn mục nào thì chức năng biên tập sẽ cho các lựa chọn:
Gỏ C: Chèn mục đơn vào bên trên vị trí mục vừa chọn.
Gỏ L: Chèn mục xếp lớp vào vào bên trên vị trí mục vừa chọn (lưu ý rằng lisp hổ trợ việc lồng
các mục xếp lớp vào nhau nhưng chỉ giới hạn trong 5 cấp vì mình nghỉ như thế là quá đủ cho nhu
cầu) có một hạn chế là lisp ko kiểm tra tính sẳn có của 1 menu xếp lớp nên nếu bạn tạo 1 mục
xếp lớp có tiêu đề trùng tiêu đề menu xếp lớp hiện có thì menu cũ sẽ được thay thế bằng menu
mới. Mổi mục xếp lớp tại menu biên tập sẽ có 1 mục hổ trợ xoá bỏ menu này (mục này bạn
không thể thay đổi nội dung và không xuất hiện bên menu sử dụng).
Gỏ P: Chèn đường phân cách bên trên vị trí mục vừa chọn. Trên mổi đường phân cách trong
menu biên tập sẽ có 1 mục xoá đường phân cách giúp việc xoá đường phân cách bêb dưới mà
không ảnh hưởng đến các đường phân cách khác (mục này bạn không thể thay đổi nội dung và
không xuất hiện bên menu sử dụng).
Gỏ S: Sửa mục chọn bằng cách nhập nội dung hiển thị và tên lệnh mới.
Gỏ X: Xoá bỏ mục chọn (lưu ý rằng kkhông nên xoá bỏ toàn bộ các mục đơn vì như thế sẽ ko có
mục khởi thuỷ giúp bạn thực hiện chức năng biên tập).
*Tại menu biên tập còn hổ trợ các chức năng:
-ĐTNM: Đổi tên menu chính.
-SLMN: Sao lưu menu hiện hành.
-GLMN: Gọi lại menu đã sao lưu.
-TLMN: Tạo mới menu (lúc này menu quay về trạng thái ban đầu như khi vừa mới gọi lệnh
VMN).
-XBMN: Xoá bỏ hoàn toàn menu khỏi cad của bạn
*Khi nào cần sử dụng chức năng biên tập thì bạn hãy load lisp còn bình thường menu hoạt động
mà ko cần lip (chỉ là chức năng gọi menu biên tập sẽ không thực hiện được).
By Ngọc Nguyễn 2013 Page 67 of 108

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop1xl ()
(setq filemenuchinhp1xl (open (strcat dauduongdan tenfilemodoc) "r"))
(while (setq noidungmenuchinhp1xl (read-line filemenuchinhp1xl))
(setq noidungnguyen noidungmenuchinhp1xl)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") (setq tenfilemodoc (strcat "/menuxl" ndtruoc ".txt")) (write-line (strcat
"[->" ndtruoc "]") filemns) (docghigiuapop1xla))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t(" ndsau ")]^C^C_" ndsau) filemns))


))
))

(close filemenuchinhp1xl)
(write-line (strcat "[<---]") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop1xla ()
(setq filemenuchinhp1xla (open (strcat dauduongdan tenfilemodoc) "r"))
(while (setq noidungmenuchinhp1xla (read-line filemenuchinhp1xla))
(setq noidungnguyen noidungmenuchinhp1xla)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") (setq tenfilemodoc (strcat "/menuxl" ndtruoc ".txt")) (write-line (strcat
"[->" ndtruoc "]") filemns) (docghigiuapop1xlb))
((/= ndsau "menuxeplop") 
By Ngọc Nguyễn 2013 Page 68 of 108

(cond
((= ndsau "mnduongphancach") (write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t(" ndsau ")]^C^C_" ndsau) filemns))


))
))

(close filemenuchinhp1xla)
(write-line (strcat "[<---]") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop1xlb ()
(setq filemenuchinhp1xlb (open (strcat dauduongdan tenfilemodoc) "r"))
(while (setq noidungmenuchinhp1xlb (read-line filemenuchinhp1xlb))
(setq noidungnguyen noidungmenuchinhp1xlb)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") (setq tenfilemodoc (strcat "/menuxl" ndtruoc ".txt")) (write-line (strcat
"[->" ndtruoc "]") filemns) (docghigiuapop1xlc))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t(" ndsau ")]^C^C_" ndsau) filemns))


))
))

(close filemenuchinhp1xlb)
(write-line (strcat "[<---]") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop1xlc ()
(setq filemenuchinhp1xlc (open (strcat dauduongdan tenfilemodoc) "r"))
By Ngọc Nguyễn 2013 Page 69 of 108

(while (setq noidungmenuchinhp1xlc (read-line filemenuchinhp1xlc))


(setq noidungnguyen noidungmenuchinhp1xlc)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") (setq tenfilemodoc (strcat "/menuxl" ndtruoc ".txt")) (write-line (strcat
"[->" ndtruoc "]") filemns) (docghigiuapop1xld))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t(" ndsau ")]^C^C_" ndsau) filemns))


))
))

(close filemenuchinhp1xlc)
(write-line (strcat "[<---]") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop1xld ()
(setq filemenuchinhp1xld (open (strcat dauduongdan tenfilemodoc) "r"))
(while (setq noidungmenuchinhp1xld (read-line filemenuchinhp1xld))
(setq noidungnguyen noidungmenuchinhp1xld)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") (setq tenfilemodoc (strcat "/menuxl" ndtruoc ".txt")) (write-line (strcat
"[->" ndtruoc "]") filemns) (docghigiuapop1xle))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line "[---]" filemns))
((/= ndsau "mnduongphancach")
By Ngọc Nguyễn 2013 Page 70 of 108

(write-line (strcat "[" ndtruoc "\t(" ndsau ")]^C^C_" ndsau) filemns))


))
))

(close filemenuchinhp1xld)
(write-line (strcat "[<---]") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop1xle ()
(setq filemenuchinhp1xle (open (strcat dauduongdan tenfilemodoc) "r"))
(while (setq noidungmenuchinhp1xle (read-line filemenuchinhp1xle))
(setq noidungnguyen noidungmenuchinhp1xle)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "mnduongphancach") (write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t(" ndsau ")]^C^C_" ndsau) filemns))


))

(close filemenuchinhp1xle)
(write-line (strcat "[<---]") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop2xl ()
(setq filemenuchinhp2xl (open (strcat dauduongdan tenfilemodoc) "r"))
(while (setq noidungmenuchinhp2xl (read-line filemenuchinhp2xl))
(setq noidungnguyen noidungmenuchinhp2xl)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") 
(setq tenfilemodoca (strcat "/menuxl" ndtruoc ".txt")) 
By Ngọc Nguyễn 2013 Page 71 of 108

(write-line (strcat "[->" ndtruoc "]") filemns) 


(setq tenmnxlhthia ndtruoc) 
(docghigiuapop2xla))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line (strcat "[Xoa duong phan cach]^C^C_" "xmn" "\;"
"\"" noidungmenuchinhp2xl "\"" "\;" "\"" tenfilemodoc "\"" "\;" "\"" "x" "\"" "\;") filemns) (write-
line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t--Bien Tap]^C^C_" "xmn" "\;" "\"" noidungmenuchinhp2xl "\""
"\;" "\"" tenfilemodoc "\"" "\;") filemns)) 
))
))

(close filemenuchinhp2xl)
(write-line (strcat "[---]") filemns)
(write-line (strcat "[<-Xoa menu xep lop " tenmnxlhthi " nay]^C^C_" "xmnxl" "\;" "\""
tenmnxlhthi "@menuxeplop" "\"" "\;" "\"" "/menuchinh.txt" "\"" "\;") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop2xla ()
(setq filemenuchinhp2xla (open (strcat dauduongdan tenfilemodoca) "r"))
(while (setq noidungmenuchinhp2xla (read-line filemenuchinhp2xla))
(setq noidungnguyen noidungmenuchinhp2xla)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") 
(setq tenfilemodocb (strcat "/menuxl" ndtruoc ".txt")) 
(write-line (strcat "[->" ndtruoc "]") filemns) 
(setq tenmnxlhthib ndtruoc) 
(docghigiuapop2xlb))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line (strcat "[Xoa duong phan cach]^C^C_" "xmn" "\;"
By Ngọc Nguyễn 2013 Page 72 of 108

"\"" noidungmenuchinhp2xla "\"" "\;" "\"" tenfilemodoca "\"" "\;" "\"" "x" "\"" "\;") filemns)
(write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t--Bien Tap]^C^C_" "xmn" "\;" "\"" noidungmenuchinhp2xla "\""
"\;" "\"" tenfilemodoca "\"" "\;") filemns)) 
))
))

(close filemenuchinhp2xla)
(write-line (strcat "[---]") filemns)
(write-line (strcat "[<-Xoa menu xep lop " tenmnxlhthia " nay]^C^C_" "xmnxl" "\;" "\""
tenmnxlhthia "@menuxeplop" "\"" "\;" "\"" tenfilemodoc "\"" "\;") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop2xlb ()
(setq filemenuchinhp2xlb (open (strcat dauduongdan tenfilemodocb) "r"))
(while (setq noidungmenuchinhp2xlb (read-line filemenuchinhp2xlb))
(setq noidungnguyen noidungmenuchinhp2xlb)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") 
(setq tenfilemodocc (strcat "/menuxl" ndtruoc ".txt")) 
(write-line (strcat "[->" ndtruoc "]") filemns) 
(setq tenmnxlhthic ndtruoc) 
(docghigiuapop2xlc))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line (strcat "[Xoa duong phan cach]^C^C_" "xmn" "\;"
"\"" noidungmenuchinhp2xlb "\"" "\;" "\"" tenfilemodocb "\"" "\;" "\"" "x" "\"" "\;") filemns)
(write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t--Bien Tap]^C^C_" "xmn" "\;" "\"" noidungmenuchinhp2xlb "\""
"\;" "\"" tenfilemodocb "\"" "\;") filemns)) 
))
By Ngọc Nguyễn 2013 Page 73 of 108

))

(close filemenuchinhp2xlb)
(write-line (strcat "[---]") filemns)
(write-line (strcat "[<-Xoa menu xep lop " tenmnxlhthib " nay]^C^C_" "xmnxl" "\;" "\""
tenmnxlhthib "@menuxeplop" "\"" "\;" "\"" tenfilemodoca "\"" "\;") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop2xlc ()
(setq filemenuchinhp2xlc (open (strcat dauduongdan tenfilemodocc) "r"))
(while (setq noidungmenuchinhp2xlc (read-line filemenuchinhp2xlc))
(setq noidungnguyen noidungmenuchinhp2xlc)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") 
(setq tenfilemodocd (strcat "/menuxl" ndtruoc ".txt")) 
(write-line (strcat "[->" ndtruoc "]") filemns) 
(setq tenmnxlhthid ndtruoc) 
(docghigiuapop2xld))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line (strcat "[Xoa duong phan cach]^C^C_" "xmn" "\;"
"\"" noidungmenuchinhp2xlc "\"" "\;" "\"" tenfilemodocc "\"" "\;" "\"" "x" "\"" "\;") filemns)
(write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t--Bien Tap]^C^C_" "xmn" "\;" "\"" noidungmenuchinhp2xlc "\""
"\;" "\"" tenfilemodocc "\"" "\;") filemns)) 
))
))

(close filemenuchinhp2xlc)
(write-line (strcat "[---]") filemns)
(write-line (strcat "[<-Xoa menu xep lop " tenmnxlhthic " nay]^C^C_" "xmnxl" "\;" "\""
tenmnxlhthic "@menuxeplop" "\"" "\;" "\"" tenfilemodocb "\"" "\;") filemns)
)
By Ngọc Nguyễn 2013 Page 74 of 108

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop2xld ()
(setq filemenuchinhp2xld (open (strcat dauduongdan tenfilemodocd) "r"))
(while (setq noidungmenuchinhp2xld (read-line filemenuchinhp2xld))
(setq noidungnguyen noidungmenuchinhp2xld)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") 
(setq tenfilemodoce (strcat "/menuxl" ndtruoc ".txt")) 
(write-line (strcat "[->" ndtruoc "]") filemns) 
(setq tenmnxlhthie ndtruoc) 
(docghigiuapop2xle))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line (strcat "[Xoa duong phan cach]^C^C_" "xmn" "\;"
"\"" noidungmenuchinhp2xld "\"" "\;" "\"" tenfilemodocd "\"" "\;" "\"" "x" "\"" "\;") filemns)
(write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t--Bien Tap]^C^C_" "xmn" "\;" "\"" noidungmenuchinhp2xld "\""
"\;" "\"" tenfilemodocd "\"" "\;") filemns)) 
))
))

(close filemenuchinhp2xld)
(write-line (strcat "[---]") filemns)
(write-line (strcat "[<-Xoa menu xep lop " tenmnxlhthid " nay]^C^C_" "xmnxl" "\;" "\""
tenmnxlhthid "@menuxeplop" "\"" "\;" "\"" tenfilemodocc "\"" "\;") filemns)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun docghigiuapop2xle ()
(setq filemenuchinhp2xle (open (strcat dauduongdan tenfilemodoce) "r"))
(while (setq noidungmenuchinhp2xle (read-line filemenuchinhp2xle))
(setq noidungnguyen noidungmenuchinhp2xle)
(setq dodainguyen (strlen noidungnguyen))
By Ngọc Nguyễn 2013 Page 75 of 108

(setq dodainguyenl dodainguyen)


(doc@)

(cond
((= ndsau "mnduongphancach") (write-line (strcat "[Xoa duong phan cach]^C^C_" "xmn" "\;"
"\"" noidungmenuchinhp2xle "\"" "\;" "\"" tenfilemodoce "\"" "\;" "\"" "x" "\"" "\;") filemns)
(write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t--Bien Tap]^C^C_" "xmnkxl" "\;" "\"" noidungmenuchinhp2xle
"\"" "\;" "\"" tenfilemodoce "\"" "\;") filemns)) 
))

(close filemenuchinhp2xle)
(write-line (strcat "[---]") filemns)
(write-line (strcat "[<-Xoa menu xep lop " tenmnxlhthie " nay]^C^C_" "xmnxl" "\;" "\""
tenmnxlhthie "@menuxeplop" "\"" "\;" "\"" tenfilemodocd "\"" "\;") filemns)
)

;;;;;;;;;;;;;;;;;
(defun c:vmn ()
(doanvmn))
;;;;;;;;;;;;;
(setq dauduongdan "E:/menu")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun doanvmn ()

(setq filemns (open (strcat dauduongdan "/dslenh.mns") "w"))

;;;;;;;;;;;;;;;;;;;;;;;;;;;taofilechuamenuchinh
(setq tinhtrangfilechinh (findfile (strcat dauduongdan "/menuchinh.txt")))
(cond
((= nil tinhtrangfilechinh) 
(setq taofilemenuchinh (open (strcat dauduongdan "/menuchinh.txt") "w"))
(write-line "Gioi thieu menu @gtmn" taofilemenuchinh)
(close taofilemenuchinh)
))

;;;;;;;;;;;;;;;;;;;;;;;;;;;taofilechuatenmenu
(setq tinhtrangfilechinh (findfile (strcat dauduongdan "/tenmenu.txt")))
(cond
By Ngọc Nguyễn 2013 Page 76 of 108

((= nil tinhtrangfilechinh) 


(setq taofiletenmenu (open (strcat dauduongdan "/tenmenu.txt") "w"))
(write-line "Menu Duy782006" taofiletenmenu)
(close taofiletenmenu)
))

;;;;;;;;;;;;;;;;;;;;;;;;;;;vietdaupop1
(setq mofiletieude (open (strcat dauduongdan "/tenmenu.txt") "r"))
(setq noidungtieude (read-line mofiletieude))
(close mofiletieude)
(write-line "***MENUGROUP=DSLenh" filemns)
(write-line "***POP1" filemns)
(write-line (strcat "ID_tieude [" noidungtieude "]") filemns)

;;;;;;;;;;;;;;;;;;;;;;;;;;;vietgiuapop1
(setq filemenuchinhp1 (open (strcat dauduongdan "/menuchinh.txt") "r"))
(while (setq noidungmenuchinhp1 (read-line filemenuchinhp1))
(setq noidungnguyen noidungmenuchinhp1)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") (setq tenfilemodoc (strcat "/menuxl" ndtruoc ".txt")) (write-line (strcat
"[->" ndtruoc "]") filemns) (docghigiuapop1xl))
((/= ndsau "menuxeplop") 

(cond
((= ndsau "mnduongphancach") (write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t(" ndsau ")]^C^C_" ndsau) filemns))


))
))
(close filemenuchinhp1)

;;;;;;;;;;;;;;;;;;;;;;;;;;;vietcuoipop1
(write-line "[---]" filemns)
(write-line "[Goi menu bien tap \t(BTMN)]^C^C_btmn" filemns)

;;;;;;;;;;;;;;;;;;;;;;;;;;;vietdaupop2
By Ngọc Nguyễn 2013 Page 77 of 108

(write-line "***POP2" filemns)


(write-line (strcat "ID_tieude [" noidungtieude "]") filemns)

;;;;;;;;;;;;;;;;;;;;;;;;;;;vietgiuapop2
(setq filemenuchinhp2 (open (strcat dauduongdan "/menuchinh.txt") "r"))
(while (setq noidungmenuchinhp2 (read-line filemenuchinhp2))
(setq noidungnguyen noidungmenuchinhp2)
(setq dodainguyen (strlen noidungnguyen))
(setq dodainguyenl dodainguyen)
(doc@)

(cond
((= ndsau "menuxeplop") 
(setq tenfilemodoc (strcat "/menuxl" ndtruoc ".txt")) 
(write-line (strcat "[->" ndtruoc "]") filemns) 
(setq tenmnxlhthi ndtruoc) 
(setq tenfilemoxoa "/menuchinh.txt") 
(docghigiuapop2xl))
((/= ndsau "menuxeplop")

(cond
((= ndsau "mnduongphancach") (write-line (strcat "[Xoa duong phan cach]^C^C_" "xmn" "\;"
"\"" noidungmenuchinhp2 "\"" "\;" "\"" "/menuchinh.txt" "\"" "\;" "\"" "x" "\"" "\;") filemns)
(write-line "[---]" filemns))
((/= ndsau "mnduongphancach")

(write-line (strcat "[" ndtruoc "\t--Bien Tap]^C^C_" "xmn" "\;" "\"" noidungmenuchinhp2 "\""
"\;" "\"" "/menuchinh.txt" "\"" "\;") filemns)) 
))
))
(close filemenuchinhp2)

;;;;;;;;;;;;;;;;;;;;;;;;;;;vietcuoipop2
(write-line "[---]" filemns)
(write-line "[DOI TEN MENU CHINH \t(DTMN)]^C^C_dtmn" filemns)
(write-line "[xOA BO MENU \t(XBMN)]^C^C_xbmn" filemns)
(write-line "[LAM LAI MENU \t(TLMN)]^C^C_tlmn" filemns)
(write-line "[LUU MENU HIEN TAI \t(SLMN)]^C^C_slmn" filemns)
(write-line "[LOAD MENU DA LUU \t(GLMN)]^C^C_glmn" filemns)
(write-line "[---]" filemns)
(write-line "[Goi menu su dung \t(SDMN)]^C^C_sdmn" filemns)
By Ngọc Nguyễn 2013 Page 78 of 108

;;;;;;;;;;;;;;;;;;;;;;;;;;;ketthucvietmns
(close filemns)

(command "_menuload" (strcat dauduongdan "/dslenh.mns")) 


(menucmd "P13=+DSlenh.pop1") 
(princ)
)

;;;;;;;;;;;;;;
;;;;;;;;;;;;;;
;;;;;;;;;;;;;;
(Defun doc@ ( ) 

(setq dodainguyen (- dodainguyen 1))


(setq noidungdocdc (substr noidungnguyen dodainguyen 1))
(if (/= noidungdocdc "@")
(doc@)
)
(IF (= noidungdocdc "@") (PROGN
(setq ndtruoc (substr noidungnguyen 1 (- dodainguyen 1))) 
(setq ndsau (substr noidungnguyen (+ dodainguyen 1) (- dodainguyenl dodainguyen))) 
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:xbmn ()
(command "_menuunload" "DSLenh") 
(command "SHELL" (strcat "del " "E:\\menu\\dslenh.*" ))
(command "DELAY" "3000" "")
(command "SHELL" (strcat "del " "E:\\menu\\*.txt" ))
(command "DELAY" "3000" "")
(Princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:tlmn ()
(command "_menuunload" "DSLenh") 
(command "SHELL" (strcat "del " "E:\\menu\\dslenh.*" ))
(command "DELAY" "3000" "")
By Ngọc Nguyễn 2013 Page 79 of 108

(command "SHELL" (strcat "del " "E:\\menu\\*.txt" ))


(command "DELAY" "3000" "")
(doanvmn)
(Princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:slmn ()
(command "SHELL" "MD E:\\menu\\saoluumenu" )
(command "DELAY" "1000" "")
(command "SHELL" "copy E:\\menu\\*.txt E:\\menu\\saoluumenu\\" )
(Princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:glmn ()
(command "_menuunload" "DSLenh") 
(command "SHELL" (strcat "del " "E:\\menu\\dslenh.*" ))
(command "DELAY" "3000" "")
(command "SHELL" (strcat "del " "E:\\menu\\*.txt" ))
(command "DELAY" "3000" "")
(command "SHELL" "copy E:\\menu\\saoluumenu\\*.txt E:\\menu\\" )
(command "DELAY" "3000" "")
(doanvmn)
(Princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:btmn ()
(command "_menuunload" "DSLenh") 
(command "_menuload" (strcat dauduongdan "/dslenh.mns")) 
(menucmd "P13=+DSlenh.pop2") 
(Princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:sdmn ()
(command "_menuunload" "DSLenh") 
(command "_menuload" (strcat dauduongdan "/dslenh.mns")) 
(menucmd "P13=+DSlenh.pop1") 
(Princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:dtmn ()
(setq tenmoi (getstring "\nNhap ten menu:")) 
By Ngọc Nguyễn 2013 Page 80 of 108

(command "_menuunload" "DSLenh") 


(setq mofiletieude (open (strcat dauduongdan "/tenmenu.txt") "w"))
(write-line tenmoi mofiletieude)
(close mofiletieude)
(doanvmn)
(Princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:xmn ()
(setq noidungtimxoa (getstring "\nNhap:"))
(setq filedocsua (getstring "\nNhap:"))

(setq mofilegiua (open (strcat dauduongdan filedocsua) "r"))


(setq mofiletrunggian (open (strcat dauduongdan "/trunggian.txt") "w"))
(setq kieutacdongmenu (strcase (getstring "\nChen muc don/ chen muc xep Lop/ Sua muc/ Xoa
muc/ chen duong Phan cach:")))

(cond
((= kieutacdongmenu "X")
(while (setq noidunggiua (read-line mofilegiua))
(if (/= noidungtimxoa noidunggiua)
(write-line noidunggiua mofiletrunggian)
)
)
);dongcondxoamenu
((= kieutacdongmenu "S")
(setq noidunghienthi (getstring 5"\nNhap noi dung hien thi tren menu:")) 
(setq tenlenh (getstring "\nNhap ten lenh:")) 
(setq chuoivietthem (strcat noidunghienthi "@" tenlenh))

(while (setq noidunggiua (read-line mofilegiua))


(if (/= noidungtimxoa noidunggiua)
(write-line noidunggiua mofiletrunggian)
)
(if (= noidungtimxoa noidunggiua)
(write-line chuoivietthem mofiletrunggian)
)
)
);dongcondchinhmenu
By Ngọc Nguyễn 2013 Page 81 of 108

((= kieutacdongmenu "C")


(setq noidunghienthi (getstring 5"\nNhap noi dung hien thi tren menu:")) 
(setq tenlenh (getstring "\nNhap ten lenh:")) 
(setq chuoivietthem (strcat noidunghienthi "@" tenlenh))

(while (setq noidunggiua (read-line mofilegiua))


(if (= noidungtimxoa noidunggiua)
(write-line chuoivietthem mofiletrunggian)
)
(write-line noidunggiua mofiletrunggian)
)
);dongcondthemmenu

((= kieutacdongmenu "L")


(setq noidunghienthi (getstring 5"\nNhap tieu de menu xep lop nay:")) 
(setq chuoivietthem (strcat noidunghienthi "@menuxeplop"))

(while (setq noidunggiua (read-line mofilegiua))


(if (= noidungtimxoa noidunggiua)
(write-line chuoivietthem mofiletrunggian)
)
(write-line noidunggiua mofiletrunggian)
)
(setq mofilexeplopghi (open (strcat dauduongdan "/menuxl" noidunghienthi ".txt") "w"))
(write-line "Gioi thieu menu xep lop@gtmnxl" mofilexeplopghi)
(close mofilexeplopghi)
);dongcondthemmenuxeplop

((= kieutacdongmenu "P")


(setq thoigianhienhanh (menucmd "M=$(getvar, date)"))
(setq chuoivietthem (strcat thoigianhienhanh "@mnduongphancach"))

(while (setq noidunggiua (read-line mofilegiua))


(if (= noidungtimxoa noidunggiua)
(write-line chuoivietthem mofiletrunggian)
)
(write-line noidunggiua mofiletrunggian)
)
);dongcondthemmenuphancach
By Ngọc Nguyễn 2013 Page 82 of 108

);dongcond

(close mofilegiua)
(close mofiletrunggian)

(setq mofilegiua (open (strcat dauduongdan filedocsua) "w"))


(setq mofiletrunggian (open (strcat dauduongdan "/trunggian.txt") "r"))
(while (setq noidunggiua (read-line mofiletrunggian))
(write-line noidunggiua mofilegiua)
)
(close mofilegiua)
(close mofiletrunggian)
(command "SHELL" (strcat "del " "E:\\menu\\trunggian.txt" ))
;(command "SHELL" (strcat "del " dauduongdan "/trunggian.txt" ))

(command "_menuunload" "DSLenh") 


(doanvmn)

(Princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:xmnkxl ()
(setq noidungtimxoa (getstring "\nNhap:"))
(setq filedocsua (getstring "\nNhap:"))

(setq mofilegiua (open (strcat dauduongdan filedocsua) "r"))


(setq mofiletrunggian (open (strcat dauduongdan "/trunggian.txt") "w"))
(setq kieutacdongmenu (strcase (getstring "\nChen muc don/ Sua muc/ Xoa muc/ chen duong
Phan cach:")))

(cond
((= kieutacdongmenu "X")
(while (setq noidunggiua (read-line mofilegiua))
(if (/= noidungtimxoa noidunggiua)
(write-line noidunggiua mofiletrunggian)
)
)
);dongcondxoamenu
By Ngọc Nguyễn 2013 Page 83 of 108

((= kieutacdongmenu "S")


(setq noidunghienthi (getstring 5"\nNhap noi dung hien thi tren menu:")) 
(setq tenlenh (getstring "\nNhap ten lenh:")) 
(setq chuoivietthem (strcat noidunghienthi "@" tenlenh))

(while (setq noidunggiua (read-line mofilegiua))


(if (/= noidungtimxoa noidunggiua)
(write-line noidunggiua mofiletrunggian)
)
(if (= noidungtimxoa noidunggiua)
(write-line chuoivietthem mofiletrunggian)
)
)
);dongcondchinhmenu
((= kieutacdongmenu "C")
(setq noidunghienthi (getstring 5"\nNhap noi dung hien thi tren menu:")) 
(setq tenlenh (getstring "\nNhap ten lenh:")) 
(setq chuoivietthem (strcat noidunghienthi "@" tenlenh))

(while (setq noidunggiua (read-line mofilegiua))


(if (= noidungtimxoa noidunggiua)
(write-line chuoivietthem mofiletrunggian)
)
(write-line noidunggiua mofiletrunggian)
)
);dongcondthemmenu

((= kieutacdongmenu "P")


(setq thoigianhienhanh (menucmd "M=$(getvar, date)"))
(setq chuoivietthem (strcat thoigianhienhanh "@mnduongphancach"))

(while (setq noidunggiua (read-line mofilegiua))


(if (= noidungtimxoa noidunggiua)
(write-line chuoivietthem mofiletrunggian)
)
(write-line noidunggiua mofiletrunggian)
)
);dongcondthemmenuphancach

);dongcond
By Ngọc Nguyễn 2013 Page 84 of 108

(close mofilegiua)
(close mofiletrunggian)

(setq mofilegiua (open (strcat dauduongdan filedocsua) "w"))


(setq mofiletrunggian (open (strcat dauduongdan "/trunggian.txt") "r"))
(while (setq noidunggiua (read-line mofiletrunggian))
(write-line noidunggiua mofilegiua)
)
(close mofilegiua)
(close mofiletrunggian)
(command "SHELL" (strcat "del " "E:\\menu\\trunggian.txt" ))
;(command "SHELL" (strcat "del " dauduongdan "/trunggian.txt" ))

(command "_menuunload" "DSLenh") 


(doanvmn)

(Princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:xmnxl ()
(setq noidungtimxoa (getstring "\nNhap:"))
(setq filedocsua (getstring "\nNhap:"))

(setq mofilegiua (open (strcat dauduongdan filedocsua) "r"))


(setq mofiletrunggian (open (strcat dauduongdan "/trunggian.txt") "w"))

(while (setq noidunggiua (read-line mofilegiua))


(if (/= noidungtimxoa noidunggiua)
(write-line noidunggiua mofiletrunggian)
)
)

(close mofilegiua)
(close mofiletrunggian)

(setq mofilegiua (open (strcat dauduongdan filedocsua) "w"))


(setq mofiletrunggian (open (strcat dauduongdan "/trunggian.txt") "r"))
(while (setq noidunggiua (read-line mofiletrunggian))
By Ngọc Nguyễn 2013 Page 85 of 108

(write-line noidunggiua mofilegiua)


)
(close mofilegiua)
(close mofiletrunggian)
(command "SHELL" (strcat "del " "E:\\menu\\trunggian.txt" ))
;(command "SHELL" (strcat "del " dauduongdan "/trunggian.txt" ))

(command "_menuunload" "DSLenh") 


(doanvmn)

(Princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(Defun c:gtmn ( ) 
(alert "*Tien ich bien tap va su dung menu truc quan.
*Co hai menu song song voi cac de muc giong nhau:
-Menu su dung: Dung nhu menu binh thuong.
-Menu bien tap: Co chuc nang bien tap, khi ban chon bien tap muc nao thi co 5 lua chon cho ban:
+Go C: Chen muc menu don tren muc vua chon.
+Go L: Chen muc menu xep lop tren muc vua chon.
+Go P: Chen duong phan cach tren muc vua chon.
+Go S: Chinh sua muc vua chon.
+Go X: Xoa bo muc vua chon khoi menu.
*Menu su dung co muc cuoi cung dung goi menu bien tap.
*Menu bien tap co muc cuoi cung dung goi menu su dung va cac chuc nang:
-Doi ten menu chinh.
-Xoa bo menu.
-Sao luu menu.
-Goi menu da luu.
-Khoi tao lai menu ban dau")
(princ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(Defun c:gtmnxl ( ) 
(alert "-Khi khoi tao mot menu xep lop minh mac dinh cho no mot muc don hien hanh.
-Tu muc don nay ban dung chuc nang bien tap de co duoc menu ung y.
-Minh ho tro ban viec tao ra cac menu xep lop long trong nhau.
-Gioi han long menu xep lop o day minh goi han trong 5 cap.
-Khi ban tao 2 menu xep lop co ten trung nhau thi noi dung cua menu tao sau se thay the menu
truoc.")
(princ))
By Ngọc Nguyễn 2013 Page 86 of 108
By Ngọc Nguyễn 2013 Page 87 of 108

Lisp rải đối tượng theo đường dẩn.

*Lâu nay dùng cái MEASURE và DIVIDE của cad thấy có vài hạn chế:


-Chỉ rải được point và block.
-Block thỉ phải gỏ tên và được chèn ra với tỉ lệ 1/1.
-Bỏ qua không chèn vào vị trí xuất phát của đường dẩn.
*Dựa trên cái lisp xác định điểm của bác SSG cho mình cải tạo và nhập chung thành 1 lệnh tác
dụng tương đương và cải thiện các nhược điểm mình nêu trên: (à nghe bảo cad12 đã kết hợp
array theo đường dẩn nhưng mình chưa tiếp xúc nên ko biết có bị dẩm lên đó ko nhưng đây là
thử nghiệm vì mình tính cho xác định điểm bắt đầu và hướng rải nửa nhưng chưa nghỉ ra kịch
bản vì có quá nhiều thường hợp muốn)
-Tên lệnh: RDT (rải đối tượng)
-Hỏi chọn đối tượng muốn rải: Bạn chọn thoải mái bằng các kiểu (đối tượng gì cũng được) kết
thúc chọn bằng enter.
+Nếu bạn chọn hơn 1 đối tượng thì sẽ hỏi bạn chọn điểm chuẩn cho nhóm đối tượng này (dùng
để làm điểm đặt trên đường dẩn í).
+Nếu bạn chọn 1 đối tượng thì sẽ xem nếu đối tượng không phải là block thì vẩn hỏi chọn điểm
chuẩn, Nếu đối tượng là block thì bỏ qua phần hỏi chọn điểm chuẩn mà lấy điểm chèn
của block đó làm điểm chuẩn.
-Hỏi chọn đường dẩn dùng để rải.
-Hỏi “Kieu rai theo: So luong/(khoang)” :
+Rải theo số lượng thì nhập S enter.
+Rải theo khoảng cách thì nhập K enter hoặc enter không (thực chất cứ nhập vào khác S thì
nhận là khoảng cách).
-Tùy theo lựa chọn mà hỏi khoảng cách rải hay số lượng rải.
-Hỏi “Co quay doi tuong vuong goc voi duong dan khong: Khong/(Co)") :
+Không quay đối tượng cho vuông góc với đường dẩn thì nhập K enter.
+Có quay thì nhập C en ter hoặc enter không (thực chất cứ nhập vào khác K thì nhận là có).
*Xong rồi. Bác nào có nhu cầu thì dùng không có thì dòm. Mong không ném đá hoặc dè bỉu.
By Ngọc Nguyễn 2013 Page 88 of 108

Bạn copy nội dung và tạo file lisp hay tải file về cũng được!

(Defun c:rdt (/ ss doituong dsl dc ddd chondd chieudaicuver diemdau diemcuoi krai
chieudaidoan slc sl index d2 p2 d5 p5 d3 p3 dt l m)
(vl-load-com)
(command "undo" "be")
(command "ucs" "")
(chonnhomdoituong)
(choncuver)
(hoikieurai)
(command "ucs" "p")
(command "undo" "end")
(princ)
)
;;;;;;;;;;;;;;;;;
(Defun chonnhomdoituong ()
(princ "\nChon doi tuong rai:")
(setq ss (ssget))

(cond 
((= ss nil) (princ "\nChua chon duoc doi tuong nao:") (chonnhomdoituong))
((/= ss nil) 
(setq dsl (sslength ss))
(cond 
((= dsl 1) 
(setq doituong (ssname SS 0))
(setq doituong (entget doituong))
(setq KIEUDOITUONG (cdr (assoc 0 doituong)))
(cond 
((= KIEUDOITUONG "INSERT") (setq dc (cdr (assoc 10 doituong))))
((/= KIEUDOITUONG "INSERT") (chondiemchuandoituong))
);ketthuccondxemblock
);kethucdsl1
((/= dsl 1) (chondiemchuandoituong))
);ketthuccondnho

);ketthucsetqdsl
);ketthuccondtong 
(princ)
)
;;;;;;;;;;;;;;;;;
(Defun chondiemchuandoituong ()
(setq dc (getpoint "\nChon diem goc: "))
(cond 
((= dc nil) (princ "\nChua chon duoc diem goc:") (chondiemchuandoituong))
By Ngọc Nguyễn 2013 Page 89 of 108

((/= ss nil))) 
(princ)
)
;;;;;;;;;;;;;;;;;
(Defun choncuver ()

(setq ddd (entsel "\nChon duong dan:"))


(while
(or
(null ddd)
(or (= "TEXT" (cdr (assoc 0 (entget (car ddd))))) (= "MTEXT" (cdr (assoc 0 (entget (car ddd)))))
(= "HATCH" (cdr (assoc 0 (entget (car ddd))))) (= "INSERT" (cdr (assoc 0 (entget (car ddd)))))
(= "REGION" (cdr (assoc 0 (entget (car ddd))))) (= "DIMENSION" (cdr (assoc 0 (entget (car
ddd)))))
)
)
(setq ddd (entsel "\nDoi tuong khong the lam duong dan! Chon lai"))
)

(setq chondd (car ddd))


(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)
(setq chieudaicuver (vlax-curve-getDistAtParam chondd (vlax-curve-getEndParam chondd)))
(setq diemdau (vlax-curve-getPointAtDist chondd 0))
(setvar "osmode"luubatdiem)
(princ)
)
;;;;;;;;;;;;;;;;;
(Defun hoikieurai ()
(setq krai (strcase (getstring "\nKieu rai theo: So luong/")))
(Cond
((= krai "S") (raisoluong))
((/= krai "S")(raikhoangcach))

(princ)
)
;;;;;;;;;;;;;;
(Defun raikhoangcach ()
(setq chieudaidoan (GETDIST "\nKhoang cach doan chia: "))
(setq sol (+ (/ chieudaicuver chieudaidoan) 1))
(setq sl (fix sol))
(setq sl (fix sl))
(thuchienrai)
(princ)
)
;;;;;;;;;;;;;;
By Ngọc Nguyễn 2013 Page 90 of 108

(Defun raisoluong ()
(setq slc (getreal "\nChia duong dan thanh may lan:"))
(setq chieudaidoan (/ chieudaicuver slc))
(setq sl (fix (+ 1 slc)))
(thuchienrai)
(princ)
)
;;;;;;;;;;;;;;
(Defun thuchienrai (/ quaykhong)

(setq quaykhong (strcase (getstring "\nCo quay doi tuong vuong goc voi duong dan khong:
Khong/")))
(Cond
((= quaykhong "K") (setq copygiua copykoquay))
((/= quaykhong "K")(setq copygiua copyquay))

(setq index -1)

(repeat sl
(setq index (1+ index))
(setq d2 (* chieudaidoan index))
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)
(setq p2 (vlax-curve-getPointAtDist chondd d2))
(setvar "osmode"luubatdiem)
(copygiua)
)
(princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;
(defun copycuoiquay()
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)
(setq d5 (- chieudaicuver 0.001))
(setq p5 (vlax-curve-getPointAtDist chondd d5))
(setq L 0)
(setq M (sslength ss))
(while (< L M)
(setq DT (ssname ss L))
(command ".copy" DT "" dc p2)
(command ".rotate" "last" "" p2 p5)
(command ".rotate" "last" "" p2 180)
(setq L (1+ L))
)
(setvar "osmode"luubatdiem)
By Ngọc Nguyễn 2013 Page 91 of 108

(princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;
(defun COPYQUAY(/ p3)
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)
(setq d3 (+ (* chieudaidoan index) 0.001))
(setq p3 (vlax-curve-getPointAtDist chondd d3))
(setvar "osmode"luubatdiem)
(Cond
((= p3 nil) (copycuoiquay))
((/= p3 nil) 
(setq L 0)
(setq M (sslength ss))
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)
(while (< L M)
(setq DT (ssname ss L))
(command ".copy" DT "" dc p2)
(command ".rotate" "last" "" p2 p3)
(setq L (1+ L))
)
(setvar "osmode"luubatdiem)
)

(princ)
)
;;;;;;;;;;;;;;
By Ngọc Nguyễn 2013 Page 92 of 108

Các tiện ích đo.


1 nhận xét
Tác dụng và hướng dẩn:
-Đo diện tích pline bằng cách chọn pline: gọi lệnh: DTICH
-Đo chu vi pline bằng cách chọn pline: gọi bằng lệnh: CHUVI
-Đo chu diện tích chữ nhật bằng cách pick 2 điểm góc hình chử nhật: gọi bằng lệnh: 2D Kết quả
viết ra tại tâm hình chữ nhật.
-Đo diện tích 1 vùng kín bằng cách pick vào 1 điểm trong vùng: gọi bằng lệnh: DTICHP
*Lưu ý lệnh cho phép xác định gí trị 1 mét là bao nhiêu để tính toán ra diện tích theo tỏ lệ đang
vẽ. Mặc định 1 mét vẽ là 1000, bạn muốn thay đổi giá trị này thì để ý khi nào lisp hỏi:
Mot met hien hanh la (1000) :
Hoặc:
Mot met hien hanh la (1000) :
Thì gỏ M enter lisp sẽ hỏi bạn: Mot met ban ve la <1000> : Bạn nhập vào enter rồi tiếp tục lệnh.
Giá trị này sẽ lưu cho các lần gọi lệnh sau trong 1 phiên làm việc.
By Ngọc Nguyễn 2013 Page 93 of 108

Bạn copy nội dung và tạo file lisp hay tải file về cũng được!

;Viet boi: KTS_DUY BINH SON - QUANG NGAI


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(DEFUN C:2d ( )
(dodientichbanghaidiem))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(DEFUN C:dtich ( )
(dodientich))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(DEFUN C:chuvi ( )
(dochuvi))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(DEFUN C:dtichp ( )
(dodientichpicdiem))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(DEFUN dodientichbanghaidiem ( )
(command "-style" "thep" "VNI-HELVE" "0" "1" "0" "n" "n")
(princ "\nPHAM QUOC DUY Binh Son - Quang ngai")
(if (null motmetdo2d)(setq motmetdo2d "1000"))
(Setq temp T)
(While temp
(setq a (strcat "\nMot met hien hanh la ("motmetdo2d") : ")) 
(Initget "m M")
(setq str (getpoint a))
(Cond
((= str "m") (setq motmetdo2d (getstring (strcat"\nMot met ban ve la <" motmetdo2d "> :"))))
((= str "M") (setq motmetdo2d (getstring (strcat"\nMot met ban ve la <" motmetdo2d "> :"))))
(Progn
(Setq a str)
(setq temp nil)
)
)
)
(setq b (getcorner a"\nDiem thu hai: "))
(setq luubatdiem (getvar "osmode")) (setq luulop (getvar "clayer"))
(setvar "osmode" 0)

(command ".RECTANGLE" a b)
(command "area" "object" "last")
(setq dientichdo2d (getvar "area"))

(setq motmetdo2dt (atof motmetdo2d)) 


By Ngọc Nguyễn 2013 Page 94 of 108

(setq dolonchu2d (/ motmetdo2dt 4)) 


(setq dientichdo2dtinh (/ dientichdo2d (* motmetdo2dt motmetdo2dt)))

(setq daitong2d (distance a b))


(setq dainua2d (/ daitong2d 2))
(setq goc2d(angle a b))
(setq diemviet2d (polar a goc2d dainua2d))

(command "erase" "last" "") 


(command "TEXT" "m" diemviet2d dolonchu2d 0 (rtos dientichdo2dtinh 2 2))
(setvar "osmode" luubatdiem) (setvar "clayer" luulop)

(setvar "MODEMACRO" "**TAILIEUKYTHUAT.COM**")


(princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(DEFUN dodientich ( )
(command "-style" "thep" "VNI-HELVE" "0" "1" "0" "n" "n")
(princ "\nPHAM QUOC DUY Binh Son - Quang ngai")

(Prompt "\nChon doi tuong") 


(Setq doituongdo (Ssget))
(setq luubatdiem (getvar "osmode")) (setq luulop (getvar "clayer"))
(setvar "osmode" 0)

(if (null motmetdo2d)(setq motmetdo2d "1000"))


(Setq temp T)
(While temp
(setq a (strcat "\nMot met hien hanh la ("motmetdo2d") : ")) 
(Initget "m M")
(setq str (getpoint a))
(Cond
((= str "m") (setq motmetdo2d (getstring (strcat"\nMot met ban ve la <" motmetdo2d "> :"))))
((= str "M") (setq motmetdo2d (getstring (strcat"\nMot met ban ve la <" motmetdo2d "> :"))))
(Progn
(Setq a str)
(setq temp nil)
)
)
)
(command "area" "object" doituongdo)
(setq dientichdo2d (getvar "area"))

(setq motmetdo2dt (atof motmetdo2d)) 


By Ngọc Nguyễn 2013 Page 95 of 108

(setq dolonchu2d (/ motmetdo2dt 4)) 


(setq dientichdo2dtinh (/ dientichdo2d (* motmetdo2dt motmetdo2dt)))

(setq dientichdo2dtinh (rtos dientichdo2dtinh 2 2))


; (setq dientichdo2dtinh (strcat "S=" dientichdo2dtinh))

(command "TEXT" a dolonchu2d 0 dientichdo2dtinh)


(setvar "osmode" luubatdiem) (setvar "clayer" luulop)
(setvar "MODEMACRO" "**TAILIEUKYTHUAT.COM**")
(princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(DEFUN dochuvi ( )
(command "-style" "thep" "VNI-HELVE" "0" "1" "0" "n" "n")
(princ "\nPHAM QUOC DUY Binh Son - Quang ngai")

(Prompt "\nChon doi tuong") 


(Setq doituongdo (Ssget))
(setq luubatdiem (getvar "osmode")) (setq luulop (getvar "clayer"))
(setvar "osmode" 0)

(if (null motmetdo2d)(setq motmetdo2d "1000"))


(Setq temp T)
(While temp
(setq a (strcat "\nMot met hien hanh la ("motmetdo2d") : ")) 
(Initget "m M")
(setq str (getpoint a))
(Cond
((= str "m") (setq motmetdo2d (getstring (strcat"\nMot met ban ve la <" motmetdo2d "> :"))))
((= str "M") (setq motmetdo2d (getstring (strcat"\nMot met ban ve la <" motmetdo2d "> :"))))
(Progn
(Setq a str)
(setq temp nil)
)
)
)
(command "area" "object" doituongdo)
(setq dientichdo2d (getvar "Perimeter"))

(setq motmetdo2dt (atof motmetdo2d)) 


(setq dolonchu2d (/ motmetdo2dt 4)) 
(setq dientichdo2dtinh (/ dientichdo2d motmetdo2dt))

(setq dientichdo2dtinh (rtos dientichdo2dtinh 2 2))


By Ngọc Nguyễn 2013 Page 96 of 108

; (setq dientichdo2dtinh (strcat "L=" dientichdo2dtinh))

(command "TEXT" a dolonchu2d 0 dientichdo2dtinh)


(setvar "osmode" luubatdiem) (setvar "clayer" luulop)
(setvar "MODEMACRO" "**TAILIEUKYTHUAT.COM**")
(princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(DEFUN dodientichpicdiem ( )

(setq luubatdiem (getvar "osmode")) (setq luulop (getvar "clayer"))


(setvar "osmode" 0)
(picpic)
(command "-boundary" diemchona "")

(setq doituongdo (entlast))

(if (null motmetdo2d)(setq motmetdo2d "1000"))


(Setq temp T)
(While temp
(setq a (strcat "\nMot met hien hanh la ("motmetdo2d") : ")) 
(Initget "m M")
(setq str (getpoint a))
(Cond
((= str "m") (setq motmetdo2d (getstring (strcat"\nMot met ban ve la <" motmetdo2d "> :"))))
((= str "M") (setq motmetdo2d (getstring (strcat"\nMot met ban ve la <" motmetdo2d "> :"))))
(Progn
(Setq a str)
(setq temp nil)
)
)
)
(command "area" "object" doituongdo)
(setq dientichdo2d (getvar "area"))

(setq motmetdo2dt (atof motmetdo2d)) 


(setq dolonchu2d (/ motmetdo2dt 4)) 
(setq dientichdo2dtinh (/ dientichdo2d (* motmetdo2dt motmetdo2dt)))

(setq dientichdo2dtinh (rtos dientichdo2dtinh 2 2))

(command "TEXT" a dolonchu2d 0 dientichdo2dtinh)


By Ngọc Nguyễn 2013 Page 97 of 108

(setvar "osmode" luubatdiem) (setvar "clayer" luulop)


(princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun C:dod ()
(dodegoi))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun dodegoi (/ COM)
(setq DCL_ID (load_dialog (strcat "c:" "\\tailieukythuat\\dcl\\do.DCL")))
(new_dialog "do" DCL_ID)
(action_tile "btn_2d" "(done_dialog 1)")
(action_tile "btn_dtich" "(done_dialog 2)")
(action_tile "btn_chuvi" "(done_dialog 3)")
(action_tile "btn_dtcv" "(done_dialog 4)")
(action_tile "btn_dtichp" "(done_dialog 5)")

(action_tile "btn_thoi" "(done_dialog 14)")

(action_tile "btn_zoom" "(done_dialog 50)")

(start_image "img_1")
(slide_image 0 0 (dimx_tile "img_1")(dimy_tile "img_1") (strcat "c:"
"\\tailieukythuat\\dcl\\lgoduy01.sld"))
(end_image)
(setq phepchon (start_dialog))
(cond 
((= phepchon 1) (dodientichbanghaidiem))
((= phepchon 2) (dodientich))
((= phepchon 3) (dochuvi))
((= phepchon 4) (dtcv))
((= phepchon 5) (dodientichpicdiem))

((= phepchon 14) (thoi))

((= phepchon 50) (zoomduy))

)
By Ngọc Nguyễn 2013 Page 98 of 108

(princ)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;---------------------------------------
(defun nstr (stri def)
(princ stri)
(princ "<")
(princ " ")
(princ def)
(princ ">")
(princ ":")
(princ " ")
);defun nstr
;--------------------
(defun nstr1 (stri)
(princ stri)
(princ "<")
(princ "Nhap vao")
(princ ">")
(princ ":")
(princ " ")
);defun nstr1
;---------------------
(defun nint (prompt def / temp)
(if def
(setq temp (getint (nstr prompt def)))
(setq def (getint (nstr1 prompt)))
);if def
(if temp
(setq def temp)
def
);if temp
);defun nint
;---------------------
(defun dnint (prompt def / temp)
(if def
(setq temp (getreal (nstr prompt def)))
(setq def (getreal (nstr1 prompt)))
);if def
(if temp
(setq def temp)
def
By Ngọc Nguyễn 2013 Page 99 of 108

);if temp
);defun nint
;--------------------
(defun ndist (po prompt def / temp) ;nhan kh/cach va luu gia tri mac dinh
(if def
(setq temp (getdist po (nstr prompt def)))
(setq def (getdist po (nstr1 prompt)))
)if def
(if temp
(setq def temp)
def
);if temp
);defun ndist
;-----------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(Defun zoomduy ( )
(command ".zoom" "")
(Princ)) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(Defun thoi ()
(princ "\nPHAM QUOC DUY Binh Son - Quang ngai")
(setvar "MODEMACRO" "**TAILIEUKYTHUAT.COM**")
(Princ)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
By Ngọc Nguyễn 2013 Page 100 of 108

Lisp Thống kê thép.

*Tiện ích thống kê thép bao gồm 3 tiện ích thống kê:
+TKTT: Thống kê thép tròn.
+TKTH: Thống kê thép hình.
+TKTM: Thống kê thép mã.

*Thống kê thép tròn:


-Tên lệnh: TKTT.
By Ngọc Nguyễn 2013 Page 101 of 108

-Xuất hiện hộp thoại chính

-Để tạo bảng mới bạn nhấn nút bat dau. Hỏi điểm chèn bạn kích 1 điểm lisp chèn bảng tiêu đề và
xuất hiện bảng 24 hình dáng thép + vài loại cấu kiện hay dùng.

+Bạn chọn các kiểu cấu kiện ví dụ seno thì lisp sẽ hỏi bạn trình tự các thanh thép của sê nô.
Hoặc chọn hình dáng thép bằng cách kích vào ô có hình thanh thép cần chọn và nhấn enter hoặc
nút thống kê. Lisp sẽ hỏi bạn các thông số bạn trả lời. Lisp sẽ tính ra tổng chiều dài và trọng
lượng.
+Lưu ý khi lisp hỏi số lượng thanh mình chuẩn bị cả chức năng tính toán số thanh. Nếu bạn đã
tính dược số thanh thì cứ nhập vào còn nếu muốn tính toán thì nhập vào số 0 enter lisp sẽ hỏi bạn
By Ngọc Nguyễn 2013 Page 102 of 108

chiều dài rải bạn nhập vào, lisp hỏi bạn khoảng cách rải bạn nhập vào lisp sẽ chia chiều dài cho
khoảng cách sau đó +1 và ghi vào chổ số lượng thanh.
+Lisp tự động xuống hàng và cộng số thứ tự thêm 1 đơn vị, khi nào hết cấu kiện thì bạn chọn nút
kekhung hoặc gỏ k thì lisp sẽ kẻ khung và hỏi số cấu kiện, tên cấu kiện, set số thứ tự thanh trở về
giá trị 1.
+Khi nào hông thống kê nửa thì nhấn nút thoi để thoát khỏi lệnh.

-Khi đã có bảng thì không chọn bắt đầu mà chọn tiếp tục sau đó chọn điểm dưới bên trái của
bảng hiện có để tiếp tục thống kê vào bảng. Khi lisp hỏi số thứ tự bắt đầu thì nhập vào bao nhiêu
nó sẽ lấy số thứ tự đó mà bắt đầu.

-Muốn chỉnh bảng thống kê thì bạn làm như sau:


+Cứ dùng lệnh ddedit để sửa các số muốn sửa.
+Xong gỏ lệnh TKTT chọn nút chinhbang. Chọn điểm trên bên trái và điểm dưới bên phải (nhớ
chừa cái tiêu đề ra à nha) ngồi chờ coi cái lisp nó đọc rồi tính lại kết quả cho bạn.
-Để tổng hợp thép làm như sau:
+Gỏ lệnh TKTT chọn nút tonghop nó lên hộp thoại sau:

+Chọn nút caukien: chọn điểm trên bên trái và dưới bên phải của từng cầu kiện. Bạn thấy lisp
đọc và viết số cấu kiện ra phía trước từng dòng của cấu kiện. Làm hết cho tất cả các cấu kiện.
+Chọn nút tonghop: Chọn điểm trên bên trái và điểm dưới bên phải (nhớ chừa cái tiêu đề ra à
nha) chỉ 1 điểm để xuất kết quả. Các số cầu kiện ghi hồi nảy sẽ tự động mất đi.

*Thống kê thép hình:


-Tên lệnh: TKTH.
-Xuất hiện hộp thoại chính.
By Ngọc Nguyễn 2013 Page 103 of 108

-Chọn bắt đầu hoặc tiếp tục: xuất hiện hộp thoại.

-Bạn chọn loại thép hình muốn thống kê và làm theo cân hỏi lisp đưa ra.

*Thống kê thép mã: Cách dùng tương tự.


@Chức năng tổng hợp và chỉnh bảng chỉ có trong thống kê thép tròn.

Cần làm theo Hướng Dẫn khi dùng lisp này!

-Tại ổ C bạn tạo thư mục TAILIEUKYTHUAT bên trong có các thư mục:


+DWG
+DCL
+LENH 
-Bạn copy vào trong các thư mục này với vị trí như sau:
+File *.dwg thì chép vào thư mục DWG.
+File *.dcl thì chép vào thư mục DCL.
+File *.sld thì chép vào thư mục DCL.
+File *.txt thì chép vào thư mục DCL.
+File *.lsp thì chép vào thư mục LENH.
By Ngọc Nguyễn 2013 Page 104 of 108

-Bạn phải chắn chắn rằng đã làm đúng các bước trên thì lisp mới chạy được vì mình dùng đường
dẩn cố định trong các lisp này.
By Ngọc Nguyễn 2013 Page 105 of 108

Các tiện ích về text 3

*Tiện ích thay đổi nội dung của các TEXT, MTEXT, DIM theo đối tượng mẫu. 
-Tác dụng giống lệnh ma của cad nhưng chỉ thay đổi nội dung TEXT, MTEXT, DIM .

-Tên lệnh: MAT


-Thao tác:
+Nhập lệnh MAT
+Chọn đồi tượng mẫu có thể là TEXT, MTEXT, DIM nều không chọn được đối tượng hoặc đối
tượng chọn không thuộc 3 loại trên thì hỏi lại đến khi chọn được thì làm dấu bằng dấu + màu
xanh lá.
+Hỏi chọn các đối tượng muốn thay đổi, bạn có thể chọn bằng cửa sổ lisp sẽ chỉ nhận các đối
tượng là TEXT, MTEXT, DIM trong vùng chọn.
+Nhấn enter các đối tượng được chọn sẽ có nội dung giống y như đối tượng mẫu.
By Ngọc Nguyễn 2013 Page 106 of 108

Lisp dời điểm chèn block

Bạn có bản vẽ mà trong đó có cái block đã chèn nhiều vị trí, rotate, scale, mirror chuyễn layer
nói chung là lung tung hết cả và đến 1 lúc bạn nhận ra cái điểm chèn của nó lúc tạo ra lại không
nằm đúng chổ mình ưng tí nào bạn muốn chuyển cái điểm chèn này vào ngay tâm block để tiện
chỉnh sửa làm sao đây :

Bạn copy nội dung và tạo file lisp hay tải file về cũng được!

(defun c:dbl ()
(command "undo" "be")

(setq doituong1 (entsel "\nChon Block muon chinh diem chen"))


(while
(or
(null doituong1)
(/= "INSERT" (cdr (assoc 0 (entget (car doituong1)))))
)
(princ "\nDoi tuong khong phai la Block! Chon lai")
(setq doituong1 (entsel "\nChon Block muon chinh diem chen"))
)

(command "ucs" "ob" doituong1)


(setq DIEMCHENMOI (getpoint "\n Chon diem chen moi cho Block nay :"))
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)
(command "layer" "s" 0 "")
(setq doituong (car doituong1))
(setq doituong (entget doituong))
(setq TENKHOI (cdr (assoc 2 doituong)))
(setq TENKHOIMOI (strcat TENKHOI "TAOTHEM"))
(setq TYLEX (cdr (assoc 41 doituong)))
(setq TYLEY (cdr (assoc 42 doituong)))
(setq DIEMTINH (list (/ (car DIEMCHENMOI) TYLEX) (/ (cadr DIEMCHENMOI) TYLEY)))
(setq XDIEMTINH (car DIEMTINH))
(setq YDIEMTINH (cadr DIEMTINH))
(setq DAICHUAS (distance (list 0 0) DIEMTINH))
(setq GOCCHUAS (angle (list 0 0) DIEMTINH))
(setq DIEMCHENTUONGDOI (polar (LIST 0 0) GOCCHUAS DAICHUAS))
(command ".INSERT" TENKHOI (LIST 0 0) 1 1 0)
(Command "EXPLODE" "last" "")
(Command "Block" TENKHOIMOI DIEMCHENTUONGDOI "Previous" "")
(command "ucs" "p")
By Ngọc Nguyễn 2013 Page 107 of 108

(setq xx (ssget "X" (list( cons 0 "INSERT") (cons 2 TENKHOI))))

(setq L 0)
(setq M (sslength XX))
(while (< L M)
(setq DTs (ssname XX L))
(setq DTMs (entget DTs))
(command "ucs" "ob" DTs)
(setq TYLEX1 (cdr (assoc 41 DTMs)))
(setq TYLEY1 (cdr (assoc 42 DTMs)))
(setq DIEMDOI (list (* XDIEMTINH TYLEX1) (* YDIEMTINH TYLEY1)))

(setq DTMs (subst (cons 2 TENKHOIMOI) (assoc 2 DTMs) DTMs))


(entmod DTMs)
(setq DIEMDOI (trans DIEMDOI 1 0))
(setq DTMs (subst (cons 10 DIEMDOI) (assoc 10 DTMs) DTMs))
(entmod DTMs) 
;(command "move" DTs "" (list 0 0) DIEMDOI)
(command "ucs" "p")
(setq L (1+ L))
)

(setvar "osmode" luubatdiem)


(Command "Purge" "B" TENKHOI "Y" "Y") 
(command "rename" "b" TENKHOIMOI TENKHOI)
(command "undo" "end")

(princ (strcat "\nVua chinh tam cua block <" TENKHOI "> :" (itoa L) " doi tuong"))
(setvar "MODEMACRO" "**CHUC BAN LAM VIEC HIEU QUA** PHAM QUOC DUY -
BINH SON - QUANG NGAI")
(Princ))
By Ngọc Nguyễn 2013 Page 108 of 108

0 NONe
1 ENDpoint
2 MIDpoint
4 CENter
8 NODe
16 QUAdrant
32 INTersection
64 INSertion
128 PERpendicular
256 TANgent
512 NEArest
1024 QUIck
2048 APParent Intersection
4096 EXTension
8192 PARallel

Osmode = Tổng osnap cần

You might also like