Happy Hobbit Posted June 21, 2016 Posted June 21, 2016 (edited) I have a lot of blocks in the drawings I'm working on. They have one attribute only in each, which are empty or blank Some of them I'd like to put a (any) value into. I've tried Without success: (setq en (car(entsel))) (setq blk (cdr(assoc 2 (entget en)))) (if (setq ent (tblobjname "block" blk)) (while (setq ent (entnext ent)) (setq entx (entget ent)) (if (eq(cdr(assoc 0 entx)) "ATTDEF") (if (entmod (subst (cons 1 "HELLO WORLD") (assoc 1 entx) entx)) (entupd ent) ) ) ) and: (setq en (car(entsel))) (setq obj (vlax-ename->vla-object en)) (setq att (vlax-invoke obj 'getattributes)) (vla-put-textstring att "HELLO WORLD") Both the above select the parent block with the (blank) attribute in I'm only just becoming familiar with vl-lisp & don't really know what I'm doing yet. My 'guess' it's the last two lines of the latter code that is wrong somewhere. Any ideas please anyone? Edited June 21, 2016 by Happy Hobbit Quote
BIGAL Posted June 21, 2016 Posted June 21, 2016 When you 'getattributes then do a not tested (foreach attx att (vla-put-textstring attx "HELLO WORLD") ; this will put hello world into every attribute ; if you only want 1st (setq x 1) ; then setup a (if (= x 1) (progn (vla-put-textstring attx "HELLO WORLD")(setq x 2))) ; x =2 so skip rest of attributes ; if you have 5 attributes then set the x to the correct attribute creation number ; the attributes are retrieved in creation order ;double click a block and all the attributes are displayed in creation order ) ; a tag name example (foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS1 0 )) 'getattributes) (if (= oldtag1 (strcase (vla-get-tagstring att))) (vla-put-textstring att newstr1) ) ; end if Quote
Tharwat Posted June 21, 2016 Posted June 21, 2016 Consider this as an example: (while (setq ss (ssget "_+.:S:E:L" '((0 . "INSERT") (66 . 1)))) (setq sn (ssname ss 0)) (while (/= (cdr (assoc 0 (setq e (entget (setq sn (entnext sn)))))) "SEQEND") (if (eq (cdr (assoc 0 e)) "ATTRIB") (entmod (subst (cons 1 "HELLO WORLD") (assoc 1 e) e)) ) ) ) Quote
Happy Hobbit Posted June 21, 2016 Author Posted June 21, 2016 Whoa ! I shall have to study this at home later. Thanks ever so chaps. Quote
Happy Hobbit Posted June 21, 2016 Author Posted June 21, 2016 Quick further Q for someone: Does (entnext block-entity-name) always return an attribute (assuming there's one or more in the block) Quote
Tharwat Posted June 21, 2016 Posted June 21, 2016 Quick further Q for someone:Does (entnext block-entity-name) always return an attribute (assuming there's one or more in the block) If you are indicating to my codes so the answer is YES except the last entity name would be named SEQEND and I used this entity name to end the looping for attributes in the selected attributed block. Quote
Happy Hobbit Posted June 21, 2016 Author Posted June 21, 2016 Thank you Tharwat, I was a little confused by the Autodesk Help description "You can access the internal structure of these complex entities by walking through the sub-entities with entnext". A line or text item is a sub-entity of a block, but all my experiments have shown that if there's no attribute entnext returns nil Quote
Tharwat Posted June 21, 2016 Posted June 21, 2016 In my posted codes I used the entnext to cycle through attributed block but if you used this method to cycle regular block so you won't be able to access the block definition unless you get the entity name from the table object ( as in your firstly posted codes ) then do your stuff with the found entity within the block. Just ask if there is any sentence not that clear to you or if you need more info about the theme. Quote
Happy Hobbit Posted June 21, 2016 Author Posted June 21, 2016 Thank you again Tharwat The code I settled on in the end is: defun c:test ( / att done en str) (setq str "X") (while (not done) (setvar 'errno 0) (setq en (car(entsel"\nSelect Attributed Block"))) (cond ((= 7 (getvar 'errno)) (princ "\nMissed, Please Try Again.")) ;; Stay in loop ((= (getvar 'errno) 52) (setq done T)); Right Click at Selection prompt exits loop ((= (getvar 'errno) 0); something picked (if (eq (cdr(assoc 0 (entget en))) "INSERT") (progn (setq att (entnext en)) (vla-put-textstring (vlax-ename->vla-object att) str) );; progn (princ "\nItem not a block, Try Again") ) ); something picked, ) ); (while (not done) (princ) ) I didn't need the extra functionality of the while/SEQEND functionality as it's on single attributed blocks I need to put a value into. However it's a very useful tip to know Quote
Tharwat Posted June 21, 2016 Posted June 21, 2016 You are welcome anytime. Well done with your codes but a small hint, try to select a regular block and not attributed. Quote
broncos15 Posted June 21, 2016 Posted June 21, 2016 Thank you again Tharwat The code I settled on in the end is: defun c:test ( / att done en str) (setq str "X") (while (not done) (setvar 'errno 0) (setq en (car(entsel"\nSelect Attributed Block"))) (cond ((= 7 (getvar 'errno)) (princ "\nMissed, Please Try Again.")) ;; Stay in loop ((= (getvar 'errno) 52) (setq done T)); Right Click at Selection prompt exits loop ((= (getvar 'errno) 0); something picked (if (eq (cdr(assoc 0 (entget en))) "INSERT") (progn (setq att (entnext en)) (vla-put-textstring (vlax-ename->vla-object att) str) );; progn (princ "\nItem not a block, Try Again") ) ); something picked, ) ); (while (not done) (princ) ) I didn't need the extra functionality of the while/SEQEND functionality as it's on single attributed blocks I need to put a value into. However it's a very useful tip to know FYI, you can also use the vla-setblockattributevalue function to set attributes of blocks (you'll just need to check if 64 bit or 32 bit). Quote
Happy Hobbit Posted June 21, 2016 Author Posted June 21, 2016 You are welcome anytime. Well done with your codes but a small hint, try to select a regular block and not attributed. Aggggghhhhhh ! well noticed Tharwat I have amended my if to: (if (and (eq (cdr(assoc 0 (entget en))) "INSERT") (entnext en) (eq (cdr(assoc 0 (entget (entnext en)))) "ATTRIB") ); and which seems to work, although it may be overkill..... Quote
Happy Hobbit Posted June 21, 2016 Author Posted June 21, 2016 FYI, you can also use the vla-setblockattributevalue function to set attributes of blocks (you'll just need to check if 64 bit or 32 bit). I haven't used that, looks well complicated from what I've read about it Quote
Tharwat Posted June 21, 2016 Posted June 21, 2016 Your amendment is correct but have a look at the following correction which check if the block object is attributed via the DXF 66 is available and is equal to 1 Also I have added the codes in pure AutoLISP without converting the block object to VLA-Object and you should localise the variable 'e' but if you just want to go with the VLA conversion just remove the commented codes as shown in the following example. (if (and (eq (cdr (assoc 0 (entget en))) "INSERT") (eq (cdr (assoc 66 (entget en))) 1) ) (vla-put-textstring (vlax-ename->vla-object (entnext en)) str) ;; (entmod (subst (cons 1 str) (assoc 1 (setq e (entget (entnext en)))) e)) (princ "\nItem not a block, Try Again") ) Quote
Happy Hobbit Posted June 21, 2016 Author Posted June 21, 2016 assoc 66 is a new one to me. I had to look it up. I much prefer vanilla lisp to VLA lisp - much easier to understand - so shall be using this! Thank you yet again for your time Tharwat Quote
Tharwat Posted June 21, 2016 Posted June 21, 2016 You are most welcome - glad to help. Here is the related DXF 66 for you to read if you would like to. THIS LINK Quote
Happy Hobbit Posted June 21, 2016 Author Posted June 21, 2016 Oh I read this, I think they're identical Quote
Tharwat Posted June 21, 2016 Posted June 21, 2016 Oh I read this, I think they're identical Yeah no changes on AutoLISP functions since they have released to public so whatever the year of the help document is, they should be identical and a copy of origin. Quote
Lee Mac Posted June 21, 2016 Posted June 21, 2016 FYI, you can also use the vla-setblockattributevalue function to set attributes of blocks (you'll just need to check if 64 bit or 32 bit). Only for blocks nested within Tables or MLeaders Quote
Happy Hobbit Posted June 22, 2016 Author Posted June 22, 2016 Only for blocks nested within Tables or MLeaders Why on earth.........to achieve what........... Takes all types to make a world I suppose Must have been a very bored day at the office when the lisp language writers coded THAT one Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.