Huong Dan Viet LISP [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

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. = 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 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

) (if (/= timfile nil) (PROGN (command "INSERT" "c:\\tailieukythuat\\dwg\\caodo.dwg" a 1 1 0) ) ) (setvar "osmode" luubatdiem) (command "undo" "end") (princ) )

Page 29 of 108

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

(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) )

Page 32 of 108

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

) ) (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) )

Page 34 of 108

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 " ") );defun nstr ;-------------------(defun nstr1 (stri) (princ stri) (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

;--------------------(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")

Page 40 of 108

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

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)))

Page 46 of 108

By Ngọc Nguyễn 2013

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:

Page 47 of 108

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: "))) (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: "))) (if (= giatric "")

By Ngọc Nguyễn 2013

(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)))

Page 49 of 108

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 "[" 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 "[" 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 "[" 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 "[" ndtruoc "]") filemns) (docghigiuapop1xle)) ((/= ndsau "menuxeplop")  (cond ((= ndsau "mnduongphancach") (write-line "[---]" filemns)) ((/= ndsau "mnduongphancach")

By Ngọc Nguyễn 2013

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