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

Lisp thay thế lệnh Replace all !!!

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

Em rất hay phải dùng lệnh thay thế( replace all), mà các Text ở đây nằm ở các bản vẽ khác nhau, có nội dung giống nhau. Vậy thiết nghĩ liệu có thể viết được 1 lisp nào cho phép thay thế chuỗi ký tự A ( gia sử là CADVIET - là chuỗi ký tự mà mình ghi vào nội dung của Lisp rồi ) bằng chuỗi ký tự B ( Diễn đàn CAD VIET )

Khi mình đánh lệnh thì lisp sẽ tự động thay thế luôn những chữ có nội dung là CADVIET nằm trong bản vẽ thành Diễn Đàn CAD VIET mà ko phải làm thêm bất cứ 1 thao tác nào nữa !!! mong được quan tâm giúp đỡ !

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à mỗi lần muốn xài cái lisp này, lại fải mở code của nó ra để thay đổi đoạn ký tự muốn thay thế?

ý bạn là vậ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
Và mỗi lần muốn xài cái lisp này, lại fải mở code của nó ra để thay đổi đoạn ký tự muốn thay thế?

ý bạn là vậy?

đúng vậy ! bởi vì mình phải làm việc với số lượng bản vẽ có nội dung giống nhau, làm các công việc giống nhau rất là lớn cho nên ko cần các bước trung gian cho phức tạp việc viết Lisp !

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à mỗi lần muốn xài cái lisp này, lại fải mở code của nó ra để thay đổi đoạn ký tự muốn thay thế?

ý bạn là vậy?

 

đúng vậy ! bởi vì mình phải làm việc với số lượng bản vẽ có nội dung giống nhau, làm các công việc giống nhau rất là lớn cho nên ko cần các bước trung gian cho phức tạp việc viết Lisp !

 

mỗi lần muốn thay đổi là mỗi lần phải mở file lisp lên sửa thì ...

nếu làm thế này:

Command: (Replaceall "Diễn Đàn CAD VIET " "CAD VIET ") enter

sẽ tự động thay thế luôn những chữ có nội dung là CADVIET nằm trong bản vẽ thành Diễn Đàn CAD VIET

thì sao nhỉ :D

 

Bạn tham khảo thêm ở đây:

http://www.cadviet.com/forum/index.php?sho...amp;#entry75960

để có thể thay thế ở các bản vẽ khác

 

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

P/S: có gì nhờ Thaistreetz viết cho :tongue2:

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

master_worse có thể đã hiểu sai rồi. Mình nghĩ ý của Hg là thế này cơ: mở một bản vẽ bất kỳ, load lisp, gõ lênh 1 fát là tất cả các text của bản vẽ có cụm từ ABC nào đó sẽ tự động chuyển thành XYZ mà HG muốn. đơn giản là thế nên không cần sử dụng lisp can thiệp vào clipboard

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
master_worse có thể đã hiểu sai rồi. Mình nghĩ ý của Hg là thế này cơ: mở một bản vẽ bất kỳ, load lisp, gõ lênh 1 fát là tất cả các text của bản vẽ có cụm từ ABC nào đó sẽ tự động chuyển thành XYZ mà HG muốn. đơn giản là thế nên không cần sử dụng lisp can thiệp vào clipboard

đúng là ý của mình giống như bạn Thái hiểu, tại vì cái lệnh Replace nó hiện ra Clip boad nên mình ko bit phải làm sao để đưa nó vào lisp ! mong các bác pro giúp đỡ !

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 là ý của mình giống như bạn Thái hiểu, tại vì cái lệnh Replace nó hiện ra Clip boad nên mình ko bit phải làm sao để đưa nó vào lisp ! mong các bác pro giúp đỡ !

với text thì bạn dùng cái này

(defun C:HG ()
(vl-load-com)
(setq old_text "Cadviet"	new_text "Forum CADVIET")
(setq adoc (vla-get-activedocument (vlax-get-acad-object)))
(vlax-for lt (vla-get-layouts adoc)
(vlax-for obj (vla-get-block lt)
 (if (eq "AcDbText" (vla-get-objectname obj))
(while (vl-string-search old_text (vla-get-textstring obj))
		  (vla-put-textstring obj
		  (vl-string-subst new_text old_text (vla-get-textstring obj)))
);while
 );if
)
)
(princ)
);end

  • Vote tăng 4

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ới text thì bạn dùng cái này

