Announcements

Starting in December, we will archive content from the community that is 10 years and older. This FAQ provides more information.

Move or Delete objects on layers with AutoLisp

Anonymous

Move or Delete objects on layers with AutoLisp

Anonymous
Not applicable

I have a routine written to loop through all of my layers on my drawing.  I'm trying to have it move the items to another layer or delete them if they are on a certain layer.  I have the if statements set up properly, but I cannot figure out the change or erase commands.

 

Here is the code I currently have - I have it set up to princ on each layer what I would like it to do so I could make sure it does the right thing:

(defun c:testmacro ()
	(setvar 'CLAYER "0")
	(setq layer (tblnext "LAYER" T))
	(while layer
		(if (= (substr (cdr (assoc 2 layer)) 1 2) "D-")
			(progn
				;ERASE ALL ITEMS ON LAYER
				(princ (strcat "\nDelete items on " (cdr (assoc 2 layer))))
			)
			(progn
				(if (= (substr (cdr (assoc 2 layer)) 1 2) "P-")
					(progn
						;CHANGE LAYER FROM P- TO E-
						(princ (strcat "\nMove from " (cdr (assoc 2 layer))))
						(princ (strcat " to "P-" (substr (cdr (assoc 2 layer)) 3)))
						
					)
					(progn
						;OTHERWISE DO NOTHING
					)
				)
			)
		)
		(setq layer (tblnext "LAYER"))
	)
)

I've tried using (ssget "_X" '((8 . (cdr (assoc 2 layer))))) to select all of the items on the layer in the CHPROP/CHANGE and ERASE commands but I get an error stating "bad SSGET list value".

0 Likes
Reply
Accepted solutions (1)
1,949 Views
15 Replies
Replies (15)

Kent1Cooper
Consultant
Consultant

It sounds to me like what you want to do can be handled by the LAYMRG and LAYDEL commands, without the need to step through anything.

Kent Cooper, AIA

Anonymous
Not applicable

Hi Kent

Typically, that would be the route I would like to take however I would like to maintain the layers (just move or delete the objects off of it).

I have layers for E-, P-, and D- for Existing, Proposed, and Demo.  The items on the demo will be removed and the proposed items will be added to the existing once construction is complete.

I would like to keep the P- and D- layers for any future work that needs to be done in these areas.

 

Edit:

I realize LAYDEL may work well for me to delete the items off of the D- layer, but it doesn't seem like LAYMRG is what would work well for me.

0 Likes

Anonymous
Not applicable

It's not letting me edit a second time - unfortunately neither of these will work for my purpose.

I appreciate the suggestion!

0 Likes

Kent1Cooper
Consultant
Consultant

Maybe more of a description is needed, but I would think that LAYMRG would be just the thing to move things from the "P-..." Layer to the "E-..." Layer.

 

Personally, I think I would put together a routine that uses LAYDEL and LAYMRG, and then just re-makes the Layers lost through those commands.  It could be quite simple, since it would require no stepping through anything.

Kent Cooper, AIA
0 Likes

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

....

I've tried using (ssget "_X" '((8 . (cdr (assoc 2 layer))))) to select all of the items on the layer ....


 

As with another thread today, you can't use a "quoted list" with the apostrophe in front for something that has elements inside that need to be evaluated.  You need an explicit (list) function, and to put the Layer name together with its DXF-code 8 using (cons).  Try:

 

(ssget "_X" (list (cons 8 (cdr (assoc 2 layer)))))

Kent Cooper, AIA

Anonymous
Not applicable

I'll definitely look into it - I wasn't sure of how well it would work as I have about 60 layers total (about 20 each) and they aren't always used in each set (e.g. D-CLNG isn't always utilized).

But I guess deleting and recreating an empty layer wouldn't be a big deal.

0 Likes

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... I have about 60 layers total (about 20 each) ....


 

I guess a routine such as I suggested would then need to step through the 20ish after-the-prefix parts to do its LAYMRG and LAYDEL things.  Whether that is more work than stepping through all the drawing objects may depend on how large a given drawing is.

