Lisp to replace block with another block

Lisp to replace block with another block

Manicbala
Enthusiast Enthusiast
23,505 Views
22 Replies
Message 1 of 23

Lisp to replace block with another block

Manicbala
Enthusiast
Enthusiast

Hi,

 

I have tried the below lisp to replace the block "RR" with "Level".


(defun C:QW4 ()

((C:-BLOCKREPLACE) "RR" "level" ""))

 

{{ Command: QW4
Initializing...
Select the block to be replaced or [?/= (select object)]: }}

 

After enter QW4 command, its prompting to select the block instead of replacing. Please resolve this.

 

Bala

Thanks
Bala
0 Likes
Accepted solutions (1)
23,506 Views
22 Replies
Replies (22)
Message 2 of 23

Anonymous
Not applicable

@Manicbala as _.Blockreplace comes from the VBA code, you will not have the result waiting using this code.
But you can try something less structured like the code below and it will have a similar result:

 

(defun c:QW4 (/ ss nbl)
  (prompt "\nSelect block: ")
  (if (setq ss (ssget "_:S:E" '((0 . "INSERT"))))
    (progn
      (setq ss (entget (setq ss (ssname ss 0))))
      (redraw (cdr (assoc 330 ss)) 3)
      (prompt
	"\nSelect blocks to be replaced: "
      )
      (while (setq nbl (ssget "_:S:E" '((0 . "INSERT"))))
	(setq nbl (entget (setq nbl (ssname nbl 0))))
	(entmod	(subst (assoc 2 nbl)
		       (assoc 2 ss)
		       ss
		)
	)
	(redraw entBlock 4)
      )
    )
  )
  (princ)
)
(prompt "Type >> Qw4 <<")

 

 

Message 3 of 23

ChicagoLooper
Mentor
Mentor

Go to Express tools to access the Replace Block command. This command replace all instances of an existing block with another. You may need to SYNC the block after performing the command.

Express Tools>Blocks Panel>Replace BlockExpress Tools>Blocks Panel>Replace Block

Chicagolooper

EESignature

0 Likes
Message 4 of 23

Manicbala
Enthusiast
Enthusiast

@Anonymous Thanks for your response.. Its working fine. But instead of selecting the blocks manually. I want to change the block "RR" to block "Level".

 

Thanks 

Bala

 

Thanks
Bala
0 Likes
Message 5 of 23

gotphish001
Advisor
Advisor

This one lets you select which ones to replace with another one in the drawing like a swap. I never tried to use it for what I think you are asking but I think it would do it. I use it to replace blocks with similar blocks but are different colors to note they are to be demoed. Its great when you don't want to swap them all out which I find is most of the time.



Nick DiPietro
Cad Manager/Monkey

Message 6 of 23

Kent1Cooper
Consultant
Consultant
Accepted solution

@Manicbala wrote:

.... instead of selecting the blocks manually. I want to change the block "RR" to block "Level".


(defun C:RR-Level (/ ss n edata)

  (if (setq ss (ssget "_X" '((2 . "RR"))))

    (repeat (setq n (sslength ss))

      (setq edata (entget (ssname ss (setq n (1- n)))))

      (entmod (subst '(2 . "Level") '(2 . "RR") edata))

    ); repeat

  ); if

); defun

Kent Cooper, AIA
Message 7 of 23

Anonymous
Not applicable

@Manicbala Like that ?

 

(defun c:Qw4 (/ Jr_replaceall answr ent idx nbl obj ss)
  (vl-load-com)
  (if (not Jr_replaceall)
    (setq Jr_replaceall "Single")
    )
  (Command "-.Undo" "_Be")
  (if (and (setq ss (ssget ":S" '((0 . "INSERT"))))
	   (progn
	     (initget "S A")
	     (if (setq answr (getkword "\nReplace only this block or replace All [Single / All]:"))
	       (setq Jr_replaceall answr)
	       (setq answr Jr_replaceall)
	       )
	     )
	   (setq nbl (getstring "\nBlock name to replace with: "))
	   (tblobjname "BLOCK" nbl)
	   )
    (progn
      (if (eq Jr_replaceall "A")
	(setq ss (ssget "x" (list '(0 . "INSERT") (assoc 2 (entget (ssname ss 0))))))
	)
      (setq idx -1)
      (while (setq ent (ssname ss (setq idx (1+ idx))))
	(setq obj (vlax-ename->vla-object ent))
	(vla-put-name obj nbl)
	(vla-update obj)
	)
      )
    )
  (command "_.Undo" "_End")
  (princ (strcat "\nReplaced " (itoa idx) " Blocks"))
  (princ)
  )

 

 

Message 8 of 23

roland.r71
Collaborator
Collaborator

@Manicbala wrote:

Hi,

 

I have tried the below lisp to replace the block "RR" with "Level".


(defun C:QW4 ()

((C:-BLOCKREPLACE) "RR" "level" ""))

 

{{ Command: QW4
Initializing...
Select the block to be replaced or [?/= (select object)]: }}

 

After enter QW4 command, its prompting to select the block instead of replacing. Please resolve this.

 

Bala


You have two extra parenthesis in places where there should be non.

(defun C:QW4 ()

((C:-BLOCKREPLACE) "RR" "level" ""))

Change it to:

 

(defun C:QW4 ()
   (C:-BLOCKREPLACE "RR" "level" "")
)
0 Likes
Message 9 of 23

Manicbala
Enthusiast
Enthusiast

Not working.. Getting below error.

Command: QW4 ; error: too many arguments

 

Bala

Thanks
Bala
0 Likes
Message 10 of 23

Manicbala
Enthusiast
Enthusiast

Thanks @Kent1Cooper. The lisp working fine.

Thanks
Bala
0 Likes
Message 11 of 23

roland.r71
Collaborator
Collaborator

Yeah, my bad. Its Expresstools.

Which is notoriously lisp-unfriendly.

 

The function in question takes no arguments and always asks for the block & replacement on the commandline. (you can find it inside [your acad programfiles dir.]\Express\blocktoxref.lsp )

 

The only difference between the regular and - version is that the later will supress cmddia.

 

So, you better stick to @Kent1Cooper's solution.

 

 

Message 12 of 23

Anonymous
Not applicable

Thank you very much. It's working for me...

Message 13 of 23

_Tharwat
Advisor
Advisor
Message 14 of 23

Anonymous
Not applicable

Thank you very much.

0 Likes
Message 15 of 23

_Tharwat
Advisor
Advisor

You're most welcome. 

0 Likes
Message 16 of 23

blasseigne_HPA
Contributor
Contributor

Is there a way to modify this lisp so I can make it always change a single block to a specific block? For example if I select a New Receptacle block (N-Recept) have it change to and existing Receptacle block (E-Recept). And I want it to change only the block that gets selected.

0 Likes
Message 17 of 23

Kent1Cooper
Consultant
Consultant

@blasseigne_HPA wrote:

Is there a way to modify this lisp so I can make it always change a single block to a specific block? For example if I select a New Receptacle block (N-Recept) have it change to and existing Receptacle block (E-Recept). And I want it to change only the block that gets selected.



For that, I use the BRS command from BlockReplace.lsp, available >here<.  The command name stands for Block Replace: Selected -- you give it your replacement Block name [E-Recept in your description], and then every Block you Select [whether it's a N-Recept Block or not] will be turned into one of those, keeping its insertion point, scales, rotation, etc.

 

[There's also a BRA command, for Block Replace: All, in which you give it your replacement Block name, and then select one  insertion of another Block, and All insertions of that Block name will be changed.]

Kent Cooper, AIA
0 Likes
Message 18 of 23

BL_Apex
Enthusiast
Enthusiast

Hi @Kent1Cooper 

 

Correct me if I'm wrong. This is a LISP that does exactly what -BLOCKREPLACE should do if the command actually worked in LISP? I can't seem to get it to work. The block I am trying to replace is actually inside of another block (the title block to be exact). I am able to successfully replace the block when using BLOCKREPLACE in its normal capacity. But now that I am trying to automate the process using LISP, I've stumbled across this thread for obvious reasons.

 

I replaced the names of @Manicbala's blocks in your LISP with the names of mine. The LISP ran successfully with no errors but the desired block was not replaced.

 

Thoughts?

0 Likes
Message 19 of 23

Kent1Cooper
Consultant
Consultant

@BL_Apex wrote:

.... The block I am trying to replace is actually inside of another block ....

I replaced the names of @Manicbala's blocks in your LISP with the names of mine. The LISP ran successfully with no errors but the desired block was not replaced.

....


Unfortunately, (ssget) can only "see" top-level objects, not nested ones.  You should be able to put the new Block definition into a drawing file of its own [not as a Block within the file, but as the top-level file contents] in a location AutoCAD can find [maybe you already have it that way], then use:

-INSERT

YourNestedBlockName=YourNewFileName

 

[note the hyphen prefix on -INSERT], answer Yes to the question of whether to redefine it, and cancel without going through with Inserting another one.  That should update the definition of even a nested one.  You might need to REGEN to see the change.

Kent Cooper, AIA
Message 20 of 23

BL_Apex
Enthusiast
Enthusiast

I believe this may be the ticket. I'll test it out and let you know.

0 Likes