Attribute window select

Attribute window select

thomas_schluesselberger
Advocate Advocate
3,196 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,197 Views
34 Replies
Replies (34)
Message 21 of 35

thomas_schluesselberger
Advocate
Advocate

Hi!

 

In the LISP "SelectAtts" from @ВeekeeCZ it works somehow.

But it's a bit buggy and also selects the invisible/blank attributes.

 

 

0 Likes
Message 22 of 35

Sea-Haven
Mentor
Mentor

Your request was for the ability to change various items in a attribute  @ВeekeeCZ  code has selected 2 of those alignment and text, but what about color, rotation etc ? You asked to use Quick properties so have advantage of various items. I could not pass Attributes to Quick select. So going back to my early post can have choices in the dcl choose what you want to change similar to Quick properties, then each value will be asked for, a blank value would be don't change.

 

SeaHaven_1-1716445692991.png

 

 

0 Likes
Message 23 of 35

komondormrex
Mentor
Mentor

@Sea-Haven don't you read the @ВeekeeCZ code well? it doesn't change the text and alignment. what it does is in a clumsy way to find a point to pick up a to be selected attribute with command 'select' and its option 'subobject'. and sure when it selects a bunch of attributes you can change their every property available in the property panel.

komondormrex_0-1716446860504.png

 

Message 24 of 35

Sea-Haven
Mentor
Mentor

 I wondered about the _sub learn something new again. I think the answer is in a combination of the two codes provided. As the ec-cad finds the attribute in a different method without the need to select a attribute to get tagname.

 

I have had another go sometimes works. I have found much to my frustration that SUB does not appear to be an option in my Bricscad V20 when using SELECT tried handle etc as well. 

 

Some one else may realise the problem, I have tested in Acad the select part is not working but it should. if I do manually the select part works. Very fustrating. (initcommandversion) not supported in my Bricscad.

 

 

; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/attribute-window-select/td-p/12771739

