Attribute window select

Attribute window select

thomas_schluesselberger
Advocate Advocate
3,179 Views
34 Replies
Message 1 of 35

Attribute window select

thomas_schluesselberger
Advocate
Advocate

Hi guys!

 

Is there a way to select multiple attributes (if possible even from multiple different blocks) via a normal selection window?

 

When i want to move or edit other factors i always need to select the attributes i want one by one.

So the goal is to select the attributes with a window/cross select window as the attributes would be normal texts.

 

If possible it woud also be nice, that the LISP is capable of selecting attributes and normal text at the same time.

0 Likes
3,180 Views
34 Replies
Replies (34)
Message 2 of 35

Kent1Cooper
Consultant
Consultant

@thomas_schluesselberger wrote:

.... Is there a way to select multiple attributes (if possible even from multiple different blocks) via a normal selection window? ....


No, unfortunately.  Window selection can "see" only top-level objects, not nested ones.

Kent Cooper, AIA
0 Likes
Message 3 of 35

thomas_schluesselberger
Advocate
Advocate

Is there maybe some way LISP could help?

0 Likes
Message 4 of 35

Kent1Cooper
Consultant
Consultant

@thomas_schluesselberger wrote:

Is there maybe some way LISP could help?


Probably not, if I understand what you intend.  But illustrate for us.  Do you, for example, want to select, say, two Attributes from one Block which also contains other Attributes that you don't want selected, and at the same time one Attribute from another Block which also contains others you don't want?  That could be achievable by picking on them individually, but with a window?

 

Maybe AutoLisp could take your window as a Crossing-type one, find the Blocks involved, and look at their Attributes.  But narrowing it down to those that are inside the window [rather than by, for example, their Tags] seems next to impossible, considering that positions of things nested in Blocks are stored at coordinates relative to the Block's insertion point, not to the window used to select it nor to the current Coordinate System, and with the complications of scale factors other than 1 and rotation other than 0, and the fact that Attributes [if not defined to prevent it] can be moved from their original positions in the Block definition, etc., etc.  [I haven't looked at what happens to an Attribute's locational entity data relative to the Block's insertion point if the Attribute gets re-positioned.]  I wouldn't say it can't be done, but it seems very daunting.

 

