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

Routine tính tổng chiều dài các đối tượng

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

Ới các bác NguyenHoanh và SSG,

Em cám ơn các bác nhiều vì đã giải thích cho em hiểu nhiều thứ, không chỉ là về lisp. Song bác SSG ạ, em muốn hỏi lại bác là cái Help mà bác nói có phải là của Acad không hay là Help của lisp? Mà Help của lisp thì em chả mò được nó ở đâu. Còn ở trong Acad thì thú thực là em cũng chửa tìm vì mở ra thấy nó như rừng, sợ lạc lối bác ạ. Về hàm or thì em tìm trong help của Acad đâu có thấy.

Các bác thông cảm cho em vì em mới lọ mọ vào lisp được mấy bữa chưa rành đường đi nước bước mà. Nói như dân chơi cờ tướng là "chưa sạch nước cản" ấy. Vì thế mong được các bác động viên nhiều chứ thật tình nhiều lúc cũng thấy mình hỏi ngớ ngẩn làm phiền các bác. Tuy nhiên cái em hỏi là thật sự em không biết chứ chả phải giả ngố đâu, các bác đừng giận. Mọi điều các bác chỉ em đều cố thực hiện cả đấy, hy vọng sẽ dần dần khá lên để các bác đỡ ngán cái đồ học mót này.

Bạn đừng vào Help bình thường mà vào Developer Help.

Cái gì cũng có ở "trỏng". Ví dụ, wcmatch ở đây:

 

http://www.cadviet.com/upfiles/dev_help.jpg

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

Ới bác NguyenHoanh ơi,

Em vẫn chưa hiểu vì theo định nghĩa của chương trinh thì e_type là một biến chứ không phải một hàm. Vậy khi xác định giá trị cho biến thì phải dùng hàm setq chứ.