Kent Cooper, AIA
0 Likes

Anonymous
Not applicable

Thank you - I got this to work in some instances but not in others.

I wrote it so that anything on layer "1" was erased and it had no problem with that.

Then I placed it into my code listed earlier in the first if statement and I just get the program calling itself again.  The log goes from "Select objects:" to "Command: TESTMACRO".

(command "._ERASE" (ssget "_X" (list (cons 8 (cdr (assoc 2 layer))))) "")
0 Likes

Anonymous
Not applicable

I changed my code from nested IFs to COND thinking maybe the issue was coming from the PROGN but I'm still getting the same "loop" where it calls itself.

Here is the code as it currently stands - I commented out the misfunctioning items.

(defun c:testmacro ()
	(setvar 'CLAYER "0")
	(setq layer (tblnext "LAYER" T))
	(while layer
		(cond
			((= (substr (cdr (assoc 2 layer)) 1 2) "D-")
				;(command "._ERASE" (ssget "_X" (list (cons 8 (cdr (assoc 2 layer))))) "")
				(princ (strcat "\nDelete all on " (cdr (assoc 2 layer))))
			)
			((= (substr (cdr (assoc 2 layer)) 1 2) "P-")
				(princ (strcat "\nMove from " (cdr (assoc 2 layer))))
				(princ (strcat " to E-" (substr (cdr (assoc 2 layer)) 3)))
				;(command "._CHPROP" (ssget "_X" (list (cons 8 (cdr (assoc 2 layer))))) "" "LA" (strcat "D-" (substr (cdr (assoc 2 layer)) 3)))
			)
			(t
				(princ (strcat "\nDo nothing to " (cdr (assoc 2 layer))))
			)
		)
		(setq layer (tblnext "LAYER"))
	)
	(princ)
)
0 Likes

ВeekeeCZ
Consultant
Consultant
Accepted solution

Something like this?

 

Notes: keep in mind that this does not handle objects outside the current space!

Also, you might what to unlock all layers, thaw all layers...

 

(defun c:testmacro ( / ss l layer nlayer)
  (setvar 'CLAYER "0")

  (if (setq ss (ssget "_X" '((8 . "D-*"))))
    (command "._ERASE" ss ""))
  
  (while (setq l (tblnext "LAYER" (null l)))
    (setq layer (cdr (assoc 2 l)))

    (if (and (wcmatch layer "P-*")
	     (setq ss (ssget "_X" (list (cons 8 layer))))
	     (setq nlayer (strcat "E" (substr layer 2)))
	     (or (tblsearch "LAYER" nlayer)
		 (vl-cmdf "_.LAYER" "_N" nlayer ""))
	     )
      (command "_.CHPROP" ss "" "_Layer" nlayer "")))
  (princ)
  )

 

Anonymous
Not applicable

 

(while layer

🤔 ???

 

0 Likes

ВeekeeCZ
Consultant
Consultant

@Anonymous wrote:

 

(while layer

🤔 ???

 


 

Nothing really wrong about it. You gotta see the whole context.

 

(setq layer (tblnext "LAYER" T))
(while layer
  
  ;;; body

  (setq layer (tblnext "LAYER"))
  )
0 Likes

Anonymous
Not applicable

That works beautifully thank you for the help!

0 Likes

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... I'm still getting the same "loop" where it calls itself. ....



Without studying deeply, I wonder....  Could it be from some such Layer not having anything on it?  Can you fix it by using an (if) test for whether  it found something, before invoking the ERASE or CHPROP command?

 

Your CHPROP command needs another "" at the end to complete it [you could go on to change another property of the same selection within the same command, so you need to tell it you're done].

Kent Cooper, AIA
0 Likes

Anonymous
Not applicable

Ah that is a good point - I'll have to test it out!

Like how BeekeeCZ did the (if (setq ss (ssget… to check that it would even provide that before running the command!

 

And you are right - whoops just forgot to add those (pretty important 😊)

0 Likes