[I confess -- I'm curious:  What kind of purpose would you have for selecting multiple but not all Attributes in multiple Blocks at the same time?]

Kent Cooper, AIA
0 Likes
Message 5 of 35

komondormrex
Mentor
Mentor

eg. to rotate 'em. or move alongside. or anything else.

0 Likes
Message 6 of 35

thomas_schluesselberger
Advocate
Advocate

Hi!

 

I attached you a video.

 

The rectangles with the numbers are each a block with an attribute.

I would like to mark these attributes using window selection, so that i can change the value, widht, ...

Currently I always have to select them one by one with CTRL+left click.

0 Likes
Message 7 of 35

ec-cad
Collaborator
Collaborator

This is an oldy of mine. Will 'move' single attribute to new location P1.

Maybe you can use the 'attedit' to do what you wanted for multiple attributes.

Won't do Text.

 

ECCAD

;; MAT.LSP, (C)opyright 2001, Control Systems & Services, L.L.C.
;; Function: to Move a given Attribute's location..
;; Revised: 07-Oct-2001, new program..
(defun C:MAT ()
 (setvar "CMDECHO" 0)
 (setvar "ORTHOMODE" 1)
 (setq P2 (getpoint "\nPick Window around Attribute to Move: "))
 (setq P3 (getcorner P2 "\nPick other Window Point: "))
 (setq P1 nil)
  (while (= P1 nil)
   (prompt (strcat "\nPick a new location for this Attribute: "))
   (setq P1 (getpoint))
  ); end while
 (command "_attedit" "_Y" "*" "*" "*" "_w" P2 P3 "_P" P1 "")
 (setq P1 nil P2 nil P3 nil)
 (princ)
); end function
(princ)
0 Likes
Message 8 of 35

Sea-Haven
Mentor
Mentor

If its a block repeated then could move the attribute values say a fixed amount away from the square number if that is what you want, can see all sorts of problems when more than 1 attribute.

 

Post a dwg with a before and an after. Need more information about what it is your trying to do.

0 Likes
Message 9 of 35

thomas_schluesselberger
Advocate
Advocate

Well there is not really an example DWG.

 

I just want the attributes to be selected, like when you select them with CTRL+leftclick.

 

0 Likes
Message 10 of 35

ВeekeeCZ
Consultant
Consultant

Here is my contribution. It's just about proving the concept - dirty enough. 

And no. Not going to do the actual att window selection. 

Probably required at least 2022.

 

(vl-load-com)

(defun c:SelectAtts ( / s g i l e)
  
  (if (and (setq s (ssget "_:L" '((0 . "INSERT") (66 . 1))))
	   (setq g "")
	   (progn
	     (while (setq e (car (nentsel "\nSelect att for tag filter <all>: ")))
	       (setq g (strcat (getpropertyvalue e "Tag") "," g)))
	     (setq g (if (= g "") "*" g)))
	   )
    (progn
      (repeat (setq i (sslength s))
	(mapcar '(lambda (a)
		   (if (wcmatch (vla-get-tagstring a) g)
		     (setq l (cons (list a
					 (vla-get-alignment a)
					 (vla-get-textstring a)
					 (progn
					   (vla-put-alignment a 10)
					   (vla-put-textstring a "X")
					   (vlax-get a 'TextAlignmentPoint)))
				   l))))
		(vlax-invoke (vlax-ename->vla-object (ssname s (setq i (1- i)))) 'getattributes)))
      (setvar 'cmdecho 0)
      (initcommandversion)
      (command "_.select")
      (foreach a l (command "_sub" (trans (last a) 0 1)))
      (foreach a l
	(vla-put-alignment (car a) (cadr a))
	(vla-put-textstring (car a) (caddr a)))
      (command "")
      (setvar 'cmdecho 1)))
  (princ)
  )

 

0 Likes
Message 11 of 35

thomas_schluesselberger
Advocate
Advocate

Hi!

 

So this is already something.

For me it's also ok that you have to select blocks whose attributes are getting marked.

 

There are only two things that don't work quite as well as I would like:

I would be very happy if you would take a moment to adapt/fix this things.

 

- The default value of "Select att for tag filter" should not be "all".

   I would need it so that only attributes that have a value and are visible are getting marked.

   But the option to select an attribute to filter by its tag is great and should remain.

 

- Strangely, attributes of unmarked blocks are also selected if the attribute filter is set to "all".

   This happens when the blocks are near the blocks i select.

   (i attached you a video where i show the problem)

 

Thank you in advance!

 

 

 

0 Likes
Message 12 of 35

komondormrex
Mentor
Mentor

@thomas_schluesselberger wrote:

I just want the attributes to be selected, like when you select them with CTRL+leftclick.

 


to do with them afterwards what?

0 Likes
Message 13 of 35

thomas_schluesselberger
Advocate
Advocate

Everything possible.


Adjust rotation, move, adjust width factor, adjust text height, change layer, change color, etc...

0 Likes
Message 14 of 35

Sea-Haven
Mentor
Mentor

If you do a bit of gogling you will find some examples I do say some as you have asked for multiple options. So various lisp functions joined together.

 

You would just start with a SSGET and filter for blocks, using VLisp can get attributes and then for each attribute change a property. This is just a show properties for an attribute.

 

(defun c:wow ( / obj)
(setq obj (vlax-ename->vla-object (car (nentsel "\nSelect an Attribute"))))
(vlax-dump-object obj)
)

 I would write a defun for each option. Testing as you go. 

SeaHaven_0-1715910763746.png

 

(if (not AH:Butts)(load "Multi Radio buttons.lsp"))
(setq ans (ah:butts 1 "V" '("Choose an Option" "rotation" "move" "adjust width factor" "adjust text height" "change layer" "change color")))

 

0 Likes
Message 15 of 35

komondormrex
Mentor
Mentor

as for me, i would rather prefer the attributes be selected somewhat like that.

komondormrex_0-1715955597796.gif

 

0 Likes
Message 16 of 35

ec-cad
Collaborator
Collaborator

Here is a Lisp (old and new vl mixed) that will get a 'list' - ss2, that contains all the attributes

within a Picked Window. Returns a list of each that are found in that Window.

It prints the Tagname, and Value. It does NOT do anything with those attributes, just lists them.

You can probably use this lisp as a Function, then 'if ss2 ....... do whatever to each of them.

;; GET_ATTS.lsp
;; Written by ECCAD for AutoDesk Forum, 5/17/2024
;; Function: to get a selection set of just 'Attributes' "ATTDEF"'s that fall within a Window.

;; Function to determine if the ATTDEF falls within a window, based on it's insertion point.
;; Send in Selection Set, and Window Points

 (vl-load-com)

 (defun is_in_window ( ss P1 P2 ); returns ss2, attdef's with insertion points 'inside' window.
  (if ss
   (progn
    (setq X1 (car P1) Y1 (cadr P1)); Window points P1, X & Y
    (setq X2 (car P2) Y2 (cadr P2)); Window points P2, X & Y
    (if (> X1 X2); Windowed from Right to Left - swap points
     (setq T1 X1 X2 X1 X1 T1 T2 Y1 Y1 Y2 Y2 T2)
    ); if
    (setq N (sslength ss) I 0)
    (repeat N
     (setq blk (vlax-ename->vla-object (ssname ss I)))
     (if (safearray-value (setq atts (vlax-variant-value (vla-getattributes blk))))
      (progn
       (setq atts (vlax-safearray->list (vlax-variant-value (vla-getattributes blk))))
        (foreach att atts
         (setq nam (vla-get-objectname att))
          (if (= nam "AcDbAttribute")
           (progn
            (setq IP (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint att))))
            (setq X (car IP) Y (cadr IP))
            (if (and (> X X1)(< X X2)(> Y Y2)(< Y Y1))
             (progn
              (setq ent (vlax-vla-object->ename att))
              (setq ss2 (cons (entget ent) ss2))
             ); progn
            ); if it is in window
          ); progn
         ); if nam =
        ); foreach
       ); progn
      ); if safe array
     (setq I (+ I 1))
     ); repeat
    ); progn
   ); if ss
  (princ)
 ); function

 (defun C:GO ( )

;; Get the selection set
;;
  (setq ss2 (list)); blank list of entities
  (setq P1 (getpoint "\nPick Upper Left Window Point"))
  (setq P2 (getcorner P1 "\nPick Lower Right Window Point"))
  (if (and (/= P1 nil)(/= P2 nil))
   (progn
    (setq ss1 (ssget "C" P1 P2 (list (cons 0 "INSERT"))))
    (is_in_window ss1 P1 P2)
    (if ss2
     (progn
      (foreach attr ss2
       (setq tag "" value "")
       (setq tag (cdr (assoc 2 attr)) value (cdr (assoc 1 attr)))
       (if (and (/= tag "")(/= value ""))
        (progn
         (princ "\n")
         (princ (strcat "\nFound Attribute: Tagname = " tag " and Value = " value))
        ); progn
       ); if
      ); foreach
     ); progn
    ); if ss2
   ); progn
  ); if P1/P2
 (princ)
 ); function C:GO
 (princ "\nType GO to run:")

Seems to work for a few samples I ran.

ECCAD

 

0 Likes
Message 17 of 35

Sea-Haven
Mentor
Mentor

At line 61 you get an attribute, would you not then just do the selected function changes  as shown in the dcl at post 14,  It should have been this Multi Toggles.lsp.

 

 

 

(foreach attr ss2

 

 

 

I think we need Thomas to come forward with some actual values of what is to be changed eg color is simple change. Red now Green, 1 -> 3.

 

Like the idea of checking is attribute in selection window, should it be able to do multiple window selects say a while with P1 P2 but a single attribute would be pick twice. ie non linear arrangement of attributes, I can see that as next request. 

0 Likes
Message 18 of 35

thomas_schluesselberger
Advocate
Advocate

Hello everyone!

Thank you for your efforts.

 

What I'm searching for is relatively exactly what @komondormrex did.

The only thing I'm not sure about is whether the LISP just highlights the attributes or whether the attributes are really selected as if I were selecting them with CTRL-left click. 

 

 

Regarding the question from @Sea-Haven:

The LISP itself should not make any changes to the attributes themselves. The LISP itself should only mark the attributes. I would then like to make the changes in the quick properties.

 

 

0 Likes
Message 19 of 35

komondormrex
Mentor
Mentor

@thomas_schluesselberger 

in the try-off, it is selecting. to get attributes selected as one does with ctrl-click is the trickiest part of the routine.)

0 Likes
Message 20 of 35

Sea-Haven
Mentor
Mentor

Wanting to use Quick properties. If you make a selection set then can pass that to the "Select" command and the properties window will display.

(command "properties")
(vla-sendcommand (vla-get-activedocument (vlax-get-acad-object)) "_.Select !ss2  ")

I have code but doing something wrong at making SS2 a selection set. It will work at higher level ie select blocks. I don't think you can make a selection set of attributes and use Quick properties.

 

0 Likes