Chuyển đến nội dung
Diễn đàn CADViet
Jin Yong

Hỏi về Lisp (thuật toán, ý tưởng, coding,...)

Các bài được khuyến nghị

Oh, Cảm ơn bác Tot77 nhiều. Đúng là cái Reactor không bị mất đi khi đóng và mở lại bản vẽ (điều kiện là phải load các hàm con trong lsp khi mở lại bản vẽ)

 

Xin bác cho hỏi có cách nào dùng Reactor mà lưu giữ lại giá trị trong lsp được không? Ví dụ mình vẽ dim từ A1... đến A3... rồi. Giờ đóng bản vẽ và mở lại bản vẽ mình muốn ghi tiếp giá trị là A4... có được không?

Hiện tại thì khi đóng và mở lại bản vẽ thì lsp ghi lại từ đầu A1...

 

Cảm ơn bác nhiều!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cảm ơn bác Tot77. Việc sử dụng biến hệ thống USERR1-5 thì mình cũng biết. Chỉ muốn hỏi là Reator có thể lưu lại giá trị hay không? Mình đoán chắc là không ^_^

 

1 điểm nữa là khi sử dụng ví dụ trong code của bác. Vấn đề nảy sinh là khi tắt và mở lại bản vẽ thì sử dụng Reactor vẫn còn đó. Tuy nhiên sử dụng lệnh TAT để tắt liên kết đi thì không được

Command: tat ; error: bad argument type: VLReactor: nil 

 

Cái này mình thấy lỗi do đối số do biến reactor chưa được khởi tạo khi mở lại bản vẽ

