Đến nội dung


Hình ảnh
* * * - - 2 Bình chọn

Viết Lisp theo yêu cầu


  • Chủ đề bị khóa Chủ đề bị khóa
2780 replies to this topic

#621 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 08 April 2008 - 01:42 PM

Với arc hoặc circle thì không cần chiều dài cũng được ạ, chỉ cần bán kính or đường kính, em tự tính bằng tay chiều dài khi đã đếm được đối tượng có bán kính or đường kính. Cảm ơn pác, nếu được thì tốt quá.


lệnh SR và SL dưới đây sẽ SELECT đối tượng theo RADIUS và SELECT đối tượng theo LENGTH.

(defun c:sr ()
(setq bk (getdist "\nVao ban kinh: ")
ss (ssget "X"
'((-4 . ""))
)
kq (ssadd)
)
(while (setq ent (ssname ss 0))
(if (equal bk
(vla-get-Radius (vlax-ename->vla-object ent))
0.0001
)
(setq kq (ssadd ent kq))
)
(setq ss (ssdel ent ss))
)
(sssetfirst kq kq)
(princ)
)


(defun c:sl ()
(setq bk (getdist "\nVao khoang cach: ")
ss (ssget "X"
'((0 . "*LINE"))
)
kq (ssadd)
)
(while (setq ent (ssname ss 0))
(if (equal bk
(vla-get-length (vlax-ename->vla-object ent))
0.0001
)
(setq kq (ssadd ent kq))
)
(setq ss (ssdel ent ss))
)
(sssetfirst kq kq)
(princ)
)

(vl-load-com)

  • 1

#622 xgame

xgame

    biết vẽ arc

  • Members
  • PipPip
  • 45 Bài viết
Điểm đánh giá: 5 (bình thường)

Đã gửi 08 April 2008 - 02:41 PM

lệnh SR và SL dưới đây sẽ SELECT đối tượng theo RADIUS và SELECT đối tượng theo LENGTH.

(defun c:sr ()
(setq bk (getdist "\nVao ban kinh: ")
ss (ssget "X"
'((-4 . "<or") (0 . "CIRCLE") (0 . "ARC") (-4 . "or>"))
)
kq (ssadd)
)
(while (setq ent (ssname ss 0))
(if (equal bk
(vla-get-Radius (vlax-ename->vla-object ent))
0.0001
)
(setq kq (ssadd ent kq))
)
(setq ss (ssdel ent ss))
)
(sssetfirst kq kq)
(princ)
)


(defun c:sl ()
(setq bk (getdist "\nVao khoang cach: ")
ss (ssget "X"
'((0 . "*LINE"))
)
kq (ssadd)
)
(while (setq ent (ssname ss 0))
(if (equal bk
(vla-get-length (vlax-ename->vla-object ent))
0.0001
)
(setq kq (ssadd ent kq))
)
(setq ss (ssdel ent ss))
)
(sssetfirst kq kq)
(princ)
)

(vl-load-com)


Cảm ơn bác Hoành đã nhiệt tình giúp đỡ em! Khi em dùng thì báo lỗi với lệnh "SL" để chọn theo length như sau (em dùng Cad2004):
Command: sl
Vao khoang cach: 300
; error: ActiveX Server returned the error: unknown name: Length

Lisp này là chọn các đối tượng có cùng kích thước với kích thước mình nhập vào, nhưng làm thế nào để biết là có bao nhiêu đối tượng có kích thước như vậy, không lẽ sau khi chọn được rồi mình lại phải ngồi đếm hả bác. Để biết có bao nhiêu đối tượng được lựa chọn em đã nhấn Ctrl+1 nhưng làm vậy thì hơi mất thời gian. Liệu có cách nào sao khi lệnh kết thúc thì cho mình kết quả hiện ra ở dòng command không bác.
  • 0

#623 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 08 April 2008 - 03:41 PM

Cảm ơn bác Hoành đã nhiệt tình giúp đỡ em! Khi em dùng thì báo lỗi với lệnh "SL" để chọn theo length như sau (em dùng Cad2004):

Command: sl
Vao khoang cach: 300
; error: ActiveX Server returned the error: unknown name: Length

