Find text, change layer

Find text, change layer

Anonymous
Not applicable
3,316 Views
15 Replies
Message 1 of 16

Find text, change layer

Anonymous
Not applicable

Hi All,

 

I'm new to lisps and the syntax is a little confusing to me so I'm having a little trouble. I have a text layer that contains around 500 text and mtext strings. I need to search for a string within the text and if it matches, change the layer. Here's an example of the logic:

 

find "HW" 

change object layer to "HW-TXT"

 

find "WFI" 

change object layer to "WFI-TXT"

 

find "CHWS"

change object layer to "CHWS-TXT"

ect...

 

If possible, it would be nice to be able to view the object before the layer is changed similar to how you can view all of the text when you use find and replace before replacing it but it's not absolutely necessary.

 

Thanks in advance

Accepted solutions (1)
3,317 Views
15 Replies
Replies (15)
Message 2 of 16

Anonymous
Not applicable
Accepted solution
(defun C:ChgText (/)
(if (setq SS (ssget "X" (list (cons 0 "TEXT,MTEXT") (cons 1 "HW"))))
(progn
(if (not (tblsearch "LAYER" "HW-TXT")) (command "LAYER" "M" "HW-TXT" ""))
(setq KK 0)
(while (< KK (sslength SS))
(command "ZOOM" "C" (cdr (assoc 10 (entget (ssname SS KK)))) "")
(if (= "Y" (strcase (getstring "\nChange Text - {y}=Yes or {n}=No ? ")))
(command "CHPROP" SS "" "LA" "HW-TXT" "")
)
(setq KK (1+ KK))
)
)
)
(princ)
)
Message 3 of 16

Anonymous
Not applicable

That worked great, thanks!

 

I understand enough of what you wrote to add the remaining layers and strings. thanks

Message 4 of 16

phillip.curlin
Participant
Participant

This solution works great   ---   any chance multiple text strings could be found and the layer changed globally inside of one lisp command?? 

0 Likes
Message 5 of 16

ronjonp
Advisor
Advisor

Try something like this:

(defun c:foo (/ s)
  ;; RJP » 2019-10-01
  ;; Add to the list below of layers to look for and target layer to place text 
  (foreach l '(("LAYERNAME" "NEWLAYERNAME")
	       ("LAYERNAME1" "NEWLAYERNAME1")
	       ("LAYERNAME2" "NEWLAYERNAME2")
	       ("LAYERNAME3" "NEWLAYERNAME3")
	       ;; Can combine multiple layers like so to put on a single target layer :)
	       ("TEST,123,RJP" "NEWLAYERNAME3")
	       ;; Partial string match
	       ("*FUNKY*" "Chicken")
	      )
    (if	(setq s (ssget "_X" (list '(0 . "*TEXT") (cons 8 (car l)))))
      (foreach e (mapcar 'cadr (ssnamex s)) (entmod (append (entget e) (list (cons 8 (cadr l))))))
    )
  )
  (princ)
)
Message 6 of 16

phillip.curlin
Participant
Participant
Thanks will give it a try.
0 Likes
Message 7 of 16

phillip.curlin
Participant
Participant

what i am trying to do is find all occurrences of the text string "*CAD WELD" on layer G-ANNO-TEXT and move that text string to layer G-ANNO-TEXT-YELL globally on multiple page layouts.

All text strings are on layer G-ANNO-TEXT

 

below was my attempt - it puts all text on layer G-ANNO-TEXT on layer G-ANNO-TEXT-YELL

station string text .jpg

(defun c:CHGTEXT-ALL (/ s)
;; RJP » 2019-10-01
;; Add to the list below of layers to look for and target layer to place text
(foreach l '(("LAYERNAME" "G-ANNO-TEXT")
;; Can combine multiple layers like so to put on a single target layer 🙂
("G-ANNO-TEXT" "G-ANNO-TEXT-YELL")
;; Partial string match
("*CAD WELD")
)
(if (setq s (ssget "_X" (list '(0 . "*TEXT") (cons 8 (car l)))))
(foreach e (mapcar 'cadr (ssnamex s)) (entmod (append (entget e) (list (cons 8 (cadr l))))))
)
)
(princ)
)

0 Likes
Message 8 of 16

ronjonp
Advisor
Advisor

Try this .. had to make the filter look for text strings on a certain layer.

(defun c:chgtext-all (/ s)
  ;; RJP » 2019-10-01
  ;; List of text string to match, layer filter, new layer
  (foreach l '(("*CAD WELD" "G-ANNO-TEXT" "G-ANNO-TEXT-YELL"))
    (if	(setq s (ssget "_X" (list '(0 . "*TEXT") (cons 1 (car l)) (cons 8 (cadr l)))))
      (foreach e (mapcar 'cadr (ssnamex s)) (entmod (append (entget e) (list (cons 8 (caddr l))))))
    )
  )
  (princ)
)
Message 9 of 16

phillip.curlin
Participant
Participant

i appreciate you time - it works great.

is there anyway to add multiple text strings in this command.

if not this is a huge time save as is - many thanks to all of you out there.

0 Likes
Message 10 of 16

ronjonp
Advisor
Advisor

@phillip.curlin wrote:

i appreciate you time - it works great.

is there anyway to add multiple text strings in this command.

if not this is a huge time save as is - many thanks to all of you out there.


Sure .. separate the strings you want to look for with commas like so:

'(("*CAD WELD,*ANOTHERSTRING*,*ETC*" "G-ANNO-TEXT" "G-ANNO-TEXT-YELL"))
0 Likes
Message 11 of 16

AKeyM
Participant
Participant

Thank you very much for this! I've been using this lisp A LOT for a while now! But its only until now that I wonder if it could be possible to write directly on the command line exactly the text I want to look for? Normaly, I go ahed and edit the code to search for a specific text and then also edit the lines where I want the layer to be named how I want the new layer to be named. But recently, I've been wondering if I really need to do that on the text editor? Is there a way to add the function to this lisp to ask to write the exact text Im looking for and the name of the new layer Im creating? 
Thanks in advance for your kind answer!

0 Likes
Message 12 of 16

Sea-Haven
Mentor
Mentor

Look at ronjonp code, keep the foreach part but before it make the list 

(foreach l '(("*CAD WELD" "G-ANNO-TEXT" "G-ANNO-TEXT-YELL"))

 

 

(setq lst '())
(setq lst (cons (getstring "\nEnter string to find include * ") lst))
(setq lst (cons (getstring "\nEnter old layer name ") lst))
(setq lst (cons (getstring "\nEnter new layer name ") lst))
(foreach l lst

 

 

 

0 Likes
Message 13 of 16

AKeyM
Participant
Participant

Thank you very much for your response. Could you please make a short example? For instance, I'm frequently finding myself searching for texts like, P-1, P-2, P-3 and so on. All can be on a different layer. I'd like to find them (regardless of which layer they are on) and sort them on a new layer for each text targeted. For this example, the result would end up finding P-1, then generating a new layer for P-1 (tipically X-P-1), and repeat the same process for P-2, (on a new layer named X-P-2), the same for P-3 and so on.

I've been using @Anonymous  code for the past 3 years or so, but I always ended up with a bunch of lisps for every project. 

0 Likes
Message 14 of 16

Sea-Haven
Mentor
Mentor

Try this

 

 

(while (/= (setq str1 (getstring "\nEnter string to find include * Enter to exit ")) "")
(setq lst '())
(setq lst (cons str1 lst))
(setq lst (cons (getstring "\nEnter old layer name ") lst))
(setq lst (cons (getstring "\nEnter new layer name ") lst))

(foreach l lst

........................
) ; end while

 

0 Likes
Message 15 of 16

AKeyM
Participant
Participant

I wrote this:

 

(defun C:SEARCH (/)
(if (setq SS (ssget "X" (list (cons 0 "TEXT,MTEXT") (cons 1 (getstring "\nTEXT TO SEARCH ")))))
(progn
(setq XX (getstring "\nNEW LAYER NAME "))
(if (not (tblsearch "LAYER" XX)) (command "LAYER" "M" XX ""))
(setq KK 0)
(command "CHPROP" SS "" "LA" XX "")
)
(setq KK (1+ KK))
)

(alert "Done!")
(princ)
)

 

It searches for a specific text, then makes a layer with the name of your choosing and then changes properties of every element found to be the on the new layer that it just created.

 

But now I'm getting trouble since some texts are in leaders with arrows, so I have to explode those to transform them into searchable text.

0 Likes
Message 16 of 16

AKeyM
Participant
Participant

After lots of trial and errors, finally I corrected some lines and now it works on Text, Mtext and Multileaders.

Also it performs the search on a specific area, instead of the entire project.

 

(defun C:SEARCH (/)

;; ALAN KEY » 2022-08-05
(setq
AA (getstring T "\nTEXT TO SEARCH: ")
)
(if (and (setq text AA)
(setq ss (ssget ":L" (list '(0 . "TEXT,MTEXT,MULTILEADER") (cons 304 (strcat "*" text "*"))))))
(sssetfirst nil ss)
)
(progn
(setq XX (getstring "\nNEW LAYER NAME: "))
(if (not (tblsearch "LAYER" XX)) (command "LAYER" "M" XX ""))
(setq KK 0)
(command "CHPROP" SS "" "LA" XX "")
)
(setq KK (1+ KK))
)
(alert "DONE!")
(princ)
)

 

That was really hard to me, I'm still learning by reading some tutorials and lots of youtube videos.