Select layers with wildcard and move to predined layer

Select layers with wildcard and move to predined layer

Anonymous
Not applicable
2,635 Views
12 Replies
Message 1 of 13

Select layers with wildcard and move to predined layer

Anonymous
Not applicable

Hey, I'm needing some help. I not experience in writing lisp but have a basic idea of following them. I'm trying to create a lisp that uses wildcards to select key words and then automatically put them on a predefined layer. I have something this so far but unfortunately, its not working.

 

(defun c:LAYCH ( / n )
  (setvar 'CLAYER "0")
  (while (setq d (tblnext "LAYER" (null d)))
    (if (and (not (wcmatch (setq n (strcase (cdr (assoc 2 d)))) "*|*,0,DEFPOINTS, D-DETL-TEXT"))
             (wcmatch n "*text*,*dim*")
     )
   (vl-catch-all-apply 'vla-put-name (list layer "C-DETL-TEXT")
   )
   )
 )
 (princ)
)
 
Basically, I want to put all "text, dim, anno" layers on C-DETL-TEXT but not include the actual layer to be put on in the wildcard. I also want to add other "if statements" to include other key words to put like, "wall, building, etc." on the layer "C-DETL-LINE."
 
Can anyone help? It seems like what I have isn't working correctly. I would greatly appreciate any help. Thanks!
0 Likes
Accepted solutions (1)
2,636 Views
12 Replies
Replies (12)
Message 2 of 13

ВeekeeCZ
Consultant
Consultant

Found this on my hdd... not sure if I wrote it.

 

(defun c:mergemultiple ( / lst)
  (setq lst '(("Layer*" "Lay")
              ("Doors*" "Door")))
  
  (foreach e lst (mergelayers (car e) (cadr e)))
  (princ)
)
    

(defun mergelayers (match to / lst def lay)
  (setq str "")
  (while (setq def (tblnext "LAYER" (null lay)))
    (if (wcmatch (setq lay (cdr (assoc 2 def))) match)
      (setq lst (cons lay lst))))
  (if lst
    (progn
      (command "_.LAYMRG")
      (foreach e lst (command "_Name" e))
      (command "" "_N" to "_Y")))
  (princ)
)
0 Likes
Message 3 of 13

Moshe-A
Mentor
Mentor

@Anonymous hi,

 

with (ssget) function you can select objects on any layer by filtering:

 

