Đến nội dung


Hình ảnh
- - - - -

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


  • Please log in to reply
19 replies to this topic

#1 hhhhgggg

hhhhgggg

    biết dimedit

  • Members
  • PipPipPipPipPip
  • 393 Bài viết
Điểm đánh giá: 30 (tàm tạm)

Đã gửi 14 November 2009 - 09:29 PM

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 đỡ !
  • 0
Hoàng Giang

#2 rubik

rubik

    Chưa sử dụng CAD

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

Đã gửi 14 November 2009 - 09:42 PM

mình thấy cái này có cần viết lISP ko, trong CAD có lệnh FIND rồi mà.
  • 0

#3 Thaistreetz

Thaistreetz

    biết lệnh adcenter

  • Advance Member
  • PipPipPipPipPipPipPip
  • 903 Bài viết
Điểm đánh giá: 505 (tốt)

Đã gửi 14 November 2009 - 10:03 PM

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?
  • 0

Hình đã gửi
IN HIM, I TRUST. THE TRUST IN MY GOD


#4 hhhhgggg

hhhhgggg

    biết dimedit

  • Members
  • PipPipPipPipPip
  • 393 Bài viết
Điểm đánh giá: 30 (tàm tạm)

Đã gửi 15 November 2009 - 08:34 AM

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 !
  • 0
Hoàng Giang

#5 master_worse

master_worse

    biết lệnh offset

  • Advance Member
  • PipPipPip
  • 170 Bài viết
Điểm đánh giá: 87 (tàm tạm)

Đã gửi 15 November 2009 - 09:16 AM

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.c...amp;#entry75960
để có thể thay thế ở các bản vẽ khác

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

Ngu dốt không đáng thẹn bằng thiếu ý chí học hỏi


Tri thức làm người ta khiêm tốn, ngu si làm người ta kiêu ngạo (Ngạn ngữ Anh)


#6 Thaistreetz

Thaistreetz

    biết lệnh adcenter

  • Advance Member
  • PipPipPipPipPipPipPip
  • 903 Bài viết
Điểm đánh giá: 505 (tốt)

Đã gửi 15 November 2009 - 11:38 AM

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
  • 0

Hình đã gửi
IN HIM, I TRUST. THE TRUST IN MY GOD


#7 hhhhgggg

hhhhgggg

    biết dimedit

  • Members
  • PipPipPipPipPip
  • 393 Bài viết
Điểm đánh giá: 30 (tàm tạm)

Đã gửi 15 November 2009 - 07:56 PM

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 đỡ !
  • 0
Hoàng Giang

#8 Thaistreetz

Thaistreetz

    biết lệnh adcenter

  • Advance Member
  • PipPipPipPipPipPipPip
  • 903 Bài viết
Điểm đánh giá: 505 (tốt)

Đã gửi 16 November 2009 - 12:24 AM

đú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

  • 4

Hình đã gửi
IN HIM, I TRUST. THE TRUST IN MY GOD


#9 hhhhgggg

hhhhgggg

    biết dimedit

  • Members
  • PipPipPipPipPip
  • 393 Bài viết
Điểm đánh giá: 30 (tàm tạm)

Đã gửi 16 November 2009 - 08:11 AM

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 !
  • 0
Hoàng Giang

#10 gia_bach

gia_bach

    biết lệnh adcenter

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

Đã gửi 16 November 2009 - 03:25 PM

[quote name='Thaistreetz' post='79386' date='Nov 16 2009, 0:24']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))

  • 2

#11 Thaistreetz

Thaistreetz

    biết lệnh adcenter

  • Advance Member
  • PipPipPipPipPipPipPip
  • 903 Bài viết
Điểm đánh giá: 505 (tốt)

Đã gửi 17 November 2009 - 01:26 AM

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:
  • 0

Hình đã gửi
IN HIM, I TRUST. THE TRUST IN MY GOD


#12 gia_bach

gia_bach

    biết lệnh adcenter

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

Đã gửi 17 November 2009 - 10:59 AM

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

  • 6

#13 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 17 November 2009 - 11:15 AM

.......
Đố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
  • 0

#14 gia_bach

gia_bach

    biết lệnh adcenter

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

Đã gửi 17 November 2009 - 02:05 PM

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.
  • 3

#15 eakarphan

eakarphan

    biết zoom

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

Đã gửi 16 November 2013 - 03:54 PM

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 ạ?


  • 0

#16 rexnguyen

rexnguyen

    Chưa sử dụng CAD

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

Đã gửi 21 November 2013 - 05:13 PM

mong ae chỉ giùm replace all cho đường kích thước. Vd : HE=3300 --->Chiều cao tầng = 3300 (font arial unicode ms)

Cám ơn ae nhiều!


  • 0

#17 minhlavic

minhlavic

    Edu level: aa10

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

Đã gửi 05 April 2015 - 09:15 AM

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.


  • 0

#18 pphung183

pphung183

    biết dimstyle

  • Members
  • PipPipPipPipPip
  • 384 Bài viết
Điểm đánh giá: 425 (tốt)

Đã gửi 05 April 2015 - 11:41 AM

Muốn giúp bạn lam nhưng rất tiếc tôi ko phải Đại ka -_- Sorry!!!


  • 2

#19 minhlavic

minhlavic

    Edu level: aa10

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

Đã gửi 06 April 2015 - 09:53 AM

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ỉ


  • 0

#20 pphung183

pphung183

    biết dimstyle

  • Members
  • PipPipPipPipPip
  • 384 Bài viết
Điểm đánh giá: 425 (tốt)

Đã gửi 06 April 2015 - 11:57 AM

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


  • 4