Lisp này là chọn các đối tượng có cùng kích thước với kích thước mình nhập vào, nhưng làm thế nào để biết là có bao nhiêu đối tượng có kích thước như vậy, không lẽ sau khi chọn được rồi mình lại phải ngồi đếm hả bác. Để biết có bao nhiêu đối tượng được lựa chọn em đã nhấn Ctrl+1 nhưng làm vậy thì hơi mất thời gian. Liệu có cách nào sao khi lệnh kết thúc thì cho mình kết quả hiện ra ở dòng command không bác.

giả vờ dùng lệnh move!
  • 0

#624 hoanghuy

hoanghuy

    biết pan

  • Members
  • Pip
  • 8 Bài viết
Điểm đánh giá: 2 (bình thường)

Đã gửi 08 April 2008 - 09:02 PM

Mục đích của bạn như thế nào. Sao phải dùng lisp mở bản vẽ. Bạn nêu nyêu cầu rỏ rỏ chút được không.

(setq tenfilecođuongan (getfiled "CHON FILE " "" "dwg" 0))
Đây là dòng gợi ý. Làm xuất hiệu hộp thoại chọn file mặc định kiểu file là dwg.
Dữ liệu thu được là tenfilecođuongan chứa tên đầy đủ của file bạn chọn. sau đó xào nấu thế nào là việc của bạn.

Mình hiện đang làm rất nhiều bản vẽ nhỏ (thiết kế các chi tiết và đặt tên theo mã số) nên muốn mở nhanh bản vẽ chi tiết đó bằng cách lấy tên block trong bản vẽ chính luôn mà không phải mất thời gian mở bản vẽ bằng cách thông thuờng. Ví dụ nhu tên block chèn trong bản vẽ trùng với tên bản vẽ chi tiết nên chọn lệnh và chọn block cần mở bản vẽ chi tiết thì Acad tự động mở file. Bạn có thể giúp mình được không?
  • 0

#625 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 08 April 2008 - 09:10 PM

Mình hiện đang làm rất nhiều bản vẽ nhỏ (thiết kế các chi tiết và đặt tên theo mã số) nên muốn mở nhanh bản vẽ chi tiết đó bằng cách lấy tên block trong bản vẽ chính luôn mà không phải mất thời gian mở bản vẽ bằng cách thông thuờng. Ví dụ nhu tên block chèn trong bản vẽ trùng với tên bản vẽ chi tiết nên chọn lệnh và chọn block cần mở bản vẽ chi tiết thì Acad tự động mở file. Bạn có thể giúp mình được không?

Bạn đã thử như thế này chưa:
- Dùng lệnh options, rồi add đường dẫn thư mục chứa các file chi tiết vào trong Support file search path (chỉ cần làm 1 lần duy nhất).
- Mỗi khi dùng lệnh insert, nhập tên block = tên file (không cần có đuôi dwg, vd tên file là chitiet1.dwg thì bạn chỉ cần nhập chitiet1 tại lệnh insert).
  • 0

#626 hoanghuy

hoanghuy

    biết pan

  • Members
  • Pip
  • 8 Bài viết
Điểm đánh giá: 2 (bình thường)

Đã gửi 08 April 2008 - 10:58 PM

Bạn đã thử như thế này chưa:
- Dùng lệnh options, rồi add đường dẫn thư mục chứa các file chi tiết vào trong Support file search path (chỉ cần làm 1 lần duy nhất).
- Mỗi khi dùng lệnh insert, nhập tên block = tên file (không cần có đuôi dwg, vd tên file là chitiet1.dwg thì bạn chỉ cần nhập chitiet1 tại lệnh insert).

Ý của mình là các bản vẽ chi tiết đó đã được chèn vào bản vẽ chính với tên block trùng với tên file chi tiết. Để mở file chi tiết chỉ cần chọn block đó thì bản vẽ chi tiết đó sẽ được Acad mở ra. Còn tạo đường dẫn để chèn cho các lần sau mà không phải chọn file thì mình đã thực hiện được (Chiêu này rất cảm ơn bạn đã hướng dẫn).
  • 0

#627 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 09 April 2008 - 08:40 AM

