Author Topic: Edit multiple attributes in a single block all with the same tag name.  (Read 9343 times)

0 Members and 1 Guest are viewing this topic.

Reu

  • Guest
I have a block that has 17 attributes with the same tag. Nevermind why it is that way. My problem is I need a routine that can update all of the attributes at the same time by typing the desired text only once. I have tried to write my own but alas my experience is too little.  I need this to work for only the selected block because this block is inserted into the drawing multiple times. I have attached the block in question. Help anyone?

Thanks in advance,
    Reuben Shilling

ronjonp

  • Needs a day job
  • Posts: 7531
Why not redefine the block with only one attribute ? Nevemind ... I see that it's creating text with halo effect.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Reu

  • Guest
Why not redefine the block with only one attribute ? Nevemind ... I see that it's creating text with halo effect.

For the record it was not my idea.

ronjonp

  • Needs a day job
  • Posts: 7531
You can use this to fill in all the attributes with one string:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ e i ss str)
  2.   (if (and (setq ss (ssget '((0 . "insert") (66 . 1))))
  3.            (setq str (getstring "\nEnter string: " t))
  4.            (setq i -1)
  5.       )
  6.     (while (setq e (ssname ss (setq i (1+ i))))
  7.       (foreach att (vlax-invoke (vlax-ename->vla-object e) 'getattributes)
  8.         (vla-put-textstring att str)
  9.       )
  10.     )
  11.   )
  12.   (princ)
  13. )

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Reu

  • Guest
You can use this to fill in all the attributes with one string:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ e i ss str)
  2.   (if (and (setq ss (ssget '((0 . "insert") (66 . 1))))
  3.            (setq str (getstring "\nEnter string: " t))
  4.            (setq i -1)
  5.       )
  6.     (while (setq e (ssname ss (setq i (1+ i))))
  7.       (foreach att (vlax-invoke (vlax-ename->vla-object e) 'getattributes)
  8.         (vla-put-textstring att str)
  9.       )
  10.     )
  11.   )
  12.   (princ)
  13. )

Perfect!
Thanks ronjonp!

ronjonp

  • Needs a day job
  • Posts: 7531
Glad to help  8-)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Reu

  • Guest
Glad to help  8-)

A couple of questions if you don't mind:

1) How did you know that "66 . 1" is the associated code with the "insert" entity for it's attribute definition?

2) How hard would it be to modify this to select only blocks whose attribute definitions all have the same tag?

Thanks,
     Reuben Shilling

Lee Mac

  • Seagull
  • Posts: 12923
  • London, England
1) How did you know that "66 . 1" is the associated code with the "insert" entity for it's attribute definition?

See DXF Group 66 of the INSERT DXF Reference.

2) How hard would it be to modify this to select only blocks whose attribute definitions all have the same tag?

