Block A Copy attrbiutes to all Instance of Block B

Block A Copy attrbiutes to all Instance of Block B

Anonymous
Not applicable
1,058 Views
7 Replies
Message 1 of 8

Block A Copy attrbiutes to all Instance of Block B

Anonymous
Not applicable

Hi,

 

I have a block called "Master_Block" that users at my company will place on the modelspace in AutoCAD. It contains multiple atttributes which they will populate. Our drawings have multiple layouts within one file. Another block (known as the "Legacy_Block") will then be placed onto each and every layout. Finally, I need a LISP script to copy all the attribute contents from The Master_Block to every instance of the Legacy Block.

 

I have a script which can copy attribute from entsel block A to entsel Block B. My plan is to try and adapt it. 

1. User selects (entsel) the Master block. (This bit already works)

2. SSGET (perhaps?) creates a list of entity names of all blocks in the document (all layouts) with effective name "Legacy_Block".

3. For each item in that list copy attributes over (using the script I already have).

 

I now have 2 entire days of AutoLISP experience so I'm still pretty terrible at this, struggling to find into on how to do the SSGET bit with effective name as the input and ename(s) as the output. Following that I'm not yet sure what I'm doing with the loop either. Any guidance anyone can offer would be greatly appreciated! 

 

Thanks, Dan

0 Likes
1,059 Views
7 Replies
Replies (7)
Message 2 of 8

ВeekeeCZ
Consultant
Consultant

Are those blocks dynamic that you want to use effective names?

Do attribute tags match names (blk A vs blks B)? 

You should have posted a sample. It would be easier to help.

0 Likes
Message 3 of 8

Anonymous
Not applicable

Hi,

 

These are just normal blocks with attributes. The attribute names match between master_block and legacy_block.

 

For IP reasons, I can't provide the block data, but I can highlightwhat I'm trying to do with the code:

 