Ý của mình là các bản vẽ chi tiết đó đã được chèn vào bản vẽ chính với tên block trùng với tên file chi tiết. Để mở file chi tiết chỉ cần chọn block đó thì bản vẽ chi tiết đó sẽ được Acad mở ra. Còn tạo đường dẫn để chèn cho các lần sau mà không phải chọn file thì mình đã thực hiện được (Chiêu này rất cảm ơn bạn đã hướng dẫn).

Bạn dùng thử lisp này, lệnh OB, select vào block là nó open file tương ứng.
Yếu cầu: bản vẽ chính và các bản vẽ chi tiết phải nằm chung thư mụckhông cần thiết lập Support File Search Path (SFSP).
Theo mình, không nên lạm dụng SFSP vì nếu số lượng project tăng lên theo thời gian (nếu bạn thiết kế thường xuyên chừng vài năm thì số lượng project tăng lên đáng kể) thì cái list SFSP cứ nối dài mãi à? Nhiều quá có vẻ không ổn chút nào. Ví dụ: 2 project khác nhau nhưng có 2 file trùng tên. Nếu không chỉ định chính xác path có khả năng sẽ gây ra nhầm lẫn.

(defun C:OB( / d bln fn dir ffn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (findfile (getvar "dwgname"))
dir (vl-filename-directory fn)
ffn (strcat dir "\\" bln ".dwg")
)
(if (findfile ffn) (command "start" ffn) (alert "File not found!"))
)

Vấn đề còn tồn tại:
Nếu file bản vẽ chi tiết đã open rồi nhưng user không nhớ và dùng tiếp OB, chương trình không có phản ứng gì cả, có thể làm cho user bối rối. Lẽ ra, chương trình phải có 1 trong 2 cách hành xử:
- Ra thông báo, kiểu như "File này đã được mở"
- Không cần thông báo, chuyển focus sang file bản vẽ đã chỉ định
Bạn nào có thể bổ sung giúp chỗ này? Cụ thể, làm thế nào để lấy được list các bản vẽ đang được open (bấm vào Menu - Window -> có 1 list các file *.dwg ở dưới cùng ấy). Lấy được list này sẽ xử được tồn tại trên.
  • 0

#628 xgame

xgame

    biết vẽ arc

  • Members
  • PipPip
  • 45 Bài viết
Điểm đánh giá: 5 (bình thường)

Đã gửi 09 April 2008 - 03:31 PM

lệnh SR và SL dưới đây sẽ SELECT đối tượng theo RADIUS và SELECT đối tượng theo LENGTH.

(defun c:sr ()
(setq bk (getdist "\nVao ban kinh: ")
ss (ssget "X"
'((-4 . "<or") (0 . "CIRCLE") (0 . "ARC") (-4 . "or>"))
)
kq (ssadd)
)
(while (setq ent (ssname ss 0))
(if (equal bk
(vla-get-Radius (vlax-ename->vla-object ent))
0.0001
)
(setq kq (ssadd ent kq))
)
(setq ss (ssdel ent ss))
)
(sssetfirst kq kq)
(princ)
)


(defun c:sl ()
(setq bk (getdist "\nVao khoang cach: ")
ss (ssget "X"
'((0 . "*LINE"))
)
kq (ssadd)
)
(while (setq ent (ssname ss 0))
(if (equal bk
(vla-get-length (vlax-ename->vla-object ent))
0.0001
)
(setq kq (ssadd ent kq))
)
(setq ss (ssdel ent ss))
)
(sssetfirst kq kq)
(princ)
)

(vl-load-com)


Bác Hoành ơi em vẫn bị lỗi khi dùng lệnh SL để lựa chọn theo length mặc dù em đã chuyển sang dùng cad2007

Command: sl

Vao khoang cach: 100
error: ActiveX Server returned the error: unknown name: Length
Bác xem giúp em một chút được không
  • 0

#629 trinh8306

trinh8306

    Chưa sử dụng CAD

  • Members
  • Pip
  • 3 Bài viết
Điểm đánh giá: 0 (bình thường)

Đã gửi 09 April 2008 - 03:58 PM

Bạn có thể post yêu cầu về autolisp ở topic này.