(defun C:HG ()
(vl-load-com)
(setq old_text "Cadviet"	new_text "Forum CADVIET")
(setq adoc (vla-get-activedocument (vlax-get-acad-object)))
(vlax-for lt (vla-get-layouts adoc)
(vlax-for obj (vla-get-block lt)
 (if (eq "AcDbText" (vla-get-objectname obj))
(while (vl-string-search old_text (vla-get-textstring obj))
		  (vla-put-textstring obj
		  (vl-string-subst new_text old_text (vla-get-textstring obj)))
);while
 );if
)
)
(princ)
);end

Cảm ơn bác Thái nhé . Lisp này thật đúng ý em ? Nhưng ngộ nhỡ cái chữ đó nó là Mtext thì lại ko đổi được ạ ? Bởi vì nó nằm ở nhìu nơi trong bản vẽ, Chạy xong lại mất công đi dò lại xem có thằng nào lạc loài là Mtext thì cũng hơi bất tiệ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
với text thì bạn dùng cái này

(defun c:hg (/ new_text old_text ss str)
 (or vlax-ename->vla-object (vl-load-com))
 (setq old_text "Cadviet" new_text "Forum CADVIET")    
 (ssget "_X" (list (cons 0 "*TEXT")(cons 1 (strcat"*"old_text "*") )))
 (if (setq ss (vla-get-activeSelectionSet (vla-get-activedocument(vlax-get-acad-object))))
   (vlax-for obj ss
     (setq str (vla-get-TextString obj))
     (while (vl-string-search old_text str)
(setq str (vl-string-subst new_text old_text str)) )
     (vla-put-textstring obj str)
     )
   )
 (princ))

  • Vote tăng 2

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ài nhận xét về List của Thaistreetz :

Nói chung Lisp của bạn chạy đúng 99,99% trừ vài truờng hợp đặc biệt. (sẽ viết phía duới)

1. Với việc sử dụng 2 vòng lặp vlax-for để truy xuất database trong CAD

(vlax-for lt (vla-get-layouts adoc)

(vlax-for obj (vla-get-block lt) .................. ...... ))

và kiểm tra điều kiện kiểu đối tuợng là TEXT

-> Lisp phải duyệt qua tất cả các đối tuợng trong bản vẽ, kể cả đối tuợng LINE, DIMENSION, ... do đó sẽ mất nhiều thời gian để thực hiện.

Đối với file CAD tuơng đối lớn, thời gian này là đáng kể (đủ để pha trà-cà phê hay .....)

Có thể tối ưu việc chọn đối tuợng khi kết hợp với 1 bộ lọc thích hợp.

VD : (ssget "_X" (list (cons 0 "TEXT")))

 

2.Với dòng lệnh WHILE :

(while (vl-string-search old_text (vla-get-textstring obj))

(vla-put-textstring obj (vl-string-subst new_text old_text (vla-get-textstring obj))) )

việc gọi hàm vla-get-textstring và vla-put-textstring trong vòng lặp là không cần thiết, mất nhiều thời gian truy xuất GET-PUT, ....

(thực ra điều này chỉ xảy ra khi chuỗi old_text cần thay thế đuợc lặp đi lặp lại trong TEXT)

có thể xử lý bằng cách lấy nội dung TEXT :

vla-get-textstring -> WHILE( thay thế old_text bằng new_text) -> gọi hàm vla-put-textstring

 

Cũng trong vòng lặp này, khi chuỗi new_text là tập con của chuỗi old_text thì LISP không thóat đuợc.

VD: khi thay thế chuỗi "Cadviet" với chuỗi "Forum Cadviet" -> CAD sẽ bi treo (OverFlow)

Bạn có thể kiểm chứng điều này. Sau đó tìm cách khắc phục nhé.

 

Vài góp ý chân thành (đừng nghĩ là vạch lá tìm sâu nha) đến Windows của Microsoft còn bị lỗi lên lỗi xuống cơ mà. <_<

Gửi bạn phuơng án khác (chưa xử lý lỗi trong vòng lặp)

