Convert multiple block with different name as single block

Convert multiple block with different name as single block

Prashanthr
Enthusiast Enthusiast
446 Views
9 Replies
Message 1 of 10

Convert multiple block with different name as single block

Prashanthr
Enthusiast
Enthusiast

Hello,

 

I have multiple similar block with different name. I want to rename all block as same. I cannot use the "BLOCKREPLACE" as I need the attribute value to remain as it is.

The blocks have name as "FA-1", "FA-2", "FA-3" and so on. I want to make all the block as same with name "FA devices"

Attached is the sample drawing.

0 Likes
447 Views
9 Replies
Replies (9)
Message 2 of 10

Brock_Olly
Collaborator
Collaborator

That's not possible with conventional commands unfortunately (you want to keep the attributes the same I'm guessing).
You'd need a custom LISP routine for this.

0 Likes
Message 3 of 10

Prashanthr
Enthusiast
Enthusiast

Hello @Brock_Olly 

 

Thanks. Yes, its not possible with built in AutoCAD functions. I assume it should be possible with custom lisp.

0 Likes
Message 4 of 10

Moshe-A
Mentor
Mentor

@Prashanthr  hi,

 

check BLKDEFALN command.

 

Your blocks FA-2, FA-3 insertion base point are not synced with FA-1 insertion base point, this results RA-1 is laid not in place 😫

 

the program copies the value of all matches attributes (not only test)

 

enjoy

Moshe

 

(defun c:blkdefaln (/ _insert_block ; local functions
		      savAttdia savAttreq ss data^ dat0 dat1 ename1 AcDbBlkRef0 AcDbBlkRef1 elis1 p0 sx sy rot AcDbAttrib0 AcDbAttrib1 )

 (defun _collect (p)
  (vl-sort
    (mapcar
      (function
        (lambda (ename / elist)
         (setq elist (entget ename))
         (cons (cdr (assoc '2 elist)) ename)
        ); lambda
      ); function
      (vl-remove-if 'listp (mapcar 'cadr (ssnamex p)))
    ); mapcar
    (function (lambda (e0 e1) (< (car e0) (car e1))))
   )
 ); _collect
  

 ; here start c:blkdefaln
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")

 (setq savAttdia (getvar "attdia"))
 (setq savAttreq (getvar "attreq"))
  
 (setvar "attdia" 0)
 (setvar "attreq" 0)
  
 (if (setq ss (ssget '((0 . "insert") (2 . "FA-#") (66 . 1))))
  (progn
   (setq data^ (_collect ss))

   (setq dat0 (nth 0 data^))
   (setq AcdbBlkRef0 (vlax-ename->vla-object (cdr dat0)))
   
   (foreach dat1 (cdr data^)
    (setq ename1 (cdr dat1))
    (setq AcdbBlkRef1 (vlax-ename->vla-object ename1))
     
    (setq elist1 (entget (cdr dat1)))
    (setq p0  (cdr (assoc '10 elist1)))
    (setq sx  (cdr (assoc '41 elist1)))
    (setq sy  (cdr (assoc '42 elist1)))
    (setq rot (cdr (assoc '50 elist1)))
     
    (command "._insert" (car dat0) "_None" p0 sx sy (angtos rot 0 4))
    (command "._chprop" "_si" (entlast) "_layer" (cdr (assoc '8 elist1)) "")
     
    (setq AcdbBlkRef2 (vlax-ename->vla-object (entlast)))

    (vl-some
      (function
        (lambda (AcDbAttrib1 AcDbAttrib2)
         (if (eq
	       (strcase (vla-get-tagString AcDbAttrib1))
	       (strcase (vla-get-tagString AcDbAttrib2))
   	     )
            (vla-put-textString AcDbAttrib2 (vla-get-textString AcDbAttrib1))
	 ); if
	); lambda
      ); function
      (vlax-invoke AcDbBlkRef1 'GetAttributes) (vlax-invoke AcDbBlkRef2 'GetAttributes)
    ); vl-some

    (vlax-release-object AcDbBlkRef2)
    (vlax-release-object AcDbBlkRef1)
    (entdel ename1)
   ); foreach

   (vlax-release-object AcdbBlkRef0) 
  ); progn
 ); if


 (setvar "attreq" savAttreq)
 (setvar "attdia" savAttdia)

 (command "._undo" "_end")
 (setvar "cmdecho" 1)
   
 (princ)
); c:blkdefaln

 

 

 

Message 5 of 10

Prashanthr
Enthusiast
Enthusiast

Hello @Moshe-A 

 

Good Morning!

Thank you so much. This works good. Not an issue with the base-point going off, I can adjust them. Can this code be modified to select other block with other names as well? Currently the code only select block with name "FA-#". Since I had shared a sample drawing, in real the block names can be different.

I tried to remove the below code and it worked in selecting all block irrespective of the name, but the block being replace was the last created block.
Thanks in advance.

(2 . "FA-#")

 

0 Likes
Message 6 of 10

gdi_matetamas
Explorer
Explorer

Instead of this line:

 

(if (setq ss (ssget '((0 . "insert") (2 . "FA-#") (66 . 1))))

 

You should write this:

 

(if (setq ss (ssget "_L" '((0 . "INSERT") (66 . 1))))

 

 

 

0 Likes
Message 7 of 10

Moshe-A
Mentor
Mentor

@Prashanthr hi,

 

An AutoLISP program some times could be house of cards, you take out the bottom and the whole structure collapses 😀

 

when you want to select other blocks:

does FA-1 is still your main block?

does the attribute tag is the same?

think of more possibilities that you want to implement before i publish the final version.

 

Moshe

 

 

 

0 Likes
Message 8 of 10

Moshe-A
Mentor
Mentor

@Prashanthr ,

 

check this fix

 

you now have to provide the block name to be as replacement 😀

 

enjoy

Moshe

Message 9 of 10

Prashanthr
Enthusiast
Enthusiast

Hello @Moshe-A 

 

Thank you so much for providing the new lisp. Its good to provide the replacement block name. But when using this lisp, one block in the whole selection of replacement is not being replaced. I'm not sure how or why this happens.

0 Likes
Message 10 of 10

Moshe-A
Mentor
Mentor

told you that 😀

 

maybe it has different attribute tag name?!

0 Likes