Cần Lisp Coppy nội dung Text theo nội dung Text khác, mà vẫn giữ nguyên text style
Chào các bác:
em đang cần 1 lisp, mong các bác giúp đỡ. Cảm ơn rất nhiều!
Yêu cầu:
- Em có các dòng text: A, B, C, D, ... (nội dung là chữ, số hoặc có cả chữ số,...)
- Nhiều trường hợp em cần các text B C D cũng có nội dung như của text A. Em cần 1 lisp có thể thực hiện nhanh thao tác này (như kích chuột vào A rồi kích vào B,C,D là được). Thanks!
  • 0

#630 duy782006

duy782006

    PHẠM QUỐC DUY

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 2155 Bài viết
Điểm đánh giá: 1360 (rất tốt)

Đã gửi 09 April 2008 - 04:13 PM

Cần Lisp Coppy nội dung Text theo nội dung Text khác, mà vẫn giữ nguyên text style
Chào các bác:
em đang cần 1 lisp, mong các bác giúp đỡ. Cảm ơn rất nhiều!
Yêu cầu:
- Em có các dòng text: A, B, C, D, ... (nội dung là chữ, số hoặc có cả chữ số,...)
- Nhiều trường hợp em cần các text B C D cũng có nội dung như của text A. Em cần 1 lisp có thể thực hiện nhanh thao tác này (như kích chuột vào A rồi kích vào B,C,D là được). Thanks!


Bạn xem trang 1 của topic này có rồi đó bạn.
  • 1