(defun C:MTB (/)
;SELECT MASTER BLOCK (THIS BIT WORKS)
  (setq baselist (list))      
  (setq ename (car (entsel "\nSelect Base Title Block:")))
  (while (= ename nil)
     (princ "\nNothing Picked")
     (setq ename (car (entsel "\nSelect Base Title Block:")))
  );end while

; SCRIPT SEARCHES FOR ALL INSTANCES OF EFFECTIVE NAME 'LEGACY_BLOCK' ->
; STORES ENTITY NAMES IN A VARIABLE

;FOR EACH ENTITY NAME IN THE VARIABLE... (
;PUT ENTITY NAME IN TO VARIABLE ename1 AND THE REST OF THIS SCRIPT SHOULD WORK

;THE REST OF THIS DOES THE ATTRIBUTE COPYING
  (setq ename (entnext ename))
  (setq elist (entget ename))   ;the entity list of the base border
  (setq etype (cdr (assoc 0 elist)))   ;should be attrib
  (while (= etype "ATTRIB")      ;puts all the attribute in a list
     (setq tag (cdr (assoc 2 elist)))      ;the attribute tag
     (setq val (cdr (assoc 1 elist)));the attribute value
     (setq baselist (append (list (list tag val)) baselist));put the attribute in list
     (setq ename (entnext ename))         ;move onto the next attribute
     (setq elist (entget ename))
     (setq etype (cdr (assoc 0 elist)))
  );end while
  (setq ename1 (entnext ename1))            ;get the next entity, should be "ATTRIB"
  (setq elist1 (entget ename1))            ;the entity list of the border
  (setq etype1 (cdr (assoc 0 elist1)))         ;should be attrib
  (while (= etype1 "ATTRIB")
     (setq attval nil)
     (setq tag (cdr (assoc 2 elist1)));the attribute tag
     (foreach item baselist
        (if (= tag (nth 0 item))
           (progn   
              (setq attval (nth 1 item))
           );end then
           (progn);else do nothing go to next in list till tag matches
        );end if
     );end foreach
     (if (/= attval nil)
        (progn   (setq elist1 (subst (cons 1 attval) (assoc 1 elist1) elist1))
           (entmod elist1));end then
        (progn);end else
     );end if
     (setq ename1 (entnext ename1))   ;move onto the next attribute
     (setq elist1 (entget ename1))
     (setq etype1 (cdr (assoc 0 elist1)))
  );end while

; END FOR
  (command "REGEN")
);end defun
(princ) 

 

It's just that middle bit that I'm stuck with. 

Message 4 of 8

ВeekeeCZ
Consultant
Consultant

So I guess all the tag names are known, right?

So, here is something very simple...

Don't forget to localize all vars, especially lst !

Untested.

 

(setq tgs '("tag1" "tag2" "tag3"))

(if (and (setq sm '((0 . "INSERT") (2 . "master_block")))
	 (setq em (ssname sm 0))
	 (setq ss (ssget "_X" '((0 . "INSERT") (2 . "legacy_bloc"))))
	 )
  (progn
    (foreach tag tgs
      (if (setq val (getpropertyvalue em tag))
	(setq lst (cons (cons tag val) lst))))
    (repeat (setq i (sslength ss))
      (setq en (ssname ss (setq i (1- i))))
      (foreach tag tgs
	(setpropertyvalue en tag (cdr (assoc tag lst)))))))

 

Message 5 of 8

pbejse
Mentor
Mentor

@Anonymous wrote:

These are just normal blocks with attributes. The attribute names match between master_block and legacy_block.



Is there only 1 Master block?

(setq Master (ssget "X" '((0 . "INSERT")(66 . 1)(2 . "MasterBLock")(410 . "Model"))))

Muliple "Legacy blocks" on layout tabs

(setq LegacyBlocks (ssget "X" '((0 . "INSERT")(66 . 1)(2 . "LegacyBlock")(410 . "~Model"))))

 
This whole bit should be a subfunction if you are going to user this more than once

(Defun _subToGetAttribValue (en / elist etype tag val baselist)
  (setq en (entnext en))
  (setq elist (entget en))		;the entity list of the base border
  (setq etype (cdr (assoc 0 elist)))	;should be attrib
  (while (= etype "ATTRIB")		;puts all the attribute in a list
    (setq tag (cdr (assoc 2 elist)))	;the attribute tag
    (setq val (cdr (assoc 1 elist)))	;the attribute value
    (setq baselist (append (list (list tag val)) baselist))
					;put the attribute in list
    (setq en (entnext en))		;move onto the next attribute
    (setq elist (entget en))
    (setq etype (cdr (assoc 0 elist)))
  )					;end while
  baselist
)

Usage:

(setq dataFromMasterBlock ( _subToGetAttribValue (ssname Master 0)))

Process the selection

(repeat	(sslength LegacyBlocks)
  (setq itemFromSelection (ssname LegacyBlocks 0))
  
    (princ "Do your thing")
  
  (ssdel itemFromSelection LegacyBlocks)
)

Not you need to put Humpty Dumpty back together again

 


@Anonymous wrote:

Hi,

I now have 2 entire days of AutoLISP experience so I'm still pretty terrible at this..

Now that is impressive considering for 2 days to put this all together

😊

 

HTH

 

 

0 Likes
Message 6 of 8

Anonymous
Not applicable

Hi, 

 

Thanks for those last two replies, I thinkbetween the two of those I should be able to 'put humpty dumpty back together again'. Just as a disclaimer I didn't write the script that does the attribute copying, somebody sent me that one. I have former programming experience although LSP seems pretty unique!.

 

Thanks for your help. I'll have a go and if I'm really stuck I'll come back.

0 Likes
Message 7 of 8

pbejse
Mentor
Mentor

@Anonymous wrote:

Thanks for those last two replies, I thinkbetween the two of those I should be able to 'put humpty dumpty back together again'.

..Thanks for your help. I'll have a go and if I'm really stuck I'll come back...


Go for it. We'll be here waiting

 

 th.jpg

 

 

 

0 Likes
Message 8 of 8

Sea-Haven
Mentor
Mentor

If both blocks have the same attribute order it can be done even simpler as you don't need to worry about tag names, but I do emphasise same order. Also should be a check for block1 has x attributes block2 has y attribute /= x y a problem.

0 Likes