(defun is_in_window ( ss P1 P2 )
(if ss
(progn
    (setq X1 (car P1) Y1 (cadr P1))
    (setq X2 (car P2) Y2 (cadr P2))
    (if (> X1 X2)
     (setq T1 X1 X2 X1 X1 T1 T2 Y1 Y1 Y2 Y2 T2)
    )
    (repeat (setq N (sslength ss))
    (setq blk (vlax-ename->vla-object (ssname ss (setq n (1- n)))))
    (if (vlax-property-available-p blk 'hasattributes)
      (progn
       (setq atts (vlax-invoke blk 'getattributes))
        (foreach att atts
		(setq ip (vlax-get att  'TextAlignmentPoint))
            (setq X (car IP) Y (cadr IP))
            (if (and (> X X1)(< X X2)(> Y Y2)(< Y Y1))
              (setq ss2 (cons ip ss2))
			)
		)
	  )
    )
	)
)
)
(princ)
)

(defun doatts ( / )
(command "properties")
(command "_.select")
(repeat (setq x (length ss2))
(command "SUB" (nth (setq x (1- x)) ss2))
)
(command "")
)
)

(defun c:editatt ( / ss2 ss1 p1 p2)
 
(setq ss2 '()) ; blank list of entities
(while (setq P1 (getpoint "\nPick Upper Left Window Point - Enter to exit"))
 (setq P2 (getcorner P1 "\nPick Lower Right Window Point"))

  (setq ss1 (ssget "C" P1 P2 (list (cons 0 "INSERT"))))
  (is_in_window ss1 p1 p2)
)


(if ss2
(doatts)
)

(princ)
)
(c:editatt)

 

 

0 Likes
Message 25 of 35

ec-cad
Collaborator
Collaborator

SeaHaven,

I've been trying to get the ss2 selection set (contains just the Attributes), to be 'selected' for

the Properties window, like Ctrl + Left click. - Doesn't work. I tried 'select' and 'pselect' (undocumented),

no joy. So, the bottom line, 'because' the Attribute is within the Block, when you select just the Attribute,

you get the 'whole' block, not just that Attribute. So I came up with a modification of get_atts.lsp as originally

posted. Named it get_atts2.lsp (code window). It takes each of those selected Attributes, and adds "XXX"

to the TextString, and does an (entmod .. on them. It demonstrates that you 'can' get those Arrributes into

a Selection Set (ss2), but you cannot grip / select them without getting the whole Block. Don't know how

the Ctrl + Left Click does it. Seems to be just a 'nentsel' type of operation, with a twist that it gets multiples.

???

For what it's worth, this is the new code.

 

 

 

;; GET_ATTS2.lsp

;; 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 X1 X2 X2 T1 T2 Y1 Y1 Y2 Y2 T2); CORRECTED
    ;(setq T1 X1 X2 X1 X1 T1 T2 Y1 Y1 Y2 Y2 T2); original was incorrect
    ); 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 elist (entget ent))
              (setq txt (cdr (assoc 1 elist)))
              (if txt
               (progn
                (if (/= txt "") ; do not include blank attributes
                 (setq ss2 (ssadd ent ss2)); add to Selection set
                ); if
               ); progn
              ); if
             ); 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 (ssadd)); blank selection set
   (princ "\n")
   (princ "\nPick Windows or Enter Key to Stop:"); instructions
   (while
    (setq P1 (getpoint "\nPick 1st Window Point"))
    (setq P2 (getcorner P1 "\nPick 2nd 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); add Attributes within window to ss2 selection set
     ); progn
    ); if P1/P2
    (setq P1 nil P2 nil)
   ); while
;; Select the attributes one at a time & 'do' something to them.
    (if (> (sslength ss2) 0)
     (progn
      (setq N 0)
      (repeat (sslength ss2)
       (setq ent (ssname ss2 N))
       (setq elist (entget ent)); Entity List
;; This section just adds "XXX" to the TextString of each Selected Attribute
       (setq txt (cdr (assoc 1 elist))); Text String
       (setq txt (strcat txt "XXX"))
       (entmod (setq elist (subst (cons 1 txt)(assoc 1 elist) elist))); CONStruct replacement Text
       (entupd (ssname ss2 N))
;; If you wanted to change the Location, you would need to modify the (assoc 10 elist)
;; or other things like (assoc 62 "color"), (assoc 40 Height) ..
       (setq N (+ N 1))
      ); repeat
     ); progn
    ); if
  (princ)
 ); function C:GO
 (princ "\nType GO to run:")

 

 

ECCAD

0 Likes
Message 26 of 35

Sea-Haven
Mentor
Mentor

If you look at the code posted I used your select by box, the list SS2 contains the point XYZ of each attribute. If you do on command line, Properties SELECT sub (nth 0 ss2) sub (nth 1 ss2) sub (nth ss2) Enter etc the attributes appear in the properties window. I used BeekeeCZ method of SELECT but its not working and I don't know why not. Will try again.

0 Likes
Message 27 of 35

ec-cad
Collaborator
Collaborator

SeaHaven,

Here's my latest on this topic. May not work on drawings with smaller text size for the attributes,

but works for attached drawing. Don't know why the OP wants many attributes in the Properties window,

that is up to them. I don't see what you can (do) with a single attribute, unless they only select just 1.

But, this code will get the attributes into the Properties Pop Down window.

You can try your 'Select sub (nth n ss2) .. with this code and see if it may work better.

Good luck. I'm done with this one.!

 

ECCAD

;; GET_ATTS3.lsp

;; 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 X1 X2 X2 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 elist (entget ent))
              (setq txt (cdr (assoc 1 elist))); Text Value
              (setq han (cdr (assoc 5 elist))); Entity 'handle'
              (if txt
               (progn
                (if (/= txt "") ; do not include blank attributes
                 (progn
                  (setq pointlist (cons IP pointlist)); insertion points
                  (setq hanlist (cons han hanlist)); add handle to list NOT USED
                  (setq ss2 (ssadd ent ss2)); add to Selection set NOT USED
                 ); progn
                ); if
               ); progn
              ); if
             ); 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 OSM (getvar "OSMODE"))
  (setvar "OSMODE" 576); Near, Intersection
  (setq ss2 (ssadd) hanlist (list) pointlist (list)); blank selection set and lists
   (princ "\n")
   (princ "\nPick Windows or Enter Key to Stop:"); instructions
   (while
    (setq P1 (getpoint "\nPick 1st Window Point"))
    (setq P2 (getcorner P1 "\nPick 2nd 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); add Attributes within window to ss2 selection set
     ); progn
    ); if P1/P2
    (setq P1 nil P2 nil)
   ); while