Cứ ngỡ trần gian là cõi thật.Cho nên tất bật đến bây giờ.
Tạo hộp thoại bằng lisp My blog QUY ĐỊNH ĐẶT TÊN TOPIC TRONG CHUYÊN MỤC LISPD http://ktsduy.wordpress.com/
Để cám ơn chỉ cần nhấn rep_up.png
(Là nhấn vào nút đó phía bài viết của người ta í chứ đừng có nhè cái hình này mà nhấn miết đi nha :-D


#631 hoanghuy

hoanghuy

    biết pan

  • Members
  • Pip
  • 8 Bài viết
Điểm đánh giá: 2 (bình thường)

Đã gửi 09 April 2008 - 07:06 PM

Bạn dùng thử lisp này, lệnh OB, select vào block là nó open file tương ứng.
Yếu cầu: bản vẽ chính và các bản vẽ chi tiết phải nằm chung thư mụckhông cần thiết lập Support File Search Path (SFSP).
Theo mình, không nên lạm dụng SFSP vì nếu số lượng project tăng lên theo thời gian (nếu bạn thiết kế thường xuyên chừng vài năm thì số lượng project tăng lên đáng kể) thì cái list SFSP cứ nối dài mãi à? Nhiều quá có vẻ không ổn chút nào. Ví dụ: 2 project khác nhau nhưng có 2 file trùng tên. Nếu không chỉ định chính xác path có khả năng sẽ gây ra nhầm lẫn.

(defun C:OB( / d bln fn dir ffn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (findfile (getvar "dwgname"))
dir (vl-filename-directory fn)
ffn (strcat dir "\\" bln ".dwg")
)
(if (findfile ffn) (command "start" ffn) (alert "File not found!"))
)

Vấn đề còn tồn tại:
Nếu file bản vẽ chi tiết đã open rồi nhưng user không nhớ và dùng tiếp OB, chương trình không có phản ứng gì cả, có thể làm cho user bối rối. Lẽ ra, chương trình phải có 1 trong 2 cách hành xử:
- Ra thông báo, kiểu như "File này đã được mở"
- Không cần thông báo, chuyển focus sang file bản vẽ đã chỉ định
Bạn nào có thể bổ sung giúp chỗ này? Cụ thể, làm thế nào để lấy được list các bản vẽ đang được open (bấm vào Menu - Window -> có 1 list các file *.dwg ở dưới cùng ấy). Lấy được list này sẽ xử được tồn tại trên.
[/code]

Mình đã thử chạy code trên của bạn nhưng câu lệnh (setq fn (findfile (getvar "dwgname"))) lại hiện đường dẫn của bản vẽ chính nên luôn hiện thông báo (alert "File not found!"). Mình xin thông tin lại nội dung như sau :
- Ví dụ trong bản vẽ khai triển mình chèn block có tên "moinoibich" trong khi đó trong thư viện mình cũng đã có file chi tiết "moinoibich.dwg".
- Để mở file chi tiết "moinoibich.dwg" thì mình chỉ cần click chọn block có tên "moinoibich" thì bản vẽ "moinoibich.dwg" sẽ được mở ra.
Cho mình hỏi tí nhé : Hình như lệnh "start" không mở được bản vẽ mà tên bản vẽ có ký tự là khoảng trắng thì phải. Ví dụ như "moi noi bich.dwg".
Mình đã thử lại như sau thì thấy mở được :
(defun C:OB( / d bln fn dir ffn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (strcat bln ".dwg")
)
(command "start" fn)
)
Mình rất cảm ơn bạn đã giúp đỡ.
  • 0

#632 hoangtrongbang

hoangtrongbang

    biết pan

  • Members
  • Pip
  • 7 Bài viết
Điểm đánh giá: 0 (bình thường)

Đã gửi 10 April 2008 - 01:12 PM

Nhờ các bác viết hộ em một lisp ghi kích thước hàng loạt, tức là chọn hàng loạt đoạn thẳng và ghi kích thước của các đường thẳng đó. Em đang cần gấp mong các cao thủ giúp em với.
  • 0

#633 Bach_Dang

Bach_Dang

    Chưa sử dụng CAD

  • Members
  • Pip
  • 1 Bài viết
Điểm đánh giá: 0 (bình thường)

Đã gửi 10 April 2008 - 07:18 PM

Em muốn nhờ các bác viết dùm 1 đoạn code thực hiện công việc sau:

1, Trên bản vẽ có 1 tập hợp các đoạn thẳng có giao cắt với nhau
2, Sử dụng lệnh chọn tất cả các đoạn thẳng đó, kết quả sẽ break các đoạn thẳng tại giao điểm của chúng.

Hiện giờ em đang làm bằng lệnh break với tham số F để chọn first point rồi sau đó chọn second point trùng với điểm đầu đã chọn. Nhưng thực hiện việc này với 1 mạng lưới khoảng 1000 phần tử giao nhau chằng chịt thì mất mấy ngày và nhàm chán. Em mong được các bác giúp đỡ.

Em xin cảm ơn.
  • 0

#634 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 11 April 2008 - 10:09 AM

Mình đã thử chạy code trên của bạn nhưng câu lệnh (setq fn (findfile (getvar "dwgname"))) lại hiện đường dẫn của bản vẽ chính nên luôn hiện thông báo (alert "File not found!"). Mình xin thông tin lại nội dung như sau :
- Ví dụ trong bản vẽ khai triển mình chèn block có tên "moinoibich" trong khi đó trong thư viện mình cũng đã có file chi tiết "moinoibich.dwg".
- Để mở file chi tiết "moinoibich.dwg" thì mình chỉ cần click chọn block có tên "moinoibich" thì bản vẽ "moinoibich.dwg" sẽ được mở ra.
Cho mình hỏi tí nhé : Hình như lệnh "start" không mở được bản vẽ mà tên bản vẽ có ký tự là khoảng trắng thì phải. Ví dụ như "moi noi bich.dwg".
Mình đã thử lại như sau thì thấy mở được :
(defun C:OB( / d bln fn dir ffn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (strcat bln ".dwg")
)
(command "start" fn)
)
Mình rất cảm ơn bạn đã giúp đỡ.

1) Bạn sửa như vậy, bắt buộc phải thiết lập Support File Search Path (SFSP). Nếu không sẽ không chạy được. Đây không phải là giải pháp hay như mình đã phân tích ở bài trên.

2) Dùng "start" đúng là bị nhược điểm về dấu space trong filename như bạn nói

3) Bạn dùng thử lisp này. Mình đã thử, chạy đúng trong mọi trường hợp, không cần thiết lập SFSP. Nếu file bản vẽ đã open, nó sẽ open tiếp ở dạng ReadOnly.


;;;-------------------------------------------------
(defun open_dwg(fn)
(vl-cmdf "vbastmt" (strcat "acadapplication.documents.open \"" fn "\",FALSE"))
)
;;;-------------------------------------------------
(defun C:OB( / d bln fn dir ffn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (findfile (getvar "dwgname"))
dir (vl-string-right-trim "\\" (vl-filename-directory fn))
ffn (strcat dir "\\" bln ".dwg")
)
(if (findfile ffn) (open_dwg ffn) (alert "File not found!"))
)
;;;-------------------------------------------------


