Getting block tag names

Getting block tag names

Anonymous
Not applicable
2,325 Views
7 Replies
Message 1 of 8

Getting block tag names

Anonymous
Not applicable

Greetings,

Im trying to create a LISP routine, but looking for something similiar didnt turned up anything I would understand enought to be able to modify it for my purposes, so I want ask specificaly:

I have LISP, on which start it asks (with "entsel") for selecting single block. It verifies that selected entity IS a block and HAS some attributes. And from here, Im gettin lost: I want to extract Tags from this selected block, whose ammount and names may differ and save them to list. After that, user is asked (with drop-down list) to select one from these found tag names. AutoCAD then inserts pre-calculated string saved in another variable (in my case "val")  into value of that selected attribute.

I would appreciate any help, Ive been browsing forums for three days now and I feel like knowing less, then when I started.

 

Best regards

Tomas Stejskal

0 Likes
Accepted solutions (1)
2,326 Views
7 Replies
Replies (7)
Message 2 of 8

ВeekeeCZ
Consultant
Consultant

Don't you want to rather use (nentsel) to select the attribute directly? 

 

BTW HERE Lee has many examples how to work with attributes. I would probably go with the last one.

0 Likes
Message 3 of 8

ronjonp
Mentor
Mentor

Here is one way to do it:

(defun c:foo (/ a e)
  (cond	((and (setq e (car (entsel)))
	      (vlax-property-available-p (setq e (vlax-ename->vla-object e)) 'hasattributes)
	 )
	 (setq a (mapcar '(lambda (x) (vla-get-tagstring x)) (vlax-invoke e 'getattributes)))
	 (mapcar 'print (vl-sort a '<))
	)
  )
  (princ)
)
(vl-load-com)
0 Likes
Message 4 of 8

Moshe-A
Mentor
Mentor

@ronjonp  hi,

 

what is the benefit on using (cond) with one case instead of classic (if)?

 

 

0 Likes
Message 5 of 8

ronjonp
Mentor
Mentor

 


@Moshe-A wrote:

@ronjonp  hi,

 

what is the benefit on using (cond) with one case instead of classic (if)?

 

 


Not sure of a benefit just my personal preference. If I have to use a 'progn' for the results I'll choose cond. Then again sometimes I'll just wrap the whole thing in 'and' depending on what I want to return.

(defun c:foo (/ a e)
  (and (setq e (car (entsel)))
       (vlax-property-available-p (setq e (vlax-ename->vla-object e)) 'hasattributes)
       (setq a (mapcar '(lambda (x) (vla-get-tagstring x)) (vlax-invoke e 'getattributes)))
       (mapcar 'print (vl-sort a '<))
  )
)
(vl-load-com)  

I could have used 'if like so too I guess.

(defun c:foo (/ e)
  (if (and (setq e (car (entsel)))
	   (vlax-property-available-p (setq e (vlax-ename->vla-object e)) 'hasattributes)
      )
    (mapcar 'print
	    (vl-sort (mapcar '(lambda (x) (vla-get-tagstring x)) (vlax-invoke e 'getattributes)) '<)
    )
  )
  (princ)
)

 

0 Likes
Message 6 of 8

Anonymous
Not applicable

Thank you for reply, but I think you did not understand me. For example, I have block with two Tags called FNC and NUMB (may vary). Those are names of variables, which I can fill and the values are then then shown inside the block. So, I can have block reprezenting utility with sequence number like AX-1234A, where AX is writen under FNC and 1234A under NUMB. I need something, where I can choose from initget-like menu from FNC and NUMB and LISP then writes anything from pre-calculated variable to Attribute of that selected Tag.

So, back to example, pre-calc variable is 1234A. I select the "template" block, which includes two clear Attributes called FNC and NUMB. Then Im tasked to select one of these names (initget-like), where I can chose from FNC and NUMB. If I choose NUMB, the variable called NUMB sets to 1234A and ends routine.

I am absolute begginer to LISP, I had no training of any kind, Im officialy even not supposed to be programming. But I have moral problem doing ten clicks, while it can be done in one. If yours code DOES that I just written here, Im sorry, I dont really understand all the parts and maybe implemented it to my code with some mistake...

 

Thank you for any kind of support

Tomas Stejskal

0 Likes
Message 7 of 8

ВeekeeCZ
Consultant
Consultant
Accepted solution

Well, if you want to go with visual LISP then here you are. Assuming you have no space within tag names.

 

(vl-load-com)

(defun c:foo (/ e abcs tags keys tag)
  
  ;; Set Attribute Value  -  Lee Mac
  ;; Sets the value of the first attribute with the given tag found within the block, if present.
  ;; blk - [vla] VLA Block Reference Object
  ;; tag - [str] Attribute TagString
  ;; val - [str] Attribute Value
  ;; Returns: [str] Attribute value if successful, else nil.
  
  (defun LM:vl-setattributevalue ( blk tag val )
    (setq tag (strcase tag))
    (vl-some
      '(lambda ( att )
         (if (= tag (strcase (vla-get-tagstring att)))
           (progn (vla-put-textstring att val) val)))
      (vlax-invoke blk 'getattributes)))
  
  
  
  (if (and (setq e (car (entsel)))
           (vlax-property-available-p (setq e (vlax-ename->vla-object e)) 'hasattributes)
           (setq abcs '("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U"))
           (setq tags (vl-sort (mapcar '(lambda (x) (vla-get-tagstring x)) (vlax-invoke e 'getattributes)) '<))
           (setq keys (vl-string-right-trim " " (apply 'strcat (mapcar '(lambda (a b) (strcat a ":" (strcase b T) " "))
                                                                      abcs tags))))
           )
    (progn
      (initget keys)
      (if (setq tag (getkword (strcat "\nPick a tag [" (vl-string-translate " " "/" keys) "]: ")))
        (LM:vl-setattributevalue e (substr tag 3) "new"))))
  (princ)
  )

 

0 Likes
Message 8 of 8

Anonymous
Not applicable

Wow, thank you so much. After just a gentle touch it is just like I wished it to be. Thanks once again and have a nice day.

 

Best possible regards

Tomas Stejskal

0 Likes