;; Select the attributes one at a time & 'do' something to them.
    (if (> (length pointlist) 0)
     (progn
      (setvar 'cmdecho 0)
      (initcommandversion)
      (command "_.select")
       (foreach pt pointlist
        (setq X (car pt) Y (cadr pt))
        (setq P1 (list (+ X 1.25)(+ Y 1.5))); for Attributes with Height of 4
        (command "_sub" (trans P1 0 1))
       ); foreach
      (command "")
      (command "_properties")
    ); progn
    ); if
  (setvar "OSMODE" OSM)
  (princ)
 ); function C:GO
 (princ "\nType GO to run:")
0 Likes
Message 28 of 35

thomas_schluesselberger
Advocate
Advocate

Hi, did anyone find some new solution?

 

Sadly the LISP from @ec-cad is not working for me.

After selecting the 2nd window Point i get the error: "Error: Bad string for ssget mode"

 

Although it doesn’t do exactly what I originally wanted, the LISP SelectAtts from @ВeekeeCZ would help me if it only selects the visible attributes. Is this possible in some way?

 

0 Likes
Message 29 of 35

komondormrex
Mentor
Mentor

hey,

you may change original line

(wcmatch (vla-get-tagstring a) g)

in the @ВeekeeCZ  code to 

(and (wcmatch (vla-get-tagstring a) g)
	(zerop (vlax-get a 'invisible))
)

 which will eliminate attributes selecting if they have their invisible property switched on.

0 Likes
Message 30 of 35

thomas_schluesselberger
Advocate
Advocate

Hello!

 

Thanks for the answer. I made a mistake in the wording though.

I didn't mean invisible attributes, but attributes that are not filled and therefore nothing is displayed.

The attribute setting "invisible" is not activated on my attributes.

0 Likes
Message 31 of 35

komondormrex
Mentor
Mentor

then to this

(and (wcmatch (vla-get-tagstring a) g)
	(zerop (vlax-get a 'invisible))
	(/= "" (vla-get-textstring a))
)
0 Likes
Message 32 of 35

thomas_schluesselberger
Advocate
Advocate

Nice!

 

Is there also a way to achieve this, but keep the possibility to filter for attribute tag?

0 Likes
Message 33 of 35

komondormrex
Mentor
Mentor

but there already is one.

0 Likes
Message 34 of 35

thomas_schluesselberger
Advocate
Advocate

I'm stupid.

 

I forgot i need to select an attribute to filtern and not write its tag.

 

 

0 Likes
Message 35 of 35

komondormrex
Mentor
Mentor

adding some fun to the @ВeekeeCZ code. but beware of tag names.

(vl-load-com)
(defun c:SelectAtts ( / s g i l e)
  (if (setq s (ssget "_:L" '((0 . "INSERT") (66 . 1))))
	   (progn
		 (foreach insert (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))
		   (foreach a (vlax-invoke insert 'getattributes)
				(if (not (member (vla-get-tagstring a) g)) (setq g (append g (list (vla-get-tagstring a))))) 
		   )
		 )
		 (setq g (acad_strlsort g))
	     (while (/= "" (setq r (getstring (strcat "\nTag filter, pick to remove [" 
		 										  (apply 'strcat (cdr (apply 'append (mapcar '(lambda (tag) (list "/" tag)) g)))) 
												  "]")
							   )
						)
				)
			(setq g (vl-remove r g))
		 )
      	(repeat (setq i (sslength s))
	  		(mapcar '(lambda (a)
	  			   (if (and (member (vla-get-tagstring a) g)
	  						(/= "" (vla-get-textstring a))
	  				   )
	  			     (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