; example

 (if (setq ss (ssget "x" '((0 . "text") (8 . "text,dim,anno,wall,building"))))
  (command "._chprop" "_si" ss "_layer" "D-DETL-TEXT" "")
 )

 

this selects all text object on the list of layers. read more about (ssget) function in the documentation or website.

 

moshe

 

0 Likes
Message 4 of 13

Anonymous
Not applicable

Thanks, the mergemultiple lisp above seems to work well but only for one layer at a time. Is there a way to add a wildcard search in the first part of that lisp where is reads (setq lst '(("Layer*" "Lay") ("Doors*" "Door")))

 

I don't necessarily want to select all of the text but just all of the layers that have the key words of "text, anno, dims" in the layer and then take those layers and place it on a new layer called "C-DETL-TEXT" and then have another set of key words and place it on a different layer. 

 

I'm not sure if   "(if (and (not (wcmatch (setq n (strcase (cdr (assoc 2 d)))) "*|*,0,DEFPOINTS, D-DETL-TEXT"))
             (wcmatch n "*text*,*dim*")" can be used as apart of that lisp to search for keywords but yet not search for others such as defpoints, D-DETL-TEXT, or anything else I want to exclude in a search.

0 Likes
Message 5 of 13

ВeekeeCZ
Consultant
Consultant
Accepted solution

Not sure how you tested it, but it really does not work for 1 layer at a time.

The code needed just minor enhancements which I thought you would manage yourself... anyway, HTH

 

(defun c:mergemultiple ( / lst)

  (setq lst '(("*text*,*anno*,*dims*" "D-DETL-TEXT")
              ("*wall*,*building*" "D-DETL-LINE")))
  
  (foreach e lst (mergelayers (car e) (cadr e)))
  (princ)
)
    

(defun mergelayers (match to / lst def lay)
  (setq str "")
  (or (tblsearch "LAYER" to)
      (command "_.LAYER" "_N" to ""))
  (while (setq def (tblnext "LAYER" (null lay)))
    (if (and (wcmatch (strcase (setq lay (cdr (assoc 2 def)))) (strcase match))
             (not (wcmatch (strcase lay) (strcat "*|*,0,DEFPOINTS," (strcase to))))
             )
      (setq lst (cons lay lst))))
  (if lst
    (progn
      (command "_.LAYMRG")
      (foreach e lst (command "_Name" e))
      (command "" "_N" to "_Y")))
  (princ)
)
Message 6 of 13

Anonymous
Not applicable

Thanks, I appreciate your help. I was going thru it and was having issues loading it into the drawing so I had to close and reopen the drawing and now, it seems to be working perfectly to what I was looking for. Thank you again for your help!

0 Likes
Message 7 of 13

ВeekeeCZ
Consultant
Consultant

Ohh, ok. You're welcome.

I made one more update of the code. 

0 Likes
Message 8 of 13

Anonymous
Not applicable
Hey, I have a question about the code below. I attempted adding a part and kept getting an error message but as shown in the first part (setq lst '(("*ANNO*,*DIM*,TEXT*" "C-DETL TEXT"), it searches for everything under "text" but I get an error message saying it cant merge "C-DETL TEXT" since that is the layer it is being merge with. The layers are being merged into C-DETL TEXT but how can I exclude this layer in the list of layers being merge to not get the message.
 
I tried adding "(if (and (wcmatch (setq lay (cdr (assoc 2 def))) match))
        (not (wcmatch "C-DETL TEXT"))" but get an error message. Can anyone help?
 
(defun c:MGL ( / lst)
(setvar 'CLAYER "0")
(setq lst '(("*ANNO*,*DIM*,TEXT*" "C-DETL TEXT")
              ("*BO*,*BORDER*,*GEOM*,*OBJECT*,*REBAR*,*WALK*" "C-DETLS")
              ("HATCH*" "C-DETL HATCH")))
 
  (foreach e lst (mergelayers (car e) (cadr e)))
  (princ)
)
   
(defun mergelayers (match to / lst def lay)
  (setq str "")
  (while (setq def (tblnext "LAYER" (null lay)))
    (if (wcmatch (setq lay (cdr (assoc 2 def))) match)
      (setq lst (cons lay lst))))
  (if lst
    (progn
      (command "_.LAYMRG")
      (foreach e lst (command "_Name" e))
      (command "" "_N" to "_Y")))
  (princ)
)
0 Likes
Message 9 of 13

ВeekeeCZ
Consultant
Consultant

Right, you're not using the last version. This issue is covered by the update as I wrote about at last post.

The line is:

(not (wcmatch (strcase lay) (strcat "*|*,0,DEFPOINTS," (strcase to))))

 

Although I decided to update the code little further - to exclude the (little) possibility of cross-matching. 

(defun c:MergeMultiple ( / lst exclude)

  (setq lst '(("*text*,*anno*,*dims*" "D-DETL-TEXT")
              ("*wall*,*building*" "D-DETL-LINE")))

  (setq exclude (apply 'strcat (mapcar '(lambda (x) (strcat x ",")) (append '("*|*" "0" "DEFPOINTS") (mapcar 'strcase (mapcar 'cadr lst))))))
  
  (foreach e lst (mergelayers (car e) (cadr e) exclude))
  (princ)
)

(defun mergelayers (match to exclude / lst def lay)
  (setq str "")
  (or (tblsearch "LAYER" to)
      (command "_.LAYER" "_N" to ""))
  (while (setq def (tblnext "LAYER" (null lay)))
    (if (and (wcmatch (strcase (setq lay (cdr (assoc 2 def)))) (strcase match))
             (not (wcmatch (strcase lay) exclude))
             )
      (setq lst (cons lay lst))))
  (if lst
    (progn
      (command "_.LAYMRG")
      (foreach e lst (command "_Name" e))
      (command "" "_N" to "_Y")))
  (princ)
)

 

 

Message 10 of 13

diepkhoi90
Contributor
Contributor
Dude, this lisp is the only thing I've found that can impact deep inside the blocks, which is impressive!
There is one thing I would like to ask for help with, when combining layers, there are some layers that are suitable for "keyword" but I want to exclude them from the combining. Is there a way to do this?

 

0 Likes
Message 11 of 13

Kent1Cooper
Consultant
Consultant

@diepkhoi90 wrote:
... I would like to ask for help with, when combining layers, there are some layers that are suitable for "keyword" but I want to exclude them from the combining. Is there a way to do this?

....'("*|*" "0" "DEFPOINTS" "YourExcludedLayer1" "YourExcludedLayer2" "YourExcludedLayer3")....

 

Kent Cooper, AIA
Message 12 of 13

diepkhoi90
Contributor
Contributor

Thank mate!

0 Likes
Message 13 of 13

diepkhoi90
Contributor
Contributor

@ВeekeeCZ wrote:

Right, you're not using the last version. This issue is covered by the update as I wrote about at last post.

The line is:

(not (wcmatch (strcase lay) (strcat "*|*,0,DEFPOINTS," (strcase to))))

 

Although I decided to update the code little further - to exclude the (little) possibility of cross-matching. 

(defun c:MergeMultiple ( / lst exclude)

  (setq lst '(("*text*,*anno*,*dims*" "D-DETL-TEXT")
              ("*wall*,*building*" "D-DETL-LINE")))

  (setq exclude (apply 'strcat (mapcar '(lambda (x) (strcat x ",")) (append '("*|*" "0" "DEFPOINTS") (mapcar 'strcase (mapcar 'cadr lst))))))
  
  (foreach e lst (mergelayers (car e) (cadr e) exclude))
  (princ)
)

(defun mergelayers (match to exclude / lst def lay)
  (setq str "")
  (or (tblsearch "LAYER" to)
      (command "_.LAYER" "_N" to ""))
  (while (setq def (tblnext "LAYER" (null lay)))
    (if (and (wcmatch (strcase (setq lay (cdr (assoc 2 def)))) (strcase match))
             (not (wcmatch (strcase lay) exclude))
             )
      (setq lst (cons lay lst))))
  (if lst
    (progn
      (command "_.LAYMRG")
      (foreach e lst (command "_Name" e))
      (command "" "_N" to "_Y")))
  (princ)
)

 

 


One more question. I'm Vietnamese so we got some weird character like " ổ, ậ, đ ..." Does it possible to make you lisp understand non-Latin keyword in the replace list.

Thanks!

0 Likes