P/S: I'm sorry! Mình đọc kỹ lại bài của bạn và đã hiểu ý: bạn có 1 số chi tiết tiêu chuẩn chứa trong thư mục thư viện, được thiết lập SFSP và có thể dùng chung cho nhiều project. Đúng không?
Nếu như vậy, bạn dùng lisp này. Filename có thể chứa space vô tư!


;;;-------------------------------------------------
(defun open_dwg(fn)
(vl-cmdf "vbastmt" (strcat "acadapplication.documents.open \"" fn "\",FALSE"))
)
;;;-------------------------------------------------
(defun C:OB2( / d bln fn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (findfile (strcat bln ".dwg"))
)
(open_dwg fn)
)
;;;-------------------------------------------------

  • 0

#635 conghoa

conghoa

    biết lệnh attdef

  • Members
  • PipPipPipPipPipPip
  • 411 Bài viết
Điểm đánh giá: 88 (tàm tạm)

Đã gửi 11 April 2008 - 01:33 PM

Em muốn nhờ các bác viết dùm 1 đoạn code thực hiện công việc sau:

1, Trên bản vẽ có 1 tập hợp các đoạn thẳng có giao cắt với nhau
2, Sử dụng lệnh chọn tất cả các đoạn thẳng đó, kết quả sẽ break các đoạn thẳng tại giao điểm của chúng.

Hiện giờ em đang làm bằng lệnh break với tham số F để chọn first point rồi sau đó chọn second point trùng với điểm đầu đã chọn. Nhưng thực hiện việc này với 1 mạng lưới khoảng 1000 phần tử giao nhau chằng chịt thì mất mấy ngày và nhàm chán. Em mong được các bác giúp đỡ.

Em xin cảm ơn.



- Mình không biết làm lisp bạn yêu cầu, chỉ biết 1 dòng lệnh này giúp bạn break nhanh hơn (một chút so với thao tác bình thường bạn làm)

Bạn copy đoạn này vào bất cứ lisp nào bạn đang dùng, khi chạy lisp bạn dùng lênh " bb " ---> chọn đường cần break ----> chọn điểm cần break -----> xong :bigsmile: không phải loàng ngoằng như bình thường bạn hay làm .

(defun c:bb () (command "BREAK" pause "_f" pause"@"))


Nhờ các bác viết hộ em một lisp ghi kích thước hàng loạt, tức là chọn hàng loạt đoạn thẳng và ghi kích thước của các đường thẳng đó. Em đang cần gấp mong các cao thủ giúp em với.



@hoangtrongbang lênh qdim có sẵn trong cad làm được điều bạn yêu cầu.
  • 0

#636 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 11 April 2008 - 04:57 PM

Em muốn nhờ các bác viết dùm 1 đoạn code thực hiện công việc sau:

1, Trên bản vẽ có 1 tập hợp các đoạn thẳng có giao cắt với nhau
2, Sử dụng lệnh chọn tất cả các đoạn thẳng đó, kết quả sẽ break các đoạn thẳng tại giao điểm của chúng.

Hiện giờ em đang làm bằng lệnh break với tham số F để chọn first point rồi sau đó chọn second point trùng với điểm đầu đã chọn. Nhưng thực hiện việc này với 1 mạng lưới khoảng 1000 phần tử giao nhau chằng chịt thì mất mấy ngày và nhàm chán. Em mong được các bác giúp đỡ.

Em xin cảm ơn.

Bạn dùng lisp này, lệnh BRK:


;;;-------------------------------------------------------------
(defun ss2ent (ss / i Le e)
(setq i 0 Le nil)
(repeat (sslength ss)
(setq
e (ssname ss i)
Le (append Le (list e))
i (1+ i)
)
)
Le
)
;;;-------------------------------------------------------------
(defun DXF (code e) (cdr (assoc code (entget e))) )
;;;-------------------------------------------------------------
(defun get_inters(e1 e2 / p11 p12 p21 p22)
(setq
p11 (dxf 10 e1) p12 (dxf 11 e1)
p21 (dxf 10 e2) p22 (dxf 11 e2)
)
(inters p11 p12 p21 p22)
)
;;;-------------------------------------------------------------
(defun C:BRK( / ss L Lp e1 e2 p e)
(setq
ss (ssget '((0 . "LINE")))
L (ss2ent ss)
Lp nil
)
(foreach e1 L
(foreach e2 L
(setq p (get_inters e1 e2))
(if (and p (not (member p Lp))) (setq Lp (append Lp (list p))))
)
)
(foreach p Lp
(setq
ss (ssget "C" p p '((0 . "LINE")))
L (ss2ent ss)
)
(foreach e L (command "break" e p p))
)
(princ)
)
;;;-------------------------------------------------------------

  • 0

#637 Bommak

Bommak

    biết vẽ line

  • Members
  • PipPip
  • 25 Bài viết
Điểm đánh giá: 1 (bình thường)

Đã gửi 11 April 2008 - 07:04 PM

@conghoa: Cảm ơn bác

@ssg: Rất cảm ơn bác. Chương trình của bác chạy rất tốt. Nó giúp bản thân em tiết kiệm cực kỳ nhiều thời gian.

Chúc các bác luôn mạnh khoẻ..
  • 0

#638 hoanghuy

hoanghuy

    biết pan

  • Members
  • Pip
  • 8 Bài viết
Điểm đánh giá: 2 (bình thường)

Đã gửi 11 April 2008 - 09:29 PM

1) Bạn sửa như vậy, bắt buộc phải thiết lập Support File Search Path (SFSP). Nếu không sẽ không chạy được. Đây không phải là giải pháp hay như mình đã phân tích ở bài trên.

2) Dùng "start" đúng là bị nhược điểm về dấu space trong filename như bạn nói

3) Bạn dùng thử lisp này. Mình đã thử, chạy đúng trong mọi trường hợp, không cần thiết lập SFSP. Nếu file bản vẽ đã open, nó sẽ open tiếp ở dạng ReadOnly.


;;;-------------------------------------------------
(defun open_dwg(fn)
(vl-cmdf "vbastmt" (strcat "acadapplication.documents.open \"" fn "\",FALSE"))
)
;;;-------------------------------------------------
(defun C:OB( / d bln fn dir ffn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (findfile (getvar "dwgname"))
dir (vl-string-right-trim "\\" (vl-filename-directory fn))
ffn (strcat dir "\\" bln ".dwg")
)
(if (findfile ffn) (open_dwg ffn) (alert "File not found!"))
)
;;;-------------------------------------------------


P/S: I'm sorry! Mình đọc kỹ lại bài của bạn và đã hiểu ý: bạn có 1 số chi tiết tiêu chuẩn chứa trong thư mục thư viện, được thiết lập SFSP và có thể dùng chung cho nhiều project. Đúng không?
Nếu như vậy, bạn dùng lisp này. Filename có thể chứa space vô tư!


;;;-------------------------------------------------
(defun open_dwg(fn)
(vl-cmdf "vbastmt" (strcat "acadapplication.documents.open \"" fn "\",FALSE"))
)
;;;-------------------------------------------------
(defun C:OB2( / d bln fn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (findfile (strcat bln ".dwg"))
)
(open_dwg fn)
)
;;;-------------------------------------------------

Mình đã thử đoạn code sau của bạn nhưng vẫn không mở được. Đúng là dùng code của mình sửa lại phải có SFSP và hàm "start" không tiện cho lắm. Cho mình hỏi bạn kết nối chuỗi "(strcat "acadapplication.documents.open \"" fn "\",FALSE"))" là tạo đường dẫn à? Đúng là mình có một số thư viện chuẩn để làm các project nhưng đôi khi cần phải mở chúng ra để sửa chữa đôi chút hoặc xem lại nó nên rất cần cách mở này. Cảm ơn bạn đã giúp đỡ.
  • 0

#639 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 12 April 2008 - 08:22 AM

Mình đã thử đoạn code sau của bạn nhưng vẫn không mở được. Đúng là dùng code của mình sửa lại phải có SFSP và hàm "start" không tiện cho lắm. Cho mình hỏi bạn kết nối chuỗi "(strcat "acadapplication.documents.open \"" fn "\",FALSE"))" là tạo đường dẫn à? Đúng là mình có một số thư viện chuẩn để làm các project nhưng đôi khi cần phải mở chúng ra để sửa chữa đôi chút hoặc xem lại nó nên rất cần cách mở này. Cảm ơn bạn đã giúp đỡ.

