Copy values from one Attribute block to selected block

Copy values from one Attribute block to selected block

karthur1
Mentor Mentor
1,663 Views
21 Replies
Message 1 of 22

Copy values from one Attribute block to selected block

karthur1
Mentor
Mentor

We have updated our BOMs and now the columns are a different spacing. When we copy the BOM's from an older drawing to this new format, the rows do not line-up correctly. To fix this, we have to copy/paste each value of the attribute block from the old block to the new block.

 

karthur1_0-1721072761617.png

 

 

What I would like to do is run a lisp command, then select the old block, then select the new block and it then copies all the values from the old to the new.  Even if the value in the old block is <blank>, it still is copied.

 

I found this (see attached), but it only copies the one value that is selected an not ALL 5 of the values in the block.  How can I make this copy/paste all the values in my block?

 

Thanks,

Kirk

 

 

0 Likes
Accepted solutions (3)
1,664 Views
21 Replies
Replies (21)
Message 2 of 22

pendean
Community Legend
Community Legend

@karthur1 wrote:

We have updated our BOMs and now the columns are a different spacing. When we copy the BOM's from an older drawing to this new format, the rows do not line-up correctly....


May I ask, why not fix the source of the problem to start with?

Which "BOMs" and which variant of AutoCAD are you using please?

 

While you wait for others to help with your LISP quest of course.

0 Likes
Message 3 of 22

karthur1
Mentor
Mentor

@pendean wrote:


May I ask, why not fix the source of the problem to start with?

Which "BOMs" and which variant of AutoCAD are you using please?

 

While you wait for others to help with your LISP quest of course.


"why not fix the source"... I am trying to standardize on a BOM format. Over the years there have been several different ones created with different width rows.

 

We are using just vanilla AutoCAD.

 

 

0 Likes
Message 4 of 22

paullimapa
Mentor
Mentor

try Att2Att.lsp

 