Ở đây không dùng hàm setq mà lại viết ngang xương là (e_type (ssdel e_name ss)) như kiểu một hàm trong lisp. Và nếu dùng hàm setq ở đây (setq e_type (ssdel e_name ss)) thì biến e_type lúc này sẽ mang thuộc tính khác với biến e_type ban đầu (setq e_type (cdr (assoc '0 e_name))) mất. Cho nên em mới càng khó suy luận thêm.

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ưa bác SSG,

ối gời ơi, cám ơn bác lắm lắm. Em thấy rồi, sẽ cố học hành tử tế theo bác chỉ. Tuy nhiên, cái vốn tiếng Anh của em cũng nhờ mót mà có nên nó lởm khởm lắm. Vì vậy chắc vẫn phải cạy cửa bác dài dài. Bác đừng giận nhé. Cả tiếng Anh em cũng sẽ cố, 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
Ới bác NguyenHoanh ơi,

Em vẫn chưa hiểu vì theo định nghĩa của chương trinh thì e_type là một biến chứ không phải một hàm. Vậy khi xác định giá trị cho biến thì phải dùng hàm setq chứ.

Ở đây không dùng hàm setq mà lại viết ngang xương là (e_type (ssdel e_name ss)) như kiểu một hàm trong lisp. Và nếu dùng hàm setq ở đây (setq e_type (ssdel e_name ss)) thì biến e_type lúc này sẽ mang thuộc tính khác với biến e_type ban đầu (setq e_type (cdr (assoc '0 e_name))) mất. Cho nên em mới càng khó suy luận thêm.

Bạn đọc thêm về cấu trúc lệnh cond:

 

(cond [(test result ...) ...])

The cond function accepts any number of lists as arguments. It evaluates the first item in each list (in the order supplied) until one of these items returns a value other than nil. It then evaluates those expressions that follow the test that succeeded.

 

Return Values

 

The value of the last expression in the sublist. If there is only one expression in the sublist (that is, if result is missing), the value of the test expression is returned. If no arguments are supplied, cond returns nil.

 

Examples

 

The following example uses cond to perform an absolute value calculation:

 

(cond

((minusp a) (- a))

(t a)

)

If the variable a is set to the value -10, this returns 10.

 

As shown, cond can be used as a case type function. It is common to use T as the last (default) test expression. Here's another simple example. Given a user response string in the variable s, this function tests the response and returns 1 if it is Y or y, 0 if it is N or n; otherwise nil.

 

(cond

((= s "Y") 1)

((= s "y") 1)

((= s "N") 0)

((= s "n") 0)

(t nil)

)

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ưa bác Nguyen hoanh,

Ơ hơ, thế là em hiểu rồi ạ. Nhưng bác này, vậy là biến e_type lúc này sẽ có giá trị là một bộ lựa chọn mới trích từ biến bộ lựa chọn ss mà vứt đi cái thắng có e_name đã xài phải không bác. Vậy thì nên xài là (ss (ssdel e_name ss)) có phải là dễ hiểu hơn không ạ? Bởi vì ở trên đã xác định biến e_type là kiểu loại đối tượng rồi (setq e_type (cdr (assoc '0 e_record))). Tất nhiên em hiểu là khi bước vào bước lặp kế tiếp thì e_type lại được định nghĩa lại rồi nên chả ảnh hưởng gì sất, xong trong cùng một câu chuyện mà bắt người đọc phải hiểu cái tên Tí cho hai thằng cởi truồng thì cũng hơi hơi áy náy ạ.

Em nói vậy bác thấy có hỗn không? Nếu có thì em xin lỗi bác trước nhé.

Em lại hỏi bác cái này nhé. Em đọc ở chủ đề này có mấy cái củ lisp của bác SSG hay là Vn...dos gì đó, khoái quà mót về xài thữ. xong chửa có xài được gì vì mới gặm thử cái lisp phantichline thì Acad nó trả lời là ;error too few arguments. Em đang mò mẫm mà chửa biết sai chỗ nào bác ạ. Lúc đầu khi load thì nó báo ; error malformed list on input, em mò mẫm tìm thì té ra là thiếu mất một cái ngoặc đóng kết thúc hàm defun, em bổ xung vào thì lại tòi ra cái lỗi trên bác ạ.

Vậy bác hoặc các bác ssg, Vn..dos kiểm tra lại và giúp em với nhé.

Còn cái lisp tính tổng độ dài của các loại đối tượng trên một lớp của bác SSG thì phải, khi em xài thử thì thấy chạy phà phà. Nhưng khi em tách hàm (vlax-curve-getendparham (entsel "\n chon doi tuong")) ra để xài riêng bằng cách nhập trực tiếp trên dòng nhắc lệnh của Acad2004 thì nó chả chịu chạy cứ bảo là không có function này, mặc dù trước khi chạy dòng mã này em đã chạy hàm (vl-load-com) trực tiếp từ dòng nhắc lệnh của Acad2004. Vậy là sao các bác nhỉ?

Mấy cái củ lisp còn lại trong chủ đề này em cũng đang gặm ạ.

Em muốn trích dẫn các bài viết của các bạn khác trên diễn đàn vào bài viết của mình thì làm thế nào ạ? Thấy các bác làm ào ào bắt ham mà "hổng dám đâu" vì chưa biết.

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 bạn một lisp "cực ngắn" theo đúng yêu cầu, tên lệnh là TL. Bạn có thể tuỳ nghi sửa đổi theo ý thích:

;;;--------------------------------------------------------------------
(defun Length1(e) (vlax-curve-getDistAtParam e (vlax-curve-getEndParam e)))
;;;--------------------------------------------------------------------
(defun C:TL( / Lay ss L e)
(setq
Lay (getstring "\nLayer name:")
ss (ssget "X" (list (cons 0 "LINE,ARC,CIRCLE,POLYLINE,LWPOLYLINE,ELLIPSE,SPLINE")
	 (cons 8 Lay)))
L 0.0
)
(vl-load-com)
(while (setq e (ssname ss 0))
(setq L (+ L (length1 e)))
(ssdel e ss)
)
(alert (strcat "Total length of all objects in layer " Lay " = " (rtos L)))
)
;;;--------------------------------------------------------------------

Bài này tuy lâu rồi nhưng xin phép khai quật lại!

Cho mình hỏi là cái này là tính tổng chiều dài theo layer

Nhưng bạn có thể thêm cho chức năng tính theo màu (color) có được ko?

đã seach trên diễn đàn không thấy có rồi mới hỏi đấy nhé

xin cảm ơ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

Xin được trả lời bạn:

1/ dấu ' có hay không trong 2 trường hợp trên đều như nhau. Có dấu phẩy thì số 0 được xem như là biến, không có dấu phẩy thì số 0 được xem như là hằng số. Bạn cũng không nên quan tâm đến nó làm gì vì điều đó không cần thiết. Điều những người viết lisp nên biết là có dấu phẩy thì khi chạy, lisp không cần phải sinh ra một ô nhớ trung gian nữa và sẽ chạy nhanh hơn một chút so với khi không có dấu phẩy. That's enough!

 

2/

Hỏi: Đoạn mã (wcmatch e_type "LINE,ARC,CIRCLE,POLYLINE,LWPOLYLINE,ELLIPSE,SPLINE") bạn học ở đâu vậy?

Đáp: Câu hỏi này quá khó nên tôi không trả lời được.

 

Hỏi: Cú pháp của hàm WCMATCH này ra sao?

Đáp: Câu hỏi quá dễ, hàm WCMATCH là hàm rất cơ bản, bạn hãy tự tìm hiểu.

 

Hỏi: có phải chỉ có duy nhất một cú pháp bạn dùng hay không hay còn có các cú pháp khác nữa?

Đáp: Còn nhiều cú pháp khác. Không chỉ trong autolisp, thường thì mọi vấn đề đều có nhiều sắc thái.

 

Hỏi: Tôi hiểu nôm na cái cú pháp của bạn là một dạng của hàm OR phải không?

Đáp: Bạn hiểu nôm na gần đúng.

 

Hỏi: Nếu tôi sửa thành (Or e_type "line,arc, circle, polyline, lwpolyline,..... ") thì sẽ có vấn đề gì nhỉ?

Đáp: Không hề hấn gì, chỉ có điều không liên quan đến mã lệnh wcmatch tẹo nào!

 

Hỏi: Đại khái tôi hiểu cái hàm wcmatch của bạn nói rằng khi biến E_type là một trong các giá trị có mặt trong chuỗi bạn mô tả thì .... có phải không?

Đáp: Bạn hiểu đại khái rất chính xác.

buồn cười quá thanks bác phát, nhưng mà rất thú vị em nghịch list thấy rất thích chưa từng chú ý tới mí cái này hêhhe

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

Nhờ sự giúp đỡ của bác Nguyễn Hoành em có viết 1 đoạn code nhằm tính tổng chiều dài của các đối tượng chọn (*Line, Arc, Circle, Elippse). Các bác dùng thử và cho ý kiến.

Một lần nữa xin cảm ơn bác Hoành về sự nhiệt tình giúp đỡ anh em.

Chúc cả nhà luôn vui..

 

(defun add_mline ()  (foreach e_record_sub	e_record    (cond ((= 10 (car e_record_sub))       (setq pt1       (cdr e_record_sub)	     mline_len 0.0       )  	)  	((= 11 (car e_record_sub))       (setq pt2       (cdr e_record_sub)	     mline_len (+ mline_len (distance pt2 pt1))	     pt1       pt2       )  	)    )  )  (setq tot_len (+ tot_len mline_len))  (ssdel e_name ss));;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defun C:tg (/ tot_len ss e_name e_record e_type)  (setq tot_len 0.0)  (setq ss (ssget))  (if (null ss)    (exit)  )  (while (> (sslength ss) 0)    (setq e_name (ssname ss 0))    (setq e_record (entget e_name))    (setq e_type (cdr (assoc '0 e_record)))    (cond ((wcmatch e_type "LINE,ARC,CIRCLE,POLYLINE,LWPOLYLINE,ELLIPSE,SPLINE")       (command "lengthen" e_name "")       (setq tot_len (+ tot_len (getvar "PERIMETER")))       (ssdel e_name ss)  	)  	((wcmatch e_type "MLINE") (add_mline))  	(e_type (ssdel e_name ss))    )  )  (prompt (strcat "\nTotal length is: " (rtos tot_len 2 2)))  (princ))

Các pro làm ơn cho em hỏi cách để thực hiện được lệnh này thế nào ạ? Em làm mãi mà không được! Em down về mà không dùng lệnh đượ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

huhu! Không đc ạ. Báo load thanh công rồi mà tắt cad đi, mở file cad cần tính ra dùng lệnh "tg" thì nhận được câu xanh rờn:" Press F1 for help"...cứu em các Bác ơi. E dùng cad 2007 có ảnh hưởng gì ko ạ???

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

Sao bạn không đọc bài hướng dẫn sử dụng lisp (trên box Autolisp hoặc Google) hơn là kêu ca nhỉ ^^ ? File lisp khi load chỉ có tác dụng với file hiện hành đó, phiên làm việc đó. Khi tắt đi bật lại hoặc sử dụng với window khác đều không được, trừ khi bạn cho nó vào Startup suite

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

Sao bạn không đọc bài hướng dẫn sử dụng lisp (trên box Autolisp hoặc Google) hơn là kêu ca nhỉ ^^ ? File lisp khi load chỉ có tác dụng với file hiện hành đó, phiên làm việc đó. Khi tắt đi bật lại hoặc sử dụng với window khác đều không được, trừ khi bạn cho nó vào Startup suite

 

Sao bạn không đọc bài hướng dẫn sử dụng lisp (trên box Autolisp hoặc Google) hơn là kêu ca nhỉ ^^ ? File lisp khi load chỉ có tác dụng với file hiện hành đó, phiên làm việc đó. Khi tắt đi bật lại hoặc sử dụng với window khác đều không được, trừ khi bạn cho nó vào Startup suite

Cảm ơn Bác Ketxu. Em đã đọc rồi, và làm theo y như hướng dẫn...thế mà vẫn báo press F1 for help....hic, khổ tâm quá!!!

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 ặc! Chỉ 1 câu nói của bác Ketxu là:" File lisp khi load chỉ có tác dụng với file hiện hành đó, phiên làm việc đó"...em đã làm được...Thích thật. Cảm ơn tất cả các Pro! Mong rằng sẽ được chỉ giáo nhiều hơn!!

  • 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

Khai quật. e dùng lisp của bác Vnsdes mà khi gõ lệnh cl thì k thấy con trỏ chuột có thay đổi gì, kể cả chọn đối tượng rồi gõ cl cũng k có tác dụng gì. trong khi dã làm theo hướng dẫn của bác í cẩn thậ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ác bác cho e hỏi e đang cần dùng lisp nầy lắm mà không biết sử dụng thế nào, đánh lệnh tg rồi chọn các đối tượng sau đó làm thế nào ạ, e ấn space nhưng mà không được các bác chỉ giúp được 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

các bác cho e hỏi e đang cần dùng lisp nầy lắm mà không biết sử dụng thế nào, đánh lệnh tg rồi chọn các đối tượng sau đó làm thế nào ạ, e ấn space nhưng mà không được các bác chỉ giúp được không ạ

Hề hề hề,

Chọn xong đối tượng thì nhấn enter để kết thúc việc chọn chứ nhấn space làm chi????

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

Khai quật. e dùng lisp của bác Vnsdes mà khi gõ lệnh cl thì k thấy con trỏ chuột có thay đổi gì, kể cả chọn đối tượng rồi gõ cl cũng k có tác dụng gì. trong khi dã làm theo hướng dẫn của bác í cẩn thận.

Hề hề hề,

Lisp này dùng tính tổng chiều dài các đối tượng được chọn chớ không phải là để là thay đổi cấu hình con trỏ. Bởi thế nó chả thay đổi gì là rất chuẩn đó.

Gõ lệnh xong nhấn enter để phát lệnh thực hiện, sau đó làm theo các hướng dẫn trên dòng command hoặc trong các dialog hiển thị.

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

http://www.cadviet.com/upfiles/3/83858_ban_ve_3.dwg

 

Nhờ các bác xem hộ e bản vẽ này: Tại sao khi đo bằng lệnh dim thì kết quả là 3.98, nhưng khi dùng lisp nó lại ra kết quả là 127,58. Muốn lisp nhận đúng về 3.98 thì làm thế nào. Rất mong được giúp đỡ. Chân thành cảm ơ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

http://www.cadviet.com/upfiles/3/83858_ban_ve_3.dwg

 

Nhờ các bác xem hộ e bản vẽ này: Tại sao khi đo bằng lệnh dim thì kết quả là 3.98, nhưng khi dùng lisp nó lại ra kết quả là 127,58. Muốn lisp nhận đúng về 3.98 thì làm thế nào. Rất mong được giúp đỡ. Chân thành cảm ơn !

Hề hề hề,

Bạn dùng lisp nào thì phải post cái lisp đó lên mới biết được chứ. ???

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

http://www.cadviet.com/upfiles/3/83858_dochieudaizz.lsp

 

Đây là lisp đo chiều dài e hay dùng, e cũng đã thử với các lisp khác như lisp tg...nhưng kết quả vẫn thế. mong bác phamthanhbinh nghiên cứu giúp e với. e chân thành cảm ơn 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

Lisp chạy không sai đâu :D, do bản vẽ của bạn không đồng phẳng, bạn thử quay góc nhìn Top thành Front thì sẽ thấ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

http://www.cadviet.com/upfiles/3/83858_dochieudaizz.lsp

 

Đây là lisp đo chiều dài e hay dùng, e cũng đã thử với các lisp khác như lisp tg...nhưng kết quả vẫn thế. mong bác phamthanhbinh nghiên cứu giúp e với. e chân thành cảm ơn 1

Hề hề hề,

Đúng như bác Conghoa đã trả lời, Lisp cho ra kết quả này vì line của bạn là line 3D. kết quả trong lisp là chiều dài thực của line, kết quả bạn dùng dimension là chiều dài hình chiếu của line.

Vì vậy nếu muốn kết quả của lisp giống y chang kết quả bạn Dim thì chả khó khăn gì đâu, bạn chỉ cần hủy bỏ cao độ z của các điểm mút của line là Ok.

Có nhiều cách:

1/- Bạn dùng lệnh flaten trong express tools là phẳng các đối tượng của bạn.

2/- Sửa lại chút chút trong lisp ở hàm phụ (getLine (en) ....)

   Thay vì 

   (distance (cdr(assoc 10 enlist)) (cdr(assoc 11 enlist)))

  Bạn đổi thành:

   (distance (reverse (cdr (reverse (cdr (assoc 10 enlist))))) (reverse (cdr (reverse (cdr(assoc 11 enlist))))))

3/- .................

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

×