Không mở được? Ssg đã test rất kỹ trên máy mình! Bạn thử dùng lại lisp sau:

;;;-------------------------------------------------
(defun open_dwg(fn / obj)
(vl-load-com)
(setq obj (vlax-get-acad-object))
(vla-put-activedocument obj (vla-open (vla-get-documents obj) fn))
)
;;;-------------------------------------------------
(defun C:OB( / d bln fn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (findfile (strcat bln ".dwg"))
)
(open_dwg fn)
)
;;;-------------------------------------------------

Yêu cầu:
1) AutoCAD đời 2002 trở đi (mình đã test trên 2002 và 2007)
2) Phải thiết lập SFSP cho thư viện các bản vẽ chi tiết
3) Bỏ tất cả các chương trình chạy thử mấy hôm nay đi
4) Thử vô hiệu hoá toàn bộ các lisp khác có thể đang thiết lập chế độ autoLoad trên máy bạn (loại trừ khả năng có function nào đó trùng tên)

Bạn đáp ứng 4 yêu cầu trên, chắc chắn phải chạy được. Nếu vẫn không chạy được thì ssg... cũng bó tay!

P/S:
Chuỗi S = "(strcat "acadapplication.documents.open \"" fn "\",FALSE"))" không phải tạo đường dẫn.
Khi thư viện đã khai báo SFSP thì kết quả (setq fn (findfile (strcat bln ".dwg"))) đã là Full Filename của bản vẽ block rồi.
Cú pháp (vl-cmdf "vbastmt" S) là gọi một thủ tục VBA bằng lisp, với S là cú pháp của VBA. Bạn không chạy được cũng có thể là do sự khác biệt về version của Cad dẫn đến khác biệt version của VBA.
  • 0

#640 hoanghuy

hoanghuy

    biết pan

  • Members
  • Pip
  • 8 Bài viết
Điểm đánh giá: 2 (bình thường)

Đã gửi 12 April 2008 - 11:24 AM

Không mở được? Ssg đã test rất kỹ trên máy mình! Bạn thử dùng lại lisp sau:

;;;-------------------------------------------------
(defun open_dwg(fn / obj)
(vl-load-com)
(setq obj (vlax-get-acad-object))
(vla-put-activedocument obj (vla-open (vla-get-documents obj) fn))
)
;;;-------------------------------------------------
(defun C:OB( / d bln fn)
(setq
d (entget (car (entsel "\nSelect block:")))
bln (cdr (assoc 2 d))
fn (findfile (strcat bln ".dwg"))
)
(open_dwg fn)
)
;;;-------------------------------------------------

Yêu cầu:
1) AutoCAD đời 2002 trở đi (mình đã test trên 2002 và 2007)
2) Phải thiết lập SFSP cho thư viện các bản vẽ chi tiết
3) Bỏ tất cả các chương trình chạy thử mấy hôm nay đi
4) Thử vô hiệu hoá toàn bộ các lisp khác có thể đang thiết lập chế độ autoLoad trên máy bạn (loại trừ khả năng có function nào đó trùng tên)

Bạn đáp ứng 4 yêu cầu trên, chắc chắn phải chạy được. Nếu vẫn không chạy được thì ssg... cũng bó tay!

P/S:
Chuỗi S = "(strcat "acadapplication.documents.open \"" fn "\",FALSE"))" không phải tạo đường dẫn.
Khi thư viện đã khai báo SFSP thì kết quả (setq fn (findfile (strcat bln ".dwg"))) đã là Full Filename của bản vẽ block rồi.
Cú pháp (vl-cmdf "vbastmt" S) là gọi một thủ tục VBA bằng lisp, với S là cú pháp của VBA. Bạn không chạy được cũng có thể là do sự khác biệt về version của Cad dẫn đến khác biệt version của VBA.

Ok, cảm ơn bạn rất nhiều. Mình thấy bạn rất giỏi về visualisp, bạn có tài liệu gì về hướng dẫn lập trình VL ko, nếu có cho mình tham khảo được không?
  • 0