; Att2Att takes attribute values from source Block and places to matching tags in target Block
; OP:
; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/copy-values-from-one-attribute-block-to-selected-block/m-p/12899135#M468702
(defun C:Att2Att (/ attlst1 attlst2 atttag lst ss1 ss2 tmp)
(vl-load-com)
 (while (not ss1)
  (princ"\nSelect Source Block with Attributes...")
  (setq ss1 (ssget "_+.:E:S" '((0 . "INSERT")(66 . 1))))
 ) ; while
 (while (not ss2)
  (princ"\nSelect Target Block with Attributes...")
  (setq ss2 (ssget "_+.:E:S" '((0 . "INSERT")(66 . 1))))
 ) ; while
 (if (and ss1 ss2)
  (progn
    (setq attlst1 (vlax-invoke (vlax-ename->vla-object (ssname ss1 0)) 'getattributes) ; get source attributes
          attlst2 (vlax-invoke (vlax-ename->vla-object (ssname ss2 0)) 'getattributes) ; get target attributes
    )
    (foreach itm attlst1 ; get from source list of assoc pair of tag and val 
     (setq lst (append lst (list (cons (strcase (vla-get-tagString itm)) (vla-get-textString itm)))))
    ) ; foreach
    (foreach itm attlst2 ; get from target list tag and see if there's match to source tag then place value
     (setq atttag (strcase (vla-get-tagString itm)))
     (if (setq tmp (assoc atttag lst)) ; if matching tag
      (vla-put-textString itm (cdr tmp)) ; put source att value to target
     )  
    ) ; foreach
  ) ; progn
 ) ; if
 (princ) ; clean exit
) ; defun

 

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 5 of 22

karthur1
Mentor
Mentor

After I load this, it gives me this error.

 

karthur1_0-1721077485018.png

 

0 Likes
Message 6 of 22

paullimapa
Mentor
Mentor

paullimapa_0-1721077884903.png

I updated my previous post and also attached lsp in this post


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 7 of 22

Sea-Haven
Mentor
Mentor

Just a question as no dwg to look at is the 2nd block mimicking a table ? If so why not use a table ? Lots of examples about read block attributes and make a table.

0 Likes
Message 8 of 22

karthur1
Mentor
Mentor

Paul,

I updated the code and it runs. When I copy the contents of the first source to the first target block it works great. But then when I select the second source and target, it copies the contents from the first source to the second target.

 

I have included a sample drawing here.  In the BOM, I want to be able copy the contents from say line item 1 to line item 5, then copy the contents of line item 2 to item 6.... etc.  It will be in no particular order, but I will have multiple ones to copy.

 

Thanks.

0 Likes
Message 9 of 22

komondormrex
Mentor
Mentor
Accepted solution

check this one modified

(defun c:copypasteattribattribbytag ( / source_block source_block_object  
										 target_block target_block_object target_attribute_found
 									 )
 	(vl-load-com)
   	(while (setq source_block (car (entsel "\nPick source block bom_num to copy values from - ENTER TO FINISH...")))
		(setq source_block_object (vlax-ename->vla-object source_block)) 
   	 	(setq target_block (car (entsel "\nPick destination block bom_num to paste values to...")))
   	 	(setq target_block_object (vlax-ename->vla-object target_block))
		(mapcar '(lambda (source_attribute)
						 (if (vl-some '(lambda (target_attribute) (= (vla-get-tagstring source_attribute) (vla-get-tagstring (setq target_attribute_found target_attribute))))
									   (vlax-invoke target_block_object 'getattributes)
							 )
							 (vla-put-textstring target_attribute_found (vla-get-textstring source_attribute))
						 )
				 )
				 (vlax-invoke source_block_object 'getattributes)
		)
  	)
  	(princ)
)
0 Likes
Message 10 of 22

karthur1
Mentor
Mentor

@komondormrex wrote:

check this one modified

 

(defun c:copypasteattribattribbytag ( / source_block source_block_object  
										 target_block target_block_object target_attribute_found
 									 )
 	(vl-load-com)
   	(while (setq source_block (car (entsel "\nPick source block bom_num to copy values from - ENTER TO FINISH...")))
		(setq source_block_object (vlax-ename->vla-object source_block)) 
   	 	(setq target_block (car (entsel "\nPick destination block bom_num to paste values to...")))
   	 	(setq target_block_object (vlax-ename->vla-object target_block))
		(mapcar '(lambda (source_attribute)
						 (if (vl-some '(lambda (target_attribute) (= (vla-get-tagstring source_attribute) (vla-get-tagstring (setq target_attribute_found target_attribute))))
									   (vlax-invoke target_block_object 'getattributes)
							 )
							 (vla-put-textstring target_attribute_found (vla-get-textstring source_attribute))
						 )
				 )
				 (vlax-invoke source_block_object 'getattributes)
		)
  	)
  	(princ)
)

 


That works, but it only copies one of the attributes to my destination. In order to get all of the attributes copied for each block, I have to do this 5 times per block. I want to be able to copy the values all attributes from one block to another.

 

 

0 Likes
Message 11 of 22

komondormrex
Mentor
Mentor

surely not, as it was programmed to copy/paste values of ALL similar tag attributes from source block to target block.

or maybe you want something different.

komondormrex_0-1721135711808.gif

 

0 Likes
Message 12 of 22

paullimapa
Mentor
Mentor
Accepted solution

forgot to localize the variable lst.

now it should work...I've updated the lisp in my previous posts changing this line from:

 

(defun C:Att2Att (/ attlst1 attlst2 atttag ss1 ss2 tmp)

 

to adding lst in the code:

(defun C:Att2Att (/ attlst1 attlst2 atttag lst ss1 ss2 tmp)

Now it should use a new lst variable when the lisp runs each time.

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 13 of 22

pbejse
Mentor
Mentor

@karthur1 wrote:

I have included a sample drawing here.  In the BOM, I want to be able copy the contents from say line item 1 to line item 5, then copy the contents of line item 2 to item 6.... etc.  It will be in no particular order,


Are you looking into bumping the values one number up? but it should leave the ITEM (MK#) as is Yes?

 

0 Likes
Message 14 of 22

karthur1
Mentor
Mentor

I am not sure what happened, but I re-copied your lisp and tried it again.  Now it ran perfectly. Does exactly what I need.

 

Thank You !!!

 

 

 

 

0 Likes
Message 15 of 22

karthur1
Mentor
Mentor

@paullimapa wrote:

forgot to localize the variable lst.

now it should work...I've updated the lisp in my previous posts changing this line from:

 

 


Paul,

Yes, this work exactly like I wanted.

 

Thanks for helping with this.

 

 

0 Likes
Message 16 of 22

paullimapa
Mentor
Mentor

glad to have helped...cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 17 of 22

karthur1
Mentor
Mentor

Paul,

I just tried your ATT2ATT today on a different drawing.  Now it doesn't copy the QTY column for some reason.  I have attached here a sample drawing that you can test.

 

Here is a short clip showing the issue also.

 

ATT2ATT Test_1.gif

0 Likes
Message 18 of 22

paullimapa
Mentor
Mentor

Your Block RTAGA QTY. has a period at the end:

paullimapa_0-1721266211494.png

But your Block Bom-Assem QTY does not:

paullimapa_1-1721266249473.png

To correct this I used the Battman command and edited the Block RTAGA's QTY. to QTY

paullimapa_2-1721266659380.png

Now Att2Att.lsp will work since it needs to find the exact matching Attribute Tag name.


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 19 of 22

karthur1
Mentor
Mentor

Paul,

Would it be possible for the lisp to not match the tag names? Could the lisp just copy the first, second, third, (or ever how many) values from the source att block and paste them into the target block? The blocks will have the same number of tags, but they may be named differently.  If it could do that, then it would work on ANY attblock in the drawing.

In the sample drawing, look down near the bottom. I tried to use the ATT2ATT to copy the values of the "Rev-Dsz" block to the "Revision Line" block. Since the tag REV tag is the only one that matches, that's the only one it copies.

 

karthur1_0-1721302297368.png

 

Of course, I could use BATTMAN and edit the names then it works as advertised.  What I am asking may not be possible... just thought I would ask.

 

Thanks for the help,

Kirk

 

 

0 Likes
Message 20 of 22

komondormrex
Mentor
Mentor
Accepted solution

@karthur1 wrote:

Would it be possible for the lisp to not match the tag names?


that one is easier

 

(defun c:copy_paste_atts ( / source_block source_block_object target_block_object)
   	(while (setq source_block (car (entsel "\nPick source block bom_num to copy values from - ENTER TO FINISH...")))
		(setq source_block_object (vlax-ename->vla-object source_block)) 
   	 	(setq target_block_object (vlax-ename->vla-object (car (entsel "\nPick destination block bom_num to paste values to..."))))
		(mapcar '(lambda (source_attribute target_attribute)
					(vla-put-textstring target_attribute (vla-get-textstring source_attribute))
				 )
				 (vlax-invoke source_block_object 'getattributes)
				 (vlax-invoke target_block_object 'getattributes)
		)
  	)
  	(princ)
)