Help with a LISP code.

Help with a LISP code.

UNKNOWN.DESIGN.LAB
Advocate Advocate
3,371 Views
22 Replies
Message 1 of 23

Help with a LISP code.

UNKNOWN.DESIGN.LAB
Advocate
Advocate

Hello i am trying to add a super practical LISP code i found that will change all block items layer to "0" layer and end the "CANNOT DELETE LAYER BECAUSE IT IS BEING USED BY BLOCK(S)" issue.

 

It is my first time creating a LISP, though i followed a tutorial before this one and got the code they were using to work properly.

 

I found this code code i want to use here: < http://forums.augi.com/showthread.php?127731-changing-multiple-blocks-to-quot-0-quot-layer >

 

Here is the error message COPIED FROM MY COMMAND LINE:

Command: FIXBLKS
Select objects: 1 found
Select objects: undo Current settings: Auto = On, Control = All, Combine = Yes, Layer = Yes
Enter the number of operations to undo or [Auto/Control/BEgin/End/Mark/Back] <1>: BEgin
Command: ; error: no function definition: VLAX-ENAME->VLA-OBJECT

 

I will attach a copy of the .lsp i created with this post as well for anyone who wished to review.

 

Here is the code copied

[This is an amateur question but should not the code start at the "(defun.....)" and not "; written by:....." ??]:

; Written By: Tom Beauford
; Changes all block entities to layer "0" with color, linetype & lineweight ByBlock
(defun C:FIXBLKS (/ SSET intCount ENAM ELST BNAM FLST FIX1)
  (defun FIX1 (BNAM / BENAM BONAM)
    (if (not (member BNAM FLST))
   (progn
     (setq FLST  (cons BNAM FLST)
     BENAM (tblobjname "block" BNAM)
     )
   (while (setq BENAM (entnext BENAM))
      (if (= (cdr (assoc 0 (entget BENAM))) "INSERT")
       (fix1 (cdr (assoc 2 (entget BENAM))))
       (progn
         (setq BONAM(vlax-ename->vla-object BENAM))
                (vl-catch-all-apply 'vla-put-layer (list BONAM "0"))
                (vl-catch-all-apply 'vla-put-color (list BONAM 0))
                (vl-catch-all-apply 'vla-put-linetype (list BONAM "Byblock"))
                (vl-catch-all-apply 'vla-put-Lineweight (list BONAM -2))
;                (vl-catch-all-apply 'vla-put-PlotStyleName (list BONAM "Byblock"))
       )
     )
   )
        )
    )
  )
  (setq SSET (ssget (list (cons 0 "INSERT"))))
  (vl-cmdf "undo" "BEgin")
  (repeat (setq intCount (sslength SSET))
    (setq intCount     (1- intCount)
          ENAM (ssname SSET intCOunt)
    ELST (entget ENAM)
    BNAM (cdr (assoc 2 ELST))
    FLST nil
    )
    (fix1 BNAM)
  )
  (vl-cmdf "undo" "End")
  (vl-cmdf "regen")
  (princ)
)

 

0 Likes
Accepted solutions (1)
3,372 Views
22 Replies
Replies (22)
Message 2 of 23

Kent1Cooper
Consultant
Consultant

Add the line:

 

(vl-load-com)

 

at the very top or very bottom of the file.

Kent Cooper, AIA
0 Likes
Message 3 of 23

UNKNOWN.DESIGN.LAB
Advocate
Advocate

Hello @Kent1Cooper,

 

Thank you for the suggestion. I added the (vl-load-com) My LISP currently looks like this:

 

(defun C:FIXBLKS (/ SSET intCount ENAM ELST BNAM FLST FIX1)
(defun FIX1 (BNAM / BENAM BONAM)
(if (not (member BNAM FLST))
(progn
(setq FLST (cons BNAM FLST)
BENAM (tblobjname "block" BNAM)
)
(while (setq BENAM (entnext BENAM))
(if (= (cdr (assoc 0 (entget BENAM))) "INSERT")
(fix1 (cdr (assoc 2 (entget BENAM))))
(progn
(setq BONAM(vlax-ename->vla-object BENAM))
(vl-catch-all-apply 'vla-put-layer (list BONAM "0"))
(vl-catch-all-apply 'vla-put-color (list BONAM 0))
(vl-catch-all-apply 'vla-put-linetype (list BONAM "Byblock"))
(vl-catch-all-apply 'vla-put-Lineweight (list BONAM -2))
; (vl-catch-all-apply 'vla-put-PlotStyleName (list BONAM "Byblock"))
)
)
)
)
)
)
(setq SSET (ssget (list (cons 0 "INSERT"))))
(vl-cmdf "undo" "BEgin")
(repeat (setq intCount (sslength SSET))
(setq intCount (1- intCount)
ENAM (ssname SSET intCOunt)
ELST (entget ENAM)
BNAM (cdr (assoc 2 ELST))
FLST nil
)
(fix1 BNAM)
)
(vl-cmdf "undo" "End")
(vl-cmdf "regen")
(princ)
)
(vl-load-com)

 

I am still getting this error message [Command line script enclosed]:

Command: FIXBLKS
Select objects: 1 found
Select objects: undo Current settings: Auto = On, Control = All, Combine = Yes, Layer = Yes
Enter the number of operations to undo or [Auto/Control/BEgin/End/Mark/Back] <1>: BEgin
Command: ; error: no function definition: VLAX-ENAME->VLA-OBJECT

 

Maybe i added the < (vl-load-com) > at a wrong place ?

Attached is the .lsp as well to review.

 

0 Likes
Message 4 of 23

ВeekeeCZ
Consultant
Consultant

Then follow THESE suggestions.

 

0 Likes
Message 5 of 23

dbroad
Mentor
Mentor

I'm glad you want to learn lisp but this doesn't necessarily seem a real need since there are already several  built-in commands that do that:

1) Setbylayer See http://tinyurl.com/yyhnrau5  This command has an option to include blocks.

2) laymrg  This express tool is a better alternative to laydel since it allows you to merge any layer with 0, thus deleting that layer.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 6 of 23

UNKNOWN.DESIGN.LAB
Advocate
Advocate

Greetings @dbroad ,

Thank you for your reply! I work with several other people on projects and my layering structure gets messed up on account of all the manufacturers block i have to import and the ones others use when they edits the model. I want to solve this problem once and for all so i appreciate your help.

 

I tried LAYMERG and it does work to an extent but creates other problems. Scenario:

I have a block, dubbed [dubbed B1] that in its definition is on layer "X" and may also have a nested block [Dubbed B2] that is on another layer, lets say "Z". I want to merge layer "X" to layer "0".

 

LAYMERGE does successfully merge layer "X" to layer "0" and deletes therein layer "X" from my drawing.

The issue is LAYMERGE leaves B1 that was defined to layer "X" now undefined + the nested B2 that was defined to layer "Z" unchanged and still define to layer "Z".

 

I end up with no layer "X", which is a win. But then have to go into B1 to change its undefined layer to layer "0" and then while in B1 go into B2 that is nested in B1 to changes its layer to "0" as well. Which required time and defeats the purpose of what i want to do. [Note not all block i deal with have nested blocks, this is is the full scenario]

 

I am trying to find a LISP routine or a way to quickly change the layers defined in a block's definition and also include in the change to layer "0" any nested blocks that might be in the main block.

0 Likes
Message 7 of 23

maxim_k
Consultant
Consultant

@UNKNOWN.DESIGN.LAB wrote:

 

I am trying to find a LISP routine or a way to quickly change the layers defined in a block's definition and also include in the change to layer "0" any nested blocks that might be in the main block.


Hi @UNKNOWN.DESIGN.LAB 

 

You forgot to mention that you are using AutoCAD for Mac, which doesn't support Visual LISP, unfortunately.

So you need routine in plain AutoLISP (without using VL- functions). I think it is possible to create such routine (or even find a ready-made AutoLISP routine that solves a similar problem). An example of such kind of routine can be found here:

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/change-layer-inside-a-block/td-p/765...

 

As fo me, sorry, but I don't have enough time for now to help you directly with this LISP, but maybe some of AutoLISP gurus here - @Kent1Cooper , @ВeekeeCZ -  can help you with creating (or finding) such routine.

 


Do you find the posts helpful? "LIKE" these posts!
Have your question been answered successfully? Click 'ACCEPT SOLUTION' button.


Maxim Kanaev
Architect
MARSS

MacACAD | Linkedin

Etiquette and Ground Rules of Autodesk Community
0 Likes
Message 8 of 23

ВeekeeCZ
Consultant
Consultant

Ok, back to your original question.

Try to type to the command line:

(vl-load-com)

then

!vlax-ename->vla-object

If you receive nil, then it's a major issue that has to be resolved by fixing the Registry, follow the link I gave you before. Then will your code work!

Edited: Never mind, didn't see that you're on Mac.

 

 

 

Your question about starting with

; written by...

If the line is initiated with a semicolon, it means its a commentary and that line is ignored by the interpreter. That said, the code starts with (defun ...) in fact.

0 Likes
Message 9 of 23

maxim_k
Consultant
Consultant
Hi @ВeekeeCZ ,

OP uses AutoCAD for Mac and (vl-load-com) function IS NOT SUPPORTED in AutoCAD for Mac as well as other Visual LISP functions. OP needs plain AutoLISP code which will work on Mac platform.

Do you find the posts helpful? "LIKE" these posts!
Have your question been answered successfully? Click 'ACCEPT SOLUTION' button.


Maxim Kanaev
Architect
MARSS

MacACAD | Linkedin

Etiquette and Ground Rules of Autodesk Community
0 Likes
Message 10 of 23

dlanorh
Advisor
Advisor
Accepted solution

Try this quick and dirty solution. No error checking. It iterates the block table and changes the layer of every non layer "0" entity to layer "0"

 

(defun c:fixblks ( / blk ent e_lst)

  (while (setq blk (tblnext "Block" nil))
    (setq ent (tblobjname "block" (cdr (assoc 2 blk))))
    (while (setq ent (entnext ent))
      (if (/= (cdr (assoc 8 (setq e_lst (entget ent)))) "0")
        (entmod (subst (cons 8 "0") (assoc 8 e_lst) e_lst))  
      );end_if
    );end_while
  );end_while
  (command "_.regen")
  (princ)
);end_defun 

I am not one of the robots you're looking for

Message 11 of 23

maxim_k
Consultant
Consultant
Hi Ron,

Thank you for your help.
Your code works fine in AutoCAD for Mac. Just tested it with one of drawings and 16 layers which were inside blocks were PURGEd successfully after using FIXBLKS.

PS Cannot mark as a solution, let's wait for OP 😉

Do you find the posts helpful? "LIKE" these posts!
Have your question been answered successfully? Click 'ACCEPT SOLUTION' button.


Maxim Kanaev
Architect
MARSS

MacACAD | Linkedin

Etiquette and Ground Rules of Autodesk Community
Message 12 of 23

ВeekeeCZ
Consultant
Consultant

@maxim_k wrote:
Hi @ВeekeeCZ ,

OP uses AutoCAD for Mac...

 

Ohh, thanks for that note. Unfortunately, I didn't read your previous post before. Now it makes sense.

Hopefully, @dlanorh gets that resolved.

0 Likes
Message 13 of 23

dlanorh
Advisor
Advisor
Not a problem. If you hadn't pointed out the "MAC" issue we would all still be scratching our heads.

I am not one of the robots you're looking for

0 Likes
Message 14 of 23

dbroad
Mentor
Mentor
"LAYMERGE does successfully merge layer "X" to layer "0" and deletes therein layer "X" from my drawing The issue is LAYMERGE leaves B1 that was defined to layer "X" now undefined the nested B2 that was defined to layer "Z" unchanged and still define to layer "Z".

Please attach a drawing that would exhibit this behavior. I've never heard of laymrg undefining blocks. It should move the insertion layer from X to 0 and move all of the nested objects that were on layer X to layer 0. It should not affect anything on any other layer.  The setbylayer command also works very well.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 15 of 23

maxim_k
Consultant
Consultant

Hi Doug,

 

@dbroad wrote:

  The setbylayer command also works very well.


Unfortunately SETBYLAYER command is not available in AutoCAD for Mac.

And @UNKNOWN.DESIGN.LAB  works in AutoCAD for Mac.

 


Do you find the posts helpful? "LIKE" these posts!
Have your question been answered successfully? Click 'ACCEPT SOLUTION' button.


Maxim Kanaev
Architect
MARSS

MacACAD | Linkedin

Etiquette and Ground Rules of Autodesk Community
0 Likes
Message 16 of 23

UNKNOWN.DESIGN.LAB
Advocate
Advocate

Hello @dbroad, thank you for your interest and support.

 

FIND COPIED FROM MY COMMAND LINE THE SCRIPT OF MY ACTIONS:

Command: LAYMER
-LAYMRG
Select object on layer to merge or [Name]
Selected layers: Nessuna.
Select object on layer to merge or [Name/Undo]
Selected layers: Nessuna.
Select object on layer to merge or [Name/Undo]
Select object on target layer to merge or [Name]:
You are about to merge layer "Nessuna" into layer "0"
Do you wish to continue?[Yes/No]Y

 

I have also attached reference images for you as requested for you to look at what happens. They will be as follows:

 

1. A shot from inside the block before any action is taken with everything in the block selected. This block has a nested one in it. It is the object with what resembles marble veins. You can see they are both on a layer labelled "Nessuna" . Please refer to the properties manager in the lower right corner to see that.

 

2. Only the nested block selected showing in the properties manager that it is also on "Nessuna"

 

3. A shot from inside the block after running the -LAYMERGE command with the reference script copied that was mentioned above. Refer to the properties manager box again to see that now the objects in the block have undefined layers. The field is blank !

 

I hope this helps you determine the cause.

 

Regards

0 Likes
Message 17 of 23

maxim_k
Consultant
Consultant
Run AUDIT command to bring back layer property to these objects. It will be not 0, but "AUDIT...." layer.
LAYMGR cannot work correctly with layers inside blocks.
Have you tried AutoLISP routine provided by @ВeekeeCZ?

Do you find the posts helpful? "LIKE" these posts!
Have your question been answered successfully? Click 'ACCEPT SOLUTION' button.


Maxim Kanaev
Architect
MARSS

MacACAD | Linkedin

Etiquette and Ground Rules of Autodesk Community
0 Likes
Message 18 of 23

UNKNOWN.DESIGN.LAB
Advocate
Advocate

Hey guys@dlanorh @maxim_k,

 

I am trying to run the code now, bare with me but i think it worked fine ! I ran in on a drawing and was able to the previously mentioned to @dbroad layer "Nessuna" and others like it easily now. I checked the blocks afterwards and they were all set inside their definitions to layer "0".  This is exactly the routine outcome i was seeking ! I am sure this will be of use to many Autocad for Mac users.

 

I will take it out for a spin today and by tomorrow EETime and if all is good will close this thread with an accepted solution and a big cheers to everyone ! Robot Very Happy. Just because if i face any hickups it will be easier to reply to this thread instead of opening up a new one.

 

@dlanorh for me to understand this code better, it seems like it will run through the block table and changes the block layers of all non "0" define objects to "0" layer? IE if i run this routine in a drawing file all the blocks will be defined to layer "0" after ?

 

Also if you see any error checks /  enhancements to conclude your gem of a fix i, and those after me, will surely appreciate it every time we use it.

 

Cheers

[I wish there was a champagne glass emoticon on here]

0 Likes
Message 19 of 23

dlanorh
Advisor
Advisor

@UNKNOWN.DESIGN.LAB wrote:

Hey guys@dlanorh @maxim_k,

 

I am trying to run the code now, bare with me but i think it worked fine ! I ran in on a drawing and was able to the previously mentioned to @dbroad layer "Nessuna" and others like it easily now. I checked the blocks afterwards and they were all set inside their definitions to layer "0".  This is exactly the routine outcome i was seeking ! I am sure this will be of use to many Autocad for Mac users.

 

I will take it out for a spin today and by tomorrow EETime and if all is good will close this thread with an accepted solution and a big cheers to everyone ! Robot Very Happy. Just because if i face any hickups it will be easier to reply to this thread instead of opening up a new one.

 

@dlanorh for me to understand this code better, it seems like it will run through the block table and changes the block layers of all non "0" define objects to "0" layer? IE if i run this routine in a drawing file all the blocks will be defined to layer "0" after ?

 

Also if you see any error checks /  enhancements to conclude your gem of a fix i, and those after me, will surely appreciate it every time we use it.

 

Cheers

[I wish there was a champagne glass emoticon on here]


 

Re your blue text, Yes ,It will set ALL  entities in ALL blocks that are not on layer "0" to layer "0", but is easily adapted to handle selected blocks.

 

There is no error checking as this was a residual bit of autolisp code that i inserted into a defun. Most of my error code makes use of visual lisp, and I didn't have time to re-write anything in autolisp.

I am not one of the robots you're looking for

0 Likes
Message 20 of 23

maxim_k
Consultant
Consultant
>>>>Also if you see any error checks / enhancements to conclude your gem of a fix i, and those after me, will surely appreciate it every time we use it.

Such kind of routine rums quickly and without user interaction, so - error checking is not needed.

Do you find the posts helpful? "LIKE" these posts!
Have your question been answered successfully? Click 'ACCEPT SOLUTION' button.


Maxim Kanaev
Architect
MARSS

MacACAD | Linkedin

Etiquette and Ground Rules of Autodesk Community
0 Likes