find and replace text and mtext

find and replace text and mtext

Anonymous
Not applicable
5,198 Views
14 Replies
Message 1 of 15

find and replace text and mtext

Anonymous
Not applicable

I have this small lisp routine that replaces old text "JKT @ MUD" with a new text "MUDLINE" :


  (setq tss2 (ssget "_X" '((0 . "TEXT,MTEXT"))))
  (repeat (sslength tss2)
    (setq tdata (entget (ssname tss2 0)))
    (if (= (strcase "JKT@MUD") (strcase (cdr (assoc 1 tdata))))
      (entmod (subst (cons 1 "MUDLINE") (assoc 1 tdata) tdata))
    ); end if
    (ssdel (ssname tss2 0) tss2)
  ); end repeat

 

This routine was to be a small part of a larger lisp routine that will modify our drawings to a new company-wide standard.

I thought this worked perfect for my needs until I realized that the old text is not always just "JKT @ MUD ".

Often the string is accompanined by a number... for example "JKT @ MUD (-40') "... thus the old string is not found and no change is made.

 

How can this be modified to find all instances of the old string, that may or may not include the attached number, and replace the old portion of that string with the new text?  YET still retain the attached number, if it exists, so we do not lose it as part of the string ... for example "MUDLINE (-40') "?

 

 

I do not wish for the routine to halt and ask me to enter or pick text to change and enter or pick text to replace it with as these values will be hard coded.

I wish it to act globally on all text and mtext. It is not necessary to work on dimensions or attributed blocks.

 

I know AutoCAD's built in Find and Replace can do this with wildcard characters, but again I need a lisp so it will be automatic as there are many instances in each drawing AND I have several other variable text strings that need this same routine copied/modified inside the larger lisp so that their individual strings will change also.

 

Thank you for any help you can provide.

0 Likes
Accepted solutions (2)
5,199 Views
14 Replies
Replies (14)
Message 2 of 15

hmsilva
Mentor
Mentor

Hi navarreb,

perhaps something like this

 

(if (wcmatch (strcase (cdr (assoc 1 tdata))) "*JKT@MUD*")
     (entmod (subst (cons 1 (vl-string-subst "MUDLINE" "JKT @ MUD" (cdr (assoc 1 tdata)))) (assoc 1 tdata) tdata)
     )
  )

 

Hope this helps,
Henrique

EESignature

0 Likes
Message 3 of 15

ВeekeeCZ
Consultant
Consultant

@hmsilva wrote:

Hi navarreb,

perhaps something like this

 

(if (wcmatch (strcase (cdr (assoc 1 tdata))) "*JKT@MUD*")
     (entmod (subst (cons 1 (vl-string-subst "MUDLINE" "JKT @ MUD" (cdr (assoc 1 tdata)))) (assoc 1 tdata) tdata)
     )
  )

 

Hope this helps,
Henrique


I tried that as well... It works, but the condition must be modified to "*JKT `@ MUD*"

 

But I think that it could be without wcmatch at all. Just like this:

 

(entmod (subst (cons 1 (vl-string-subst "MUDLINE" "JKT @ MUD" (cdr (assoc 1 tdata)))) (assoc 1 tdata) tdata)

... but maybe that is too much extra work... (changing entity for no reason), so like this?

 

    (if (/= (setq told (cdr (assoc 1 tdata)))
	    (setq tnew (vl-string-subst "MUDLINE" "JKT @ MUD" told)))
      (entmod (subst (cons 1 tnew) (assoc 1 tdata) tdata))

 

0 Likes
Message 4 of 15

hmsilva
Mentor
Mentor

@ВeekeeCZ wrote:

@hmsilva wrote:

Hi navarreb,

perhaps something like this

 

(if (wcmatch (strcase (cdr (assoc 1 tdata))) "*JKT@MUD*")
     (entmod (subst (cons 1 (vl-string-subst "MUDLINE" "JKT @ MUD" (cdr (assoc 1 tdata)))) (assoc 1 tdata) tdata)
     )
  )

 

Hope this helps,
Henrique


I tried that as well... It works, but the condition must be modified to "*JKT `@ MUD*"

 

But I think that it could be without wcmatch at all. Just like this:

 

(entmod (subst (cons 1 (vl-string-subst "MUDLINE" "JKT @ MUD" (cdr (assoc 1 tdata)))) (assoc 1 tdata) tdata)

 


Hi BeekeeCZ,

that is correct, I did forgot the "`" @Anonymous escape the @Anonymous

And yes, we could just use the entmod and the subst, in all text strings...

 

Henrique

 

EESignature

0 Likes
Message 5 of 15

Anonymous
Not applicable

Thank you Henrique and BeeKee,

 

I much appreciate the help.

 

I have gotten both to work but with this modification it is only discovering the old string in the letter case in which the code has been typed.

Please tell me where in this modified code do I place the "strcase" option so that no matter whether the old string it spelled in uppercase, lowercase, or a combination of both, it will still be found?

 

Thanks

0 Likes
Message 6 of 15

ВeekeeCZ
Consultant
Consultant
Accepted solution

@Anonymous wrote:

Thank you Henrique and BeeKee,

 

I much appreciate the help.

 

I have gotten both to work but with this modification it is only discovering the old string in the letter case in which the code has been typed.

Please tell me where in this modified code do I place the "strcase" option so that no matter whether the old string it spelled in uppercase, lowercase, or a combination of both, it will still be found?

 

Thanks


Here you go.... let's make it general... with variables.. 

Case of both told (as origin) and lookfor (as text to match) are uppercase.

 

Spoiler
(defun c:testfunction ()
  (setq lookfor (getstring T "\nLook for: ")
	replacewith (getstring T "\nReplace with: "))
  
  (setq tss2 (ssget "_X" '((0 . "TEXT,MTEXT"))))
  (repeat (sslength tss2)
    (setq tdata (entget (ssname tss2 0)))
    (if (/= (setq told (cdr (assoc 1 tdata)))
	    (setq tnew (vl-string-subst replacewith (strcase lookfor) (strcase told))))
      (entmod (subst (cons 1 tnew) (assoc 1 tdata) tdata))
      ); end if
    (ssdel (ssname tss2 0) tss2)
    ); end repeat
  
)

 

Message 7 of 15

hmsilva
Mentor
Mentor
Accepted solution

@Anonymous wrote:

Thank you Henrique and BeeKee,

 

I much appreciate the help.

 

I have gotten both to work but with this modification it is only discovering the old string in the letter case in which the code has been typed.

Please tell me where in this modified code do I place the "strcase" option so that no matter whether the old string it spelled in uppercase, lowercase, or a combination of both, it will still be found?

 

Thanks



Maybe something like this...

 

(vl-load-com)
(defun c:demo (/ i obj RegExp ss)
   (if (setq ss (ssget "_X" '((0 . "MTEXT,TEXT"))))
      (progn
         (setq RegExp (vlax-get-or-create-object "VBScript.RegExp"))
         (vlax-put-property RegExp 'Global actrue)
         (vlax-put-property RegExp 'Ignorecase actrue)
         (vlax-put-property RegExp 'Multiline actrue)
         (vlax-put-property RegExp 'Pattern "JKT @ MUD ")
         (repeat (setq i (sslength ss))
            (setq obj (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
            (if (vlax-write-enabled-p obj)
               (vla-put-textstring obj (vlax-invoke RegExp 'Replace (vla-get-textstring obj) "MUDLINE"))
            )
         )
         (vlax-release-object RegExp)
      )
   )
   (princ)
)

 

Hope this helps,
Henrique

EESignature

Message 8 of 15

Anonymous
Not applicable

Thanks for the excellent help guys.

These both work great!

0 Likes
Message 9 of 15

hmsilva
Mentor
Mentor

@Anonymous wrote:

Thanks for the excellent help guys.

These both work great!


You're welcome, navarreb!
Glad I could help

 

@ВeekeeCZ Nice solution!

Henrique

EESignature

0 Likes
Message 10 of 15

ВeekeeCZ
Consultant
Consultant

@hmsilva wrote:

@Anonymous wrote:

Thanks for the excellent help guys.

These both work great!


You're welcome, navarreb!
Glad I could help

 

@ВeekeeCZ Nice solution!

Henrique


@Anonymous you're welcome!

 

@hmsilva Thank you Henrique! Your solution looks impressive to me! Are there some benefits in this solution? What reason let you to provide such an advanced (at least to me) solution?

0 Likes
Message 11 of 15

hmsilva
Mentor
Mentor

@ВeekeeCZ wrote:

@hmsilva Thank you Henrique! Your solution looks impressive to me! Are there some benefits in this solution? What reason let you to provide such an advanced (at least to me) solution?


 HI BeekeeCZ,

I did use RegExp just to demonstrate a 'simple' way to deal with text case.

  VBScript with Regular Expressions 

 

Cheers

Henrique

EESignature

0 Likes
Message 12 of 15

Anonymous
Not applicable

Guys,

Im not good in any of Lisp Coding, can some one help me modify this lisp that i have found on the internet.

Its a good routine for replacing Old text to a new text.

my problem is i've been trying to Put all the change/new text into Layer Dimension and Set the color by layer just in case the text color was assign with something else. with my attempt to change it (red text), the only  Text changing to Dimension layer is just the last Text on the list which is ("10" "273"). seem the selection by "Previous" is not selecting everything.

Can you please help me to make it work. Many Thanks!

 

(defun C:FRTXT1 ( / _mapss old new SS )
(defun _mapss ( f s i / e ) (if (setq e (ssname s (setq i (1+ i)))) (cons (f e) (_mapss f s i))))
(foreach x
'(
;("OldText1" "NewText1")
;("OldText2" "NewText2")
;("OldText3" "NewText3")
; ...
("1" "33")
("2" "60")
("3" "89")
("4" "114")
("6" "168")
("8" "219")
("10" "273")
; ...
)
(and
(vl-every 'set '(old new) x)
(setq SS (ssget "_X" (list '(0 . "TEXT") (setq old (cons 1 old)))))
(_mapss (lambda (e / enx) (setq enx (entget e)) (entmod (subst (cons 1 new) old enx))) SS -1)
); and
); foreach
(princ)
(Command "change" "p" "" "p" "la" "Dimension" "")
(Command "setbylayer" "p" "" "n" "n")
); defun

 

 

0 Likes
Message 13 of 15

Kent1Cooper
Consultant
Consultant

Try giving it the actual selection-set variable:

(Command "change" SS "" "p" "la" "Dimension" "")
(Command "setbylayer" SS "" "n" "n")

[Or, for the first one, save yourself a few characters:]

(Command "chprop" SS "" "la" "Dimension" "") 
Kent Cooper, AIA
Message 14 of 15

Anonymous
Not applicable

Hi Kent. Thanks for the quick reply. I'd copy the code but still I cant get the whole set on my list to change to dimension layer. it still the last part that is changing ("10" "273").

 

0 Likes
Message 15 of 15

Anonymous
Not applicable

Hi Kent,

Thank You Very much! SS actually works! I just need to place it on the right spot! Many Thanks Man!Smiley Happy

 

     (_mapss (lambda (e / enx) (setq enx (entget e)) (entmod (subst (cons 1 new) old enx))) SS -1)
(Command "chprop" SS "" "la" "Dimension" "")
   ); and
(Command "setbylayer" SS "" "n" "n")
 ); foreach
 (princ)
); defun

 

0 Likes