Mutileader block attribute

Mutileader block attribute

H_franco
Participant Participant
2,188 Views
9 Replies
Message 1 of 10

Mutileader block attribute

H_franco
Participant
Participant

I have the following lisp routine that edit attribute values inside a multileader, however when I attached a block with more than one attribute the values is the same for all attribute definitions. I truly want just to change the value of ONE attribute definition and not the rest. Can anyone help me?  

(defun c:emdl ( / idx sel str ) (setq str (getstring t "\nSpecify new attribute value: ")) (if (setq sel (ssget "_:L" '((0 . "MULTILEADER")))) (repeat (setq idx (sslength sel)) (LM:setmleaderblockattributevalues (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))) str) ) ) (princ) )

0 Likes
Accepted solutions (1)
2,189 Views
9 Replies
Replies (9)
Message 2 of 10

devitg
Advisor
Advisor

@H_franco  Please upload your sample.dwg

0 Likes
Message 3 of 10

H_franco
Participant
Participant

@devitg  I have uploaded the file. When i run the lisp i get the result on the left multileader. I want to edit just the number and the remain attribute will remain the same or vice versa. I would like to have a dialog box or a option meme to select which attribute i want to change when i select the all of the multileaders. 

0 Likes
Message 4 of 10

devitg
Advisor
Advisor

@H_franco  please add the 

 

LM:SETMLEADERBLOCKATTRIBUTEVALUES
0 Likes
Message 5 of 10

Sea-Haven
Mentor
Mentor

Agree with Devitg need the code for LM:setmleader…….

 

Looking at http://www.lee-mac.com/attributefunctions.html there are plenty of functions to do what you want, there are also ways of getting tag name via Nentsel so can pick attribute to change across multiple.

0 Likes
Message 6 of 10

pbejse
Mentor
Mentor

@H_franco wrote:

I have the following lisp routine that edit attribute values inside a multileader, however when I attached a block with more than one attribute the values is the same for all attribute definitions. I truly want just to change the value of ONE attribute definition and not the rest. Can anyone help me?  


In cases like that, what you need is routine that targets a specfic TAG name or otherwise use the first attribute definition, but in your block, the target is not even the first one, which means you need to specify the TAG name. Also there are issues not using a standard naming with a blocks and etc.  


To make a routine truly universal, you have to take into account every possble scenario. 

 

3 ways you can do this.

1 Hard code the TAG name in the code

2. Prompt for a tag name to find. <---- that is if user happen to know the tag name.

3. Select the target attribute as reference before selecting the blocks to be processed. but then again there are blocks using same TAG names in a single block (crazy isnt it? ) [ and also too much work ]

 

We will stick Option 1 for now

(defun c:Demo (/ _MLAttValue BlockColl ss i e f)
  (vl-load-com)
;;; pBe 22May2013 ;;;
  ;; Demo for Mtext Block Attribute ;;;
  (defun _MLAttValue (en et tag coll m / n i attag)
    (setq n -1
	  i (1- (vla-get-count et))
    )
    (while (and (null attag) (< n i))
      (if
	(And
	  (eq "AcDbAttributeDefinition"
	      (vla-get-ObjectName (setq x (vla-item et (setq n (1+ n)))))
	  )
	  (eq tag (vla-get-TagString x))
          (setq attag (vla-getBlockAttributeValue en (setq ID (vla-get-ObjectID x))))
	)
	 (if m (vla-SetBlockAttributeValue en ID m) attag)
	 )
      )
     
  )
  (setq	BlockColl
	 (vla-get-blocks
	   (vla-get-ActiveDocument (vlax-get-acad-object)))
         blocklist '("TAG-HEX-TXT3" "_TagBox");<  Add as may block names
         TAG "XX" ;<-- hard coded tag name
	 )
  (if (and  (setq str (getstring t "\nSpecify new attribute value: "))
            (setq ss (ssget "_:L" '((0 . "MULTILEADER"))))
            )
    (repeat (setq i (sslength ss))
      (setq e (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
          
      (if (setq matrb (member (vla-get-ContentBlockName e) blocklist))
	   (_mlattvalue
		      e
		      (vla-item BlockColl (car matrb))
		      TAG
		      BlockColl str
		    )
	    )
      )
    )
  (princ)
)

 

 

 

0 Likes
Message 7 of 10

Sea-Haven
Mentor
Mentor

You forgot 4

 

You can change an attribute knowing the order of the attributes when looping through attributes if = x  y then update attribute. All att tags can be same.

 

Like you said though re-order the block and version 4 does not work now.

0 Likes
Message 8 of 10

pbejse
Mentor
Mentor

@Sea-Haven wrote:

You forgot 4

 

You can change an attribute knowing the order of the attributes when looping through attributes if = x  y then update attribute. All att tags can be same.

 

Like you said though re-order the block and version 4 does not work now.


 

True, that is another option, need to get back on that, I almost had it. its a mix between lisp and .NET. I got the order and dynamic property figured out, but when i inserted the block, the default values are swapped, minor thing ( i think )

 

I'll keep you posted.

 

 

 

 

 

0 Likes
Message 9 of 10

H_franco
Participant
Participant

I updated the lisp based on the comments. If i stay with option 3 i will have to keep my tags names short hahahaha. but I have modified this lisp multiple times already and i remember having an small dialog to identified which tag i want to update but i dont remember save it that version, I know that included tag names for sure.  

 

(defun c:emdl ( / idx sel str )
    (setq str (getstring t "\nSpecify new attribute value: "))
    (if (setq sel (ssget "_:L" '((0 . "MULTILEADER"))))
        (repeat (setq idx (sslength sel))
            (LM:setmleaderblockattributevalues (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))) str)
        )
    )    
    (princ)
)

;; Set MLeader Block Attribute Values  -  Lee Mac
;; mld - [vla] MLeader object with attributed block content
;; val - [str] New attribute value

(defun LM:setmleaderblockattributevalues ( mld val / oid )
   (if (= acblockcontent (vla-get-contenttype mld))
        (vlax-for obj
            (vla-item
                (vla-get-blocks (vla-get-document mld))
                (vla-get-contentblockname mld)
            )
            (if (and (= "AcDbAttributeDefinition" (vla-get-objectname obj))
                     (= :vlax-false (vla-get-constant obj))
                )
                (progn
                    (if (vlax-property-available-p obj 'objectid32)
                        (setq oid (vla-get-objectid32 obj))
                        (setq oid (vla-get-objectid   obj))
                    )
                    (if (vlax-method-applicable-p mld 'setblockattributevalue32)
                        (vla-setblockattributevalue32 mld oid val)
                        (vla-setblockattributevalue   mld oid val)
                    )
                )
            )
        )
    )
)

(vl-load-com) (princ)

 

0 Likes
Message 10 of 10

pbejse
Mentor
Mentor
Accepted solution

 


@H_franco wrote:

I updated the lisp based on the comments. If i stay with option 3 i will have to keep my tags names short hahahaha. but I have modified this lisp multiple times already and i remember having an small dialog to identified which tag i want to update but i dont remember save it that version, I know that included tag names for sure.  


 

If you want option 3 we can do that.BUT i will not edit "LM:setmleaderblockattributevalues" routine. 

We will need one  from LeeMac's collection LM:List Box  

 

 

 

(defun c:pbedml (/ _MLAttValue _HowMayTagsBuddy BlockColl str tag ss i e nm f blocklist)
  (vl-load-com)
;;; 	pBe 22May2019 |  Demo for Mtext Block Attribute 	;;;
  
(defun _HowMayTagsBuddy	(nm / tags sel)
  (Vlax-for itm	(Vla-item BlockColl nm)
    (if	(eq (vla-get-ObjectName itm) "AcDbAttributeDefinition")
      (setq tags (cons (vla-get-TagString itm) tags))
    ) 
  )
  (if (and tags
	    (or (and (= (length tags) 1) (setq sel tags))	 
	 	(setq sel (LM:listbox "Select TAG to modfiy" tags 0)))
	 	)
    	(list  nm (car sel)))	   
  ) 

  (defun _MLAttValue (en et tag coll m / n i attag)
    (setq n -1 i (1- (vla-get-count et)))
    (while (and (null attag) (< n i))
      (if
	(And
	  (eq "AcDbAttributeDefinition"
	      (vla-get-ObjectName (setq x (vla-item et (setq n (1+ n)))))
	  )
	  (eq tag (vla-get-TagString x))
          (setq attag (vla-getBlockAttributeValue en (setq ID (vla-get-ObjectID x))))
	)
	 (if m (vla-SetBlockAttributeValue en ID m) attag)
	 )
      )     
  )
  
(setq	BlockColl  (vla-get-blocks
   (vla-get-ActiveDocument (vlax-get-acad-object)))
 )
  (if (and  (setq str (getstring t "\nSpecify new attribute value: "))
            (setq ss (ssget "_:L" '((0 . "MULTILEADER"))))
            )

    (repeat (setq i (sslength ss))
      (setq e (vlax-ename->vla-object (ssname ss (setq i (1- i))))
            nm (vla-get-ContentBlockName e))
      
      (if (setq TAG
	      (if (setq f (assoc nm blocklist))
			(cadr f)
		 		(cadar (setq blocklist (cons
						  (_HowMayTagsBuddy nm) blocklist)))
			)
		)
	   (_mlattvalue e (vla-item BlockColl nm)
		      TAG BlockColl str
		    )
	    )
      )
    )
  (princ)
)

 

 

 

The way it works is:

  • It would ask the user to select the target tag name only there are more than one attribute on the contentBlockname. otherwise it will modify the single attribute.
  • IT will only ask the user once per block name while processing the selected MleaderStyle
  • Deposit the payment to  112 66 101 58 85 83 36 32 79 78 76 89 32 80 76 69 65 83 69 for stagerring amount of

1 million.jpg

 

HTH