Routine to select a block and change the justification of all attributes

Routine to select a block and change the justification of all attributes

Anonymous
Not applicable
3,970 Views
19 Replies
Message 1 of 20

Routine to select a block and change the justification of all attributes

Anonymous
Not applicable

Is it possible to create a routine that allows me to select a block containing a number of attributes, and tell it to change the justification of those attributes? And possible the rotation angle of all of them at once?

0 Likes
Accepted solutions (1)
3,971 Views
19 Replies
Replies (19)
Message 2 of 20

cadffm
Consultant
Consultant
Yes, it is possible.

Sebastian

0 Likes
Message 3 of 20

john.uhden
Mentor
Mentor

Yes, that is possible.

Using ActiveX is probably the easiest, using functions such as (vla-getattributes) and (vlax-put  <attobj> <property> <value>)

John F. Uhden

0 Likes
Message 4 of 20

DannyNL
Advisor
Advisor

As you can read above, yes it is possible.

 

But it will only be needed if you want to change all the attributes in a block at once. If you only want to change one or some of them, you already can do that with the standard Enhanced Attirbute Editor (EATTEDIT).

0 Likes
Message 5 of 20

john.uhden
Mentor
Mentor

Well. he could filter for tag strings using wcmatch.

John F. Uhden

0 Likes
Message 6 of 20

DannyNL
Advisor
Advisor

Yes, of course that is possible. It's also possible to just pick the attributes without using the block at all.

But it all depends on the use case.

0 Likes
Message 7 of 20

Anonymous
Not applicable

Yes I want to change all the attributes at once.

Basically what I have is a block symbol of a "valve" on a flow diagram.  The block has four attributes attached to it that the user fills in after the block is inserted.  I currently have all the attributes set to "MIDDLE" justified.  However, a lot of the time the user needs the attributes to be either "LEFT" or "RIGHT" justified, depending on how the attribute text can end up interfering with other objects.  I would like a routine that allows them to select the block, and change the justification of those four attributes to either "LEFT" or "RIGHT".  Do you think the way I'm asking to do it is the best way?  Thanks for your help!

0 Likes
Message 8 of 20

DannyNL
Advisor
Advisor
Accepted solution

Ok, see code below

 