Try this:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:attdupes ( / def inc lst sel str )
  2.     (while (setq def (tblnext "BLOCK" (null def)))
  3.         (if
  4.             (and (= 2 (logand 2 (cdr (assoc 70 def))))
  5.                 (
  6.                     (lambda ( ent / lst )
  7.                         (while (setq ent (entnext ent))
  8.                             (if (= "ATTDEF" (cdr (assoc 0 (entget ent))))
  9.                                 (setq lst (cons (strcase (cdr (assoc 2 (entget ent)))) lst))
  10.                             )
  11.                         )
  12.                         (and (cdr lst) (apply '= lst))
  13.                     )
  14.                     (tblobjname "BLOCK" (cdr (assoc 2 def)))
  15.                 )
  16.             )
  17.             (setq lst (vl-list* "," (cdr (assoc 2 def)) lst))
  18.         )
  19.     )
  20.     (if (and lst (setq sel (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 (apply 'strcat (cdr lst)))))))
  21.         (progn
  22.             (setq str (getstring t "\nAttribute value: "))
  23.             (repeat (setq inc (sslength sel))
  24.                 (foreach att (vlax-invoke (vlax-ename->vla-object (ssname sel (setq inc (1- inc)))) 'getattributes)
  25.                     (vla-put-textstring att str)
  26.                 )
  27.             )
  28.         )
  29.         (princ "\nNo blocks found with identical attribute tags.")
  30.     )
  31.     (princ)
  32. )

Reu

  • Guest
1) How did you know that "66 . 1" is the associated code with the "insert" entity for it's attribute definition?

See DXF Group 66 of the INSERT DXF Reference.

2) How hard would it be to modify this to select only blocks whose attribute definitions all have the same tag?



Ok i feel really dumb, i was looking for "block" . . . it is "insert" ! Oh boy.

ronjonp

  • Needs a day job
  • Posts: 7531
Glad to help  8-)

...

2) How hard would it be to modify this to select only blocks whose attribute definitions all have the same tag?

Thanks,
     Reuben Shilling

This will only update blocks that have attributes that are all named the same.

Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ atts e i ss str)
  2.   (if (and (setq ss (ssget '((0 . "insert") (66 . 1))))
  3.            (setq str (getstring "\nEnter string: " t))
  4.            (setq i -1)
  5.       )
  6.     (while (setq e (ssname ss (setq i (1+ i))))
  7.       (if (and (setq atts (vlax-invoke (vlax-ename->vla-object e) 'getattributes))
  8.                (cdr atts)
  9.                (apply '= (mapcar 'vla-get-tagstring atts))
  10.           )
  11.         (foreach att atts (vla-put-textstring att str))
  12.       )
  13.     )
  14.   )
  15.   (princ)
  16. )
« Last Edit: March 19, 2013, 03:04:08 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Reu

  • Guest
Re: Edit multiple attributes in a single block all with the same tag name.
« Reply #10 on: March 19, 2013, 09:37:15 AM »
1) How did you know that "66 . 1" is the associated code with the "insert" entity for it's attribute definition?

See DXF Group 66 of the INSERT DXF Reference.

2) How hard would it be to modify this to select only blocks whose attribute definitions all have the same tag?

Try this:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:attdupes ( / def inc lst sel str )
  2.     (if (and lst (setq sel (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 (apply 'strcat (cdr lst)))))))
  3.         (progn
  4.             (setq str (getstring t "\nAttribute value: "))
  5.             (repeat (setq inc (sslength sel))
  6.                 (foreach att (vlax-invoke (vlax-ename->vla-object (ssname sel (setq inc (1- inc)))) 'getattributes)
  7.                     (vla-put-textstring att str)
  8.                 )
  9.             )
  10.         )
  11.         (princ "\nNo blocks found with identical attribute tags.")
  12.     )
  13.     (princ)
  14. )

Looks like this is what I was looking for. The whole code works great if you want to update every block in the drawing that has identical attributes to the same string. However as modified below you can edit individual blocks one at a time without changing them all to the same string.

Code - Auto/Visual Lisp: [Select]
  1. (defun c:ty ()
  2.   (if ;_the following returns a non-nil value
  3.     (and lst ;_all of the following conditions are met
  4.          (setq sel (ssget "_:S" ;_set the variable "sel" to the selection set picked by the user, allowing only a single object to be selected.
  5.                           (list ;_create a list of the following . . .
  6.                             '(66 . 1)
  7.                             '(0 . "INSERT")
  8.                             (cons 2 ;_construct a dotted pair associated with the number 2
  9.                                   (apply 'strcat ;_apply the function "strcat" to the following . . .
  10.                                          (cdr lst) ;_all but the first element of the list "lst"
  11.                                   ) ;_end apply
  12.                             ) ;_end cons
  13.                           ) ;_end list
  14.                    ) ;_end ssget
  15.          ) ;_end setq
  16.     ) ;_end and
  17.      (progn ;_Do the following. . .
  18.        (setq str (getstring t "\nEnter replacement text string: ")) ;_set the variable "str" to the user specified string
  19.        (repeat ;_repeat the following . . .
  20.          (setq inc (sslength sel)) ;_the same number of times as the length of the selection set "sel" (since only a single selection is allowed this will be 1)
  21.           (foreach att ;_step through the following expression
  22.                        (vlax-invoke
  23.                          (vlax-ename->vla-object
  24.                            (ssname sel (setq inc (1- inc)))
  25.                          ) ;_end vlax-ename->vla-object
  26.                          'getattributes
  27.                        ) ;_end vlax-invoke
  28.             (vla-put-textstring att str) ;_modify the attributes with the new string
  29.           ) ;_end foreach
  30.        ) ;_end repeat
  31.      ) ;_end progn
  32.      (alert ;_else print the following message in the alert format
  33.        "\nThe block you selected cannot be edited with this command!"
  34.      )
  35.   ) ;_end if
  36.   (princ)
  37. ) ;_end defun
  38. (princ "\nType TY to edit 'halo' text.")

I do wonder why this will not work when I set the variables to local instead of global.
« Last Edit: March 19, 2013, 09:53:02 AM by Reu »

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Edit multiple attributes in a single block all with the same tag name.
« Reply #11 on: March 19, 2013, 09:43:22 AM »
It's because 'lst' in your AND statement is nil if you localiz(s)e your variables.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Reu

  • Guest
Re: Edit multiple attributes in a single block all with the same tag name.
« Reply #12 on: March 19, 2013, 09:51:18 AM »
It's because 'lst' in your AND statement is nil if you localiz(s)e your variables.

Thanks Ron.

Lee Mac

  • Seagull
  • Posts: 12923
  • London, England
Re: Edit multiple attributes in a single block all with the same tag name.
« Reply #13 on: March 19, 2013, 09:51:54 AM »
Just change the "_X" to either "_:L" or "_+.:E:S:L" in my original code.
Why remove the while loop?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Edit multiple attributes in a single block all with the same tag name.
« Reply #14 on: March 19, 2013, 10:01:13 AM »
Of topic but for other block attribute editing in the future you may want to consider this:
http://www.theswamp.org/index.php?topic=10216.0
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.