(bởi do khi mở bản vẽ không dùng lệnh bat để khởi tạo biến reactor mà trong thân hàm lệnh TAT đã sử dụng biến reactor rồi (defun c:tat() (if (vlr-added-p reactor) 

 

Một điểm nữa là khi tắt và mở lại bản vẽ là cho dù dùng lệnh bat để khởi tạo reactor nhưng dùng lệnh TAT thì không thể "tắt" được cái Reactor đó. Bác xem lại chỗ này giúp mình với. Cảm ơn bác!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Vấn đề này mình cũng đã trao đổi 1 lần ở topic nào đó về Reactor. Tue_NV hỏi trong topic này nên mình nhắc lại luôn tại đây.

Bạn để ý cấu trúc hàm tạo ra 1 reactor bất kỳ đều có 1 đối số là data. Mọi người thường để nil vì không biết nó làm được những gì, hoặc không sử dụng nó. Với mình thì ứng dụng của nó là rất lớn. Bạn có thể ghi thông tin cần lưu giữ vào nó.

 

- Data chấp nhận mọi kiểu dữ liệu, kể cả là một hàm hay 1 đoạn code thực thi.

- Data của 1 reactor không bị đóng chết nội dung theo nội dung bạn ghi vào nó khi tạo ra reactor. Bạn có thể đọc, sửa, ghi đè và xóa nó bất kỳ lúc nào bạn muốn, kể cả ngay trong quá trình thực thi callback của chính nó.

- Data không giới hạn kích thước thông tin (bit) ghi vào nó.

 

Xét về hình thái dữ liệu và tiềm năng sử dụng thì data tương đối giống xrecord nhưng có ưu nhược điểm sau:

- Dễ tạo, dễ truy xuất và chỉnh sửa, sử dụng linh hoạt với reactor.

- Dễ bị vô tình xóa đi bởi 1 ứng dụng khác có sử dụng các hàm xóa reactor. Xrecord thì chỉ người lập trình ra ứng dụng mới truy cập được nên bảo vệ dữ liệu tốt hơn.

------------------------------------

Mình trả lời nội dung bạn hỏi Tot77 luôn.

Có thể tot77 viết 1 ví dụ cho bạn vì câu hỏi #2449 nên viết như vậy chứ nếu viết ứng dụng hoàn chỉnh thì không viết kiểu vậy được. Sẽ tạo ra rác reactor sau mỗi lần tắt mở bản vẽ. 

Việc sử dụng 1 biến đển nhận diện 1 reactor chỉ phù hợp khi reactor đó được tạo ra và xóa đi trong 1 lệnh cụ thể. Khi tạo ra reactor dạng "chạy nền" thì phải sử dụng data đẻ nhận diện 1 reactor. sẽ tránh được trường hợp như trên. Để xác định 1 reactor, bạn cần kết hợp các hàm Vlr-reactors và Vlr-data

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Đúng như ThuyLinh nói, ví dụ trên chỉ minh hoạ cho cái vlr-pers thôi, vì vây ko đăt tên cho reactor.

Nếu muốn viết kỹ hơn thì sửa hàm bat như sau:

 

(defun c:bat(/ DATA REACTORS)
(setq data (mapcar 'vlr-data  (setq reactors (cdar (vlr-reactors :vlr-command-reactor)))))
  (if (not (member "comreactor" data))
    (setq reactor (vlr-pers (vlr-command-reactor "comreactor" '((:vlr-commandEnded . EndCommand)))))
(setq reactor (nth (vl-position "comreactor" data) reactors))
)
  (princ)
)

và thêm dòng (c:bat) ở cuối file.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Chào các anh em, các bác! Cho em làm phiền (hỏi lạc đề với các mục trên) 1 chút ạ!

Em muốn đếm số lẻ phần thập phân của một số nhưng khi thực hiện thì không đúng như yêu cầu.

Em dùng hàm như sau:

(strlen (substr (rtos (float Number)) (+ (vl-string-search "." (rtos (float Number))) 2) (strlen (rtos (float Number))))) 

Ví dụ: (setq Number 0.0993347)

Nhưng giá trị lại trả về 4 do hàm (rtos (float Number)) = "0.0993"

Các bác có thể tư vấn cho em được không ạ? Em cảm ơn các bác nhiều!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
 

- ý tưởng thô thiển của nhoc là trong lsp set unit tối đa 8 số lẽ ^^, chuyển số thành chuỗi, đảo ngược chuổi, loại bỏ các số 0 dư, cuối cùng là đếm hihi, nếu số thập phân của anh dài hơn 8 số lẽ thì nhoc chưa nghĩ ra ^^

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cảm ơn em nhoclangbat và bác ntdnv. 

Em đang định dùng thuật toán kiểm tra số có phải là số nguyên ko? Nếu ko phải số nguyên thì nhân tiếp 10 cho đến khi đúng điều kiện số nguyên thì dừng vòng lặp.

Không biết cách này ổn ko?

Em cũng đang test

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cảm ơn bác Doan Van Ha!

Em cũng thử cách của bác nhưng sao nó vẫn không ra kết quả bác nhỉ?

(defun C:00 (  / loop I NUMBER TXT)
(setq i 1)
(setq Number 0.0993347)
(setq loop nil)
(while loop
  	(cond
	  (T
		(if (not (equal Number (fix Number) 1e-15))
		    (setq Number (* Number 10))
		    (setq loop T)
		)
	  )
	)
  	(setq i (1+ i))
)
(Princ i)
(princ)
)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Anh không hiểu nhu cầu của em, nhưng loop=nil thì còn while gì nữa. Chắc muốn thế này:

 

(defun C:11 ( / I NUMBER)
 (setq i 0)
 (setq Number 0.0993347)
 (while (not (equal Number (fix Number) 1e-15))
  (setq Number (* Number 10))
  (setq i (1+ i)))
 (Princ i)
 (princ))
  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
(defun LenCurve (cur) 
(vlax-curve-getDistAtParam cur (vlax-curve-getEndParam cur)) ) 
(defun C:CK (/ e k p ps pe L fuzz kc p0 flag p1 OK kc1) (vl-load-com)
(setq e (car (entsel "\nChon curve:")) 
k (getreal "\nKhoang cach giua 2 diem theo duong thang:") 
p (trans (getpoint "\nChon diem tai 1 in 2 dau mut :") 1 0)
ps (vlax-curve-getStartPoint e) 
pe (vlax-curve-getEndPoint e) L (LenCurve e) fuzz 1e-8)
(cond ((equal p ps fuzz) (setq kc k p0 ps flag 1))
((equal p pe fuzz) (setq kc (- L k) p0 pe flag -1))
((alert "Phai chon diem bat dau tai 1 trong 2 dau mut!"))	)
(setq p1 p0) (while p1 (setq OK nil) (while (not OK) 
(setq p1 (vlax-curve-getPointAtDist e kc) kc1 (distance p0 p1)) 
(if (equal kc1 k fuzz) (setq OK T) (setq kc (+ kc (* flag (- k kc1)))))
(if (equal p1 ps fuzz) (exit))	) 
(if p1 (entmake (list (cons 0 "POINT") (cons 10 p1))))
(setq p0 p1) (setq kc (+ kc (* flag k)))	) (princ))

Đây là lisp chia các điểm cách đều trên Objects như : line, pline, spline, arc... lisp chạy tốt nhưng không hiểu sao lại luôn báo lỗi : error: bad argument type: 2D/3D point: nil . Cho em hỏi cách khắc phục nó ạ :( .

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cái này chắc ok.

 

(defun LenCurve (cur)
(vlax-curve-getDistAtParam cur (vlax-curve-getEndParam cur))
)
(defun C:CK (/ e k p ps pe L fuzz kc p0 flag p1 OK kc1)
(vl-load-com)
(setq e  (car (entsel "\nChon curve:"))
k  (getreal "\nKhoang cach giua 2 diem theo duong thang:")
p  (trans (getpoint "\nChon diem  bat dau tai 1 trong 2 dau mut :") 1 0)
ps  (vlax-curve-getStartPoint e)
pe  (vlax-curve-getEndPoint e)
L  (LenCurve e)
fuzz 1e-8
)
(cond ((equal p ps fuzz)
(setq kc k
p0 ps
flag 1
)
)
((equal p pe fuzz)
(setq kc (- L k)
p0 pe
flag -1
)
)
((alert "Phai chon diem bat dau tai 1 trong 2 dau mut!"))
)
(setq p1 p0)
(while p1
(setq OK nil)
(while (and (not OK) (setq p1 (vlax-curve-getPointAtDist e kc))) 
(setq kc1 (distance p0 p1))
(if (equal kc1 k fuzz)
(setq OK T)
(setq kc (+ kc (* flag (- k kc1))))
)
(if (equal p1 ps fuzz)
(exit)
)
)
(if p1
(entmake (list (cons 0 "POINT") (cons 10 p1)))
)
(setq p0 p1)
(setq kc (+ kc (* flag k)))
)
(princ)
)
  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Anh Tot77 hay thật :) , tìm mãi mà không biết lỗi ở đâu chỉ mang máng nghi ngờ từ vòng lặp while thứ 2 mà ko biết sửa sau :P . thank u!!!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Sau khi sử dụng hàm SSGET để chọn các đường pline bằng hàm

(setq SSS (ssget "C" diemdau diemtren1 fltr)), khi chạy chương trình nó xử lý từ dưới lên trên bây giờ mình muốn nó xử lý từ trên xuống dưới

Nhờ mọi người giúp đỡ sắp xếp lại thứ tự các pline từ trên xuống dưới (chỉ sắp xếp theo tọa độ Y)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Bạn có thể nói rõ hơn không?

Mình đang viết lisp điền cao độ của các lớp đắp k98. đã chạy ok rồi nhưng còn vướng 1 cái là đánh số thứ tự cho các cao độ. hiện tại là nó đánh số từ dưới lên bây giò muốn đánh từ trên xuống

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình đang viết lisp điền cao độ của các lớp đắp k98. đã chạy ok rồi nhưng còn vướng 1 cái là đánh số thứ tự cho các cao độ. hiện tại là nó đánh số từ dưới lên bây giò muốn đánh từ trên xuống

Nếu chạy OK rồi thì chỉ cần dùng hàm (reverse list) để đảo chiều là đuợc.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Thay vì ssget "C" bạn thử dùng ssget "F" như này xem sao.

 

(defun c:te (/ A N SS) 
(setq ss (ssget "f" (list (setq a (getpoint)) (getpoint a)))
n 0)
(while (> (sslength ss ) 0)
(command "change" (ssname ss 0) "" "P" "c" (itoa (setq n (1+ n))) "")
(ssdel (ssname ss 0) ss)
)
)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mọi người cho hỏi em sai chỗ nào với:

Command: (setq pt1 (getpoint))
(-3638.75 -3687.08 0.0)
Command: (setq pt2 (getpoint))
(-4289.96 -1634.83 0.0)
Command: (getdist pt2 pt1)
; error: bad argument type: stringp: (-3638.75 -3687.08 0.0)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Khi xuât dữ liệu từ cad qua excel 

Muốn xuống dòng dùng lệnh (princ "\n" fid)

Muốn bỏ qua 1 cột dùng (princ "," fid)

Muốn bỏ qua 3 cột dùng (princ "," fid) (princ "," fid) (princ "," fid)

Khi muốn bỏ qua nhiều hơn 3 cột không thể dùng lệnh như trên được nữa.

Nhờ mọi người giúp đỡ 

Cám ơn nhiều

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Thử dùng (princ ",,,,,,,,,," fid) xem sao.

Cám ơn bạn đã giúp đỡ mình đã làm được. Cho mình hỏi thêm tí nữa có lệnh nào để kiểm tra vị trí ô chuột đang đứng có dữ liệu hay không???

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay


×