get value of specific attribute to var

get value of specific attribute to var

renanemeyer
Advocate Advocate
830 Views
8 Replies
Message 1 of 9

get value of specific attribute to var

renanemeyer
Advocate
Advocate

Hello everybody.
I'm wanting a "basic thing" but I can't implement it in my code.
I need to get a specific value of an attribute in a specific block and then use it in the lisp.

It would be the value 11 of the BlkLocal block.

image.png

 

First I did a function in my lisp to get the value:

 

 
(defun get-attrib-value (blk-name tag)
    (vlax-for blk (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))
        (if (and (= (vla-get-ObjectName blk) "AcDbBlockReference") (= (vla-get-Name blk) blk-name))
            (vlax-for attdef blk
                (if (= (vla-get-TagString attdef) tag)
                    (return (vla-get-TextString attdef))
                )
            )
        )
    )
    ""
)

 

Then I used:


(setq VarX (get-attrib-value "BlkLocal" "11"))

 

but it returns empty.
I tried to understand a code found at:

 

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/how-can-extract-attribute-informatio...


however it scans and displays all.
Do you have an easy method to fix this VarX that shows empty even though it's not empty?

0 Likes
Accepted solutions (1)
831 Views
8 Replies
Replies (8)
Message 2 of 9

ronjonp
Mentor
Mentor

Try this small change .. this code is horribly inefficient though because you are going through the entire drawing to get one value.

 

(defun get-attrib-value	(blk-name tag)
  (vlax-for blk	(vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
    (if	(and (= (vla-get-objectname blk) "AcDbBlockReference") (= (vla-get-name blk) blk-name))
      (vlax-for	attdef blk
	(if (= (vla-get-tagstring attdef) tag)
	  (setq return (vla-get-textstring attdef))
	)
      )
    )
  )
  return
)

 

 

Use the 'get-attribute' function HERE in that same thread you linked to.

 

Message 3 of 9

renanemeyer
Advocate
Advocate

thanks for the tip and help with this @ronjonp 
however I try to run it (modified as below just to display)

(defun get-attrib-value	(blk-name tag / return)
  (vlax-for blk	(vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
    (vlax-for b	blk
      (if (and (= (vla-get-objectname b) "AcDbBlockReference") (= (vla-get-name b) blk-name))
	(vlax-for attdef b
	  (and (= (vla-get-tagstring attdef) tag) (setq return (vla-get-textstring attdef)))
	)
      )
    )
  )
  return
)

(defun c:AttValue ()
  (setq VarX (get-attrib-value "BlkLocal" "11")))
  (if VarX 
    (progn
      (princ "\nValue is: ")
      (princ VarX)
    )
    (princ "\nAtt not found.")
  )
  (princ)
)

and even with the block, it doesnt find the value.
even in a new drawing it isnt found.
I tried to change it to vla-get-paperspace because I'm going to use it in the layout, even there, in a new drawing, a new bloc... error: Unknown name.
=//

0 Likes
Message 4 of 9

ronjonp
Mentor
Mentor

My bad .. code updated above it had an error in it. Are your blocks dynamic? If not we can filter them directly without iterating over the entire layout.

Message 5 of 9

renanemeyer
Advocate
Advocate

Alright, I tried to rewrite the code several ways (I adjusted the get-attrib-value function to return an empty string if the attribute is not found, instead of nil) but I hadn't thought about this possibility of filtering it.
It is not dynamic, it is a normal block and is present only in Layout1

0 Likes
Message 6 of 9

ronjonp
Mentor
Mentor

Try this .. it will store the value in 'return'. You need to supply the correct blockname and tagstring.

 

(if (setq s (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "NAME_OF_YOUR_BLOCK"))))
  (foreach att (vlax-invoke (vlax-ename->vla-object (ssname s 0)) 'getattributes)
    (and (= (vla-get-tagstring att) "NAME_OF_TAGSTRING") (setq return (vla-get-textstring att)))
  )
)

 

Message 7 of 9

renanemeyer
Advocate
Advocate
Accepted solution

@ronjonp 
I did the test and it didn't work (I did several other variations and I'll leave a comment on how the one that worked in case you or anyone visiting also goes through something similar)
I used the entnext function with no arguments to get the first entity in the drawing.

(defun get-attrib-value (blk-name tag / all-entities att val)
  (setq all-entities (entnext))
  (while all-entities
    (if (and (= (cdr (assoc 0 (entget all-entities))) "INSERT")
             (= (cdr (assoc 2 (entget all-entities))) blk-name))
      (progn
        (setq att (entnext all-entities))
        (while (and att (not val))
          (if (and (= (cdr (assoc 0 (entget att))) "ATTRIB")
                   (= tag (cdr (assoc 2 (entget att)))))
            (setq val (cdr (assoc 1 (entget att))))
          )
          (setq att (entnext att))
        )
      )
    )
    (setq all-entities (entnext all-entities))
  )
  val
)

0 Likes
Message 8 of 9

Sea-Haven
Mentor
Mentor

You dont need the tagname if you want the 11th attribute, a couple of ways can loop with a counter till get to 11 and retrieve that attribute, or can get the 11th attribute directly (nth (- 11 1) atts)

 

 

(setq blk (vlax-ename->vla-object (car (entsel "\nPick title block "))))
(setq atts (vlax-invoke blk 'getattributes))
(setq att (nth 10 atts))
(setq txt11 (vlax-get att 'textstring))

 

Message 9 of 9

renanemeyer
Advocate
Advocate

Yes, @Sea-Haven yours is a great idea.
Only on this occasion is it not so viable as you would only need to store it in a variable to use it later, doing so without the need to select the block manually.
Thanks for sharing

0 Likes