(defun c:hg (/ new_text old_text ss str)
 (or vlax-ename->vla-object (vl-load-com))
 (setq old_text "Cadviet" new_text "Forum CADVIET")    
 (ssget "_X" (list (cons 0 "*TEXT")(cons 1 (strcat"*"old_text "*") )))
 (if (setq ss (vla-get-activeSelectionSet (vla-get-activedocument(vlax-get-acad-object))))
   (vlax-for obj ss
     (setq str (vla-get-TextString obj))
     (while (vl-string-search old_text str)
(setq str (vl-string-subst new_text old_text str)) )
     (vla-put-textstring obj str)
     )
   )
 (princ))

Thực ra đây không phải là lisp em viết anh ạ, nó được em tách ra từ một bộ lisp tổng hợp mà em sưu tầm được. Về lỗi vòng lặp while thì em cũng đã nhận ra và thử khắc phục ngay sau lần đầu test đoạn lisp này nhưng chưa có kết quả (em định dùng một hàm if trong vòng lặp, nếu đối tượng được duyệt có nhóm ký tự giống new_text thì sẽ bỏ qua không thực hiện việc thay thế, tuy nhiên chưa biết viết nó thế nào). hihi, chính vì thế nên em mới để cái old_text và new_text thế kia. không ngờ anh nhận ra ngay, sợ thật :cheers:

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ực ra đây không phải là lisp em viết anh ạ, nó được em tách ra từ một bộ lisp tổng hợp mà em sưu tầm được. Về lỗi vòng lặp while thì em cũng đã nhận ra và thử khắc phục ngay sau lần đầu test đoạn lisp này nhưng chưa có kết quả (em định dùng một hàm if trong vòng lặp, nếu đối tượng được duyệt có nhóm ký tự giống new_text thì sẽ bỏ qua không thực hiện việc thay thế, tuy nhiên chưa biết viết nó thế nào). hihi, chính vì thế nên em mới để cái old_text và new_text thế kia. không ngờ anh nhận ra ngay, sợ thật :D

Chẳng có gì đáng sợ cả, Bị treo máy vài lần thì nhận ra ngay thôi. :cheers:

 

Hàm vl-string-searchvl-string-subst có tham số start-pos chỉ vị trí bắt đầu tìm kiếm hay thay thế.

kết hợp với tham số này sẽ giải quyết đuợc lỗi trên.

(defun ReplaceString (old_str new_str str / m n)

(setq m 0 n (strlen new_str))

(while (setq m (vl-string-search old_str str m))

(setq str (vl-string-subst new_str old_str str m))

(setq m (+ n m))

)

str

)

test : (ReplaceString "Cadviet" "Forum Cadviet" "Cadviet1 Cadviet2 Cadviet3 Cadviet4")

-> "Forum Cadviet1 Forum Cadviet2 Forum Cadviet3 Forum Cadviet4"

 

Cập nhật Lisp Tìm và thay thế.

(defun ReplaceString (old_str new_str str / m n)
 (setq m 0 n (strlen new_str))
 (while (setq m (vl-string-search old_str str m))
   (setq str (vl-string-subst new_str old_str str m))
   (setq m (+ n m))
   )
 str
 )
(defun c:hg (/ new_text old_text ss str)
 (or vlax-ename->vla-object (vl-load-com))
 (setq old_text "Cadviet" new_text "Forum CADVIET")    
 (ssget "_X" (list (cons 0 "*TEXT")(cons 1 (strcat"*"old_text "*") )))
 (if (setq ss (vla-get-activeSelectionSet (vla-get-activedocument(vlax-get-acad-object))))
   (vlax-for obj ss
     (setq str (vla-get-TextString obj)
    str (ReplaceString old_text new_text  str))      
     (vla-put-textstring obj str)
     )
   )
 (princ))

  • Vote tăng 6

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 với file CAD tuơng đối lớn, thời gian này là đáng kể (đủ để pha trà-cà phê hay .....)

Có thể tối ưu việc chọn đối tuợng khi kết hợp với 1 bộ lọc thích hợp.

VD : (ssget "_X" (list (cons 0 "TEXT")))

........

Chào anh gia bách.

Anh cho Tue_NV hỏi chổ này tí :

Về hàm (ssget "X") thì em đã biết : là tập hợp chọn dữ liệu trên toàn bản vẽ

Còn về các tham số :I ; :N ; :S ; :E trong hàm ssget thì thực sự em chưa hiểu lắm về cách sử dụng nó và ứng dụng trong những trường hợp nào?

Anh có thể giải thích cho Tue_NV chổ này một chút được không?

Cảm ơn anh

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 anh gia bách.

Anh cho Tue_NV hỏi chổ này tí :

Về hàm (ssget "X") thì em đã biết : là tập hợp chọn dữ liệu trên toàn bản vẽ

Còn về các tham số :I ; :N ; :S ; :E trong hàm ssget thì thực sự em chưa hiểu lắm về cách sử dụng nó và ứng dụng trong những trường hợp nào?

Anh có thể giải thích cho Tue_NV chổ này một chút được không?

Cảm ơn anh

Một vài ý theo sự hiểu biết của mình.

:E Everything in aperture : Chọn tất cả đối tuợng có giao với con trỏ chuột bằng cách PICK (khi sử dụng tùy chọn này, con trỏ chuột có dạng hình vuông - kích thuớc phụ thuộc vào biến hệ thống PickBox Size)

 

I Implied : Tùy chọn này sử dụng trong truờng hợp chọn đối tuợng truớc, gọi lệnh sau.

 

:S Force single object selection only : Tùy chọn này chỉ cho phép chọn 1 đối tuợng.

 

:N Nested : Cung cấp thêm thông tin về các thực thể con subentity. (Chưa hiểu công dụng của nó)

 

Chúc bạn sức khỏe.

  • Vote tăng 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

Chào các anh, em đang cần một lisp  để thay thế nhiều đoạn text. Ví dụ em có 1 bản vẽ với các đoạn text là A, B, C ... bây giờ em muốn chuyển nó thành X, Y , Z ( A sẽ thành X, B sẽ thành Y, C sẽ thành Z....) mà dùng lisp trên để thay thế từng cái thì lâu quá vì em phải làm với nhiều bản vẽ. Có cách nào để em chỉ cần gõ 1 lần lệnh là các đoạn text khác nhau trong bản vẽ đó được thay đổi một lần luôn 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ó đại ca nào giỏi cho mình hỏi cái này. Công ty em có 2 người làm chung. Khi đi đường ống kỹ thuật:  một ông ký hiệu là D100-L52m, một ông lại là L52-D100... mà có rất nhiều cái D-L và L-D khác nhau. Vậy làm thế nào để thay thế tất cả về 1 loại D-L hoặc L-D.

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 ca nào giỏi cho mình hỏi cái này. Công ty em có 2 người làm chung. Khi đi đường ống kỹ thuật:  một ông ký hiệu là D100-L52m, một ông lại là L52-D100... mà có rất nhiều cái D-L và L-D khác nhau. Vậy làm thế nào để thay thế tất cả về 1 loại D-L hoặc L-D.

không ai giúp mình nhỉ

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

không ai giúp mình nhỉ

Bạn nên rút kinh nghiệm. Đây là môi trường học tập trao dồi kiến thức chứ ko ai muốn làm Đại ka đâu :) . Những điều bạn ko biết thì hỏi sẽ có người giúp và bạn nên tôn trọng họ như những người bạn, người anh, người thầy của mình :) . Bạn thử Lisp này xem sao :

(defun c:cstr (/ ss kt s ent str st1 st2 L D txt) 
(setq ss (ssget '((0 . "TEXT") (1 . "*-*")))) (initget "LD DL")
(setq kt (getkword "n\Chon kieu LD hay DL [LD/DL]? <LD>:"))
(while (> (sslength ss ) 0) (setq s (ssname ss 0) ent (entget s) str (cdr (assoc 1 ent)) 
st1 (car (str-split str "-")) st2 (cadr (str-split str "-"))) 
(setq L (if (= (vl-string-search "D" st1) nil) st1 st2))
(setq D (if (= (vl-string-search "L" st2) nil) st2 st1))
(if (= kt "LD") (setq txt (strcat L "-" D)) (setq txt (strcat D "-" L)))
(setq ent (subst (cons 1 txt) (assoc 1 ent) ent)) (entmod ent) (ssdel s ss)	)
(princ))
(defun str-split (string split / return stepover)
(setq return '()) (while (vl-string-search split string)
(setq return (append return (list (substr string 1 (vl-string-search split string))))
stepover (+ (vl-string-search split string) (strlen split))
string (substr string (1+ stepover) (- (strlen string) stepover)))	)
(setq return (append return (list string))) )

  • Vote tăng 4

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


×