(defun c:Test (/ T_Object T_NewAlignment T_AlignmentPoint)
   (if
      (and
         (setq T_Object (car (entsel "\nSelect block: ")))
         (= (vla-get-ObjectName (setq T_Object (vlax-ename->vla-object T_Object))) "AcDbBlockReference")
         (= (vla-get-HasAttributes T_Object) :vlax-true)
      )
      (progn
         (initget 6 "Left Center Right Middle BL BC BR ML MC MR TL TC TR")
         (if
            (setq T_NewAlignment (getkword "\nVertical Alignment [Left/Center/Right/Middle/BL/BC/BR/ML/MC/MR/TL/TC/TR/]: "))
            (progn
               (mapcar
                  '(lambda (T_Check T_Value) (if (= T_NewAlignment T_Check)(setq T_NewAlignment (eval T_Value))))
                  '("Left" "Center" "Right" "Middle" "BL" "BC" "BR" "ML" "MC" "MR" "TL" "TC" "TR")
                  '(acAlignmentLeft acAlignmentCenter acAlignmentRight acAlignmentMiddle acAlignmentBottomLeft acAlignmentBottomCenter acAlignmentBottomRight acAlignmentMiddleLeft acAlignmentMiddleCenter acAlignmentMiddleRight acAlignmentTopLeft acAlignmentTopCenter acAlignmentTopRight)
               )
               (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
               (foreach T_Attribute (vlax-safearray->list (vlax-variant-value (vla-GetAttributes T_Object)))
                  (setq T_AlignmentPoint
                     (if
                        (= (vla-get-Alignment T_Attribute) 0)
                        (vla-get-InsertionPoint     T_Attribute)
                        (vla-get-TextAlignmentPoint T_Attribute)
                     )
                  )                     
                  (vla-put-Alignment T_Attribute T_NewAlignment)
                  (if
                     (= T_NewAlignment 0)
                     (vla-put-InsertionPoint     T_Attribute T_AlignmentPoint)
                     (vla-put-TextAlignmentPoint T_Attribute T_AlignmentPoint)
                  )                  
               )
               (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
            )
         )            
      )
   )
   (princ)
)
0 Likes
Message 9 of 20

roland.r71
Collaborator
Collaborator

@Anonymous wrote:

Yes I want to change all the attributes at once.

Basically what I have is a block symbol of a "valve" on a flow diagram.  The block has four attributes attached to it that the user fills in after the block is inserted.  I currently have all the attributes set to "MIDDLE" justified.  However, a lot of the time the user needs the attributes to be either "LEFT" or "RIGHT" justified, depending on how the attribute text can end up interfering with other objects.  I would like a routine that allows them to select the block, and change the justification of those four attributes to either "LEFT" or "RIGHT".  Do you think the way I'm asking to do it is the best way?  Thanks for your help!


Yes. It is the best way for the situation as described.

However: If you created the block too, you might wanna check into dynamic blocks, as you could create a block to have this choice incorporated. This would circumvent the need for a separate lisp routine to change the justification.

0 Likes
Message 10 of 20

DannyNL
Advisor
Advisor

I think that not locking the position of the attributes in a block is even a better solution.

No LISP routine or dynamic block needed. In case one or more attribute values might intersect other objects, just select the attribute grip and position it on the location you want.

0 Likes
Message 11 of 20

roland.r71
Collaborator
Collaborator

@DannyNL wrote:

I think that not locking the position of the attributes in a block is even a better solution.

No LISP routine or dynamic block needed. In case one or more attribute values might intersect other objects, just select the attribute grip and position it on the location you want.


This could (still) turn out to be time consuming. The more blocks & attributes, the worse it gets.

Perfect method for adjusting 1 or 2 attributes. Not for a drawing full with blocks, with multiple attributes each (to modify). Where a routine or dynamic block would only require 1 click a block, or it (a lisp routine) could be made to work on a complete selection set.

0 Likes
Message 12 of 20

DannyNL
Advisor
Advisor

I agree if you have a lot of blocks, but on the other hand if you need to modify most of the (attributes of) inserted blocks after inserting than something is off. A good block design is therefore also an important issue, which can save a lot of time afterwards. Preventing is a better way than solving.

0 Likes
Message 13 of 20

Anonymous
Not applicable

I have left the attributes not locked, so the users can move them around if needed.  It's been effective, since the need to move them can be very different.  However, most of the time they simply want to change the justification for all four attributes globally.  It's a case of the users being greedy and wanting to "hit a button" to do everything for them.  Lazy. So I'm trying to make it as painless as flexible as possible, within reason.

0 Likes
Message 14 of 20

Anonymous
Not applicable

Thanks!  This is awesome!  I'll give it a go and see what happens.......

0 Likes
Message 15 of 20

roland.r71
Collaborator
Collaborator

Lazy people are best at automation 😛

0 Likes
Message 16 of 20

Anonymous
Not applicable

This works perfectly!  Wow!  Thank you for your time on this.  It's greatly appreciated and problem completely solved!

 

Doug

0 Likes
Message 17 of 20

DannyNL
Advisor
Advisor

You're welcome & glad I could help Smiley Happy

 

BTW, I totally forgot about the rotation and I was in a good mood.

So see code modified code below that let's you select multiple blocks at once and ask if you want to modify the alignment or rotation of the attributes.

 

(defun c:Test (/ T_Selection T_Choice T_NewAlignment T_NewRotation T_AlignmentPoint)
   (if
      (setq T_Selection (ssget '((0 . "INSERT")(66 . 1))))               
      (progn
         (initget 6 "Alignment Rotation")
         (setq T_Choice (getkword "Change attribute [Alignment/Rotation]: "))
         (cond
            (
               (= T_Choice "Alignment")
               (initget 6 "Left Center Right Middle BL BC BR ML MC MR TL TC TR")
               (if
                  (setq T_NewAlignment (getkword "\nVertical Alignment [Left/Center/Right/Middle/BL/BC/BR/ML/MC/MR/TL/TC/TR/]: "))
                  (progn
                     (mapcar
                        '(lambda (T_Check T_Value) (if (= T_NewAlignment T_Check)(setq T_NewAlignment (eval T_Value))))
                        '("Left" "Center" "Right" "Middle" "BL" "BC" "BR" "ML" "MC" "MR" "TL" "TC" "TR")
                        '(acAlignmentLeft acAlignmentCenter acAlignmentRight acAlignmentMiddle acAlignmentBottomLeft acAlignmentBottomCenter acAlignmentBottomRight acAlignmentMiddleLeft acAlignmentMiddleCenter acAlignmentMiddleRight acAlignmentTopLeft acAlignmentTopCenter acAlignmentTopRight)
                     )
                  )
               )
            )
            (
                (= T_Choice "Rotation")                
                (setq T_NewRotation (getangle "\nNew attribute rotation: "))
            )
         )
         (if
            (vl-remove-if 'not (list T_NewAlignment T_NewRotation))
            (progn
               (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
               (foreach T_Object (vl-remove-if '(lambda (T_Item) (listp (cadr T_Item))) (ssnamex T_Selection))
                  (foreach T_Attribute (vlax-safearray->list (vlax-variant-value (vla-GetAttributes (vlax-ename->vla-object (cadr T_Object)))))
                     (cond
                        (
                           T_NewAlignment
                           (setq T_AlignmentPoint
                              (if
                                 (= (vla-get-Alignment T_Attribute) 0)
                                 (vla-get-InsertionPoint     T_Attribute)
                                 (vla-get-TextAlignmentPoint T_Attribute)
                              )
                           )                     
                           (vla-put-Alignment T_Attribute T_NewAlignment)
                           (if
                              (= T_NewAlignment 0)
                              (vla-put-InsertionPoint     T_Attribute T_AlignmentPoint)
                              (vla-put-TextAlignmentPoint T_Attribute T_AlignmentPoint)
                           )                  
                        )
                        (
                           T_NewRotation
                           (vla-put-Rotation T_Attribute T_NewRotation)
                        )
                        (
                           T
                           nil
                        )
                     )
                  )
               )
               (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
            )
         )                     
      )
   )
   (princ)
)
0 Likes
Message 18 of 20

jrreid
Advocate
Advocate

Just found this and saved as BLKJUST.lsp and works great!

Never thought about this for many years until now!

Thanks, JRR.

0 Likes
Message 19 of 20

timothy_crouse
Collaborator
Collaborator

When I use this lisp it does align the attributes as specified but it also shifts them.

 

Eg if I select a dynamic block that has MC justified attributes and specify ML, it seems to justify them as ML but shifts them to the right a bit.

 

See attached to experiment with.

 

Best Regards

-Tim C.

 

 

0 Likes
Message 20 of 20

john.uhden
Mentor
Mentor

I most often get the same unwanted results when trying to change the alignment of text and mtext... they shift.  It annoys the crepe out of me but I have never researched it (trial and error) to learn what to do to compensate.

John F. Uhden

0 Likes