broncos15 Posted March 7, 2016 Posted March 7, 2016 (edited) I have been working on this LISP routine for a while to edit a multileader with a block and attribute. I am able to select all the similar multileaders, but then the code doesn't do anything when I am trying to actually edit them. Does anyone have any suggestions for what I am doing wrong? (defun c:editmla (/ *error* entlist ent302 ent8 ss ss1 x x1 entlist2 newVal whilestop cnt MLeaderStyle) (defun *error* (msg) (if (not (member msg '("Function cancelled" "quit / exit abort")) ) (princ (strcat "\nError: " msg)) ) (princ) ) (setq whilestop t) (setvar 'errno 0) (while whilestop (if (setq ent (car (entsel "\nSelect MLEADER with # to select: "))) (progn (setq entlist (entget ent)) (cond ((/= (cdr (assoc 0 entlist)) "MULTILEADER") (princ "\nSelected object is not a multileader.") ) ((/= acblockcontent (cdr (assoc 172 (reverse entlist)))) (princ "\nSelected multileader does not contain an attributed block." ) ) (t (if (setq newVal (getint "\nNew Attribute Value: ")) (progn (editmla:grab) (editmla:tag) (setq whilestop nil) ) (setq whilestop nil) ) ) ) ) (if (/= (getvar 'errno) 52) (princ "\nYou missed. Try again.") (setq whilestop nil) ) ) ) (princ) ) ;;;This portion of the code is what grabs the mleaders (defun editmla:grab () (setq ent8 (cdr (assoc 8 entlist))) (foreach x entlist (if (and (eq 302 (car x)) (not (or (wcmatch "LEADER{" (cdr x)) (wcmatch "" (cdr x))) ) ) (setq ent302 (cdr x)) ) ) (if (/= ent302 nil) (progn (setq ss (ssget "_A" (list '(0 . "MULTILEADER") (cons 8 ent8) (cons 302 ent302) ) ) ) (setq MLeaderStyle (vla-get-stylename (vlax-ename->vla-object ent)) cnt 0 ss1 (ssadd) ) (repeat (sslength ss) (if (= (vla-get-stylename (vlax-ename->vla-object (ssname ss cnt))) MLeaderStyle) (ssadd (ssname ss cnt) ss1) ) (setq cnt (+ cnt 1)) ) (if (sslength ss1) (sssetfirst nil ss1) ) (setq whilestop nil) ) (princ "\nMultileader attribute is blank.") ) ) ;;;This is what actually edits the attribute (defun editmla:tag () (if ss1 (progn (setq cnt2 0) (repeat (sslength ss1) (setq entlist2 (ssname ss1 cnt2)) (foreach x1 entlist2 (if (and (eq 302 (car x1)) (not (or (wcmatch "LEADER{" (cdr x1)) (wcmatch "" (cdr x1))) ) ) (setq entlist2 (subst (cons 302 newVal) (assoc 302 entlist2) entlist2)) (entmod entlist2) ) ) ) ) ) ) Edited March 7, 2016 by broncos15 Quote
broncos15 Posted March 8, 2016 Author Posted March 8, 2016 So I have been researching it some more and I feel like my issue has to do with my entmod portion. Am I incorrectly handling the selection set with the entmod? Quote
broncos15 Posted March 15, 2016 Author Posted March 15, 2016 I have continued to mess with this and I have tried 2 different solutions, but I can't get either to work. The first solution using textedit is: (defun editmla:tag () (if ss1 (progn (setq cnt2 0) (repeat (sslength ss1) (setq ent2 (ssname ss1 cnt2)) (command "._tedit" ent2 "" newVal "") ) ) ) ) I am confused why this doesn't work because I am following exactly how text edit works. My other solution was using a slight variant with entmod, but it still isn't doing anything. My code is (defun editmla:tag () (if ss1 (progn (setq cnt2 0) (repeat (sslength ss1) (setq ent2 (ssname ss1 cnt2)) (foreach x1 ent2 (if (and (eq 302 (car x1)) (not (or (wcmatch "LEADER{" (cdr x1)) (wcmatch "" (cdr x1))) ) ) (setq ent2 (subst (cons 302 newVal) (assoc 302 ent2) ent2)) (entmod (reverse ent2) ) ) ) ) ) ) ) I am confused why this doesn't do anything because I am making use of entmod. Quote
broncos15 Posted March 15, 2016 Author Posted March 15, 2016 I have now tried to do it using the vla-SetBlockAttributeValue function, but this doesn't work either. I know it has to do with me not using the function correctly, but can anyone point out my error? (defun editmla:tag () (if ss1 (progn (setq cnt2 0) (repeat (sslength ss1) (setq ent2 (vlax-ename->vla-object (ssname ss1 cnt2))) (vla-SetBlockAttributeValue ent2 (vla-get-ObjectId ent2) newVal) ) ) ) ) Quote
broncos15 Posted March 15, 2016 Author Posted March 15, 2016 So after looking into this more, I realize that my issue has to do with the fact that I am using the setblockattributevalue method, but I am not getting the attribute definition. Is there an easy way to do this for Multileaders. I have seen Lee's example here at the link below, but I can't figure out how to do this with multileaders https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/vla-setblockattributevalue-please-help/td-p/4758691. Quote
Lee Mac Posted March 15, 2016 Posted March 15, 2016 (edited) Here's a function for you to consider: ;; Set MLeader Block Attribute Value - Lee Mac ;; mld - [vla] MLeader object with attributed block content ;; tag - [str] Attribute tag whose value will be modified ;; val - [str] New attribute value (defun LM:setmleaderblockattributevalue ( mld tag val ) (if (= acblockcontent (vla-get-contenttype mld)) (vl-catch-all-error-p (vl-catch-all-apply '(lambda ( / oid ) (vlax-for obj (vla-item (vla-get-blocks (vla-get-document mld)) (vla-get-contentblockname mld) ) (if (and (= "AcDbAttributeDefinition" (vla-get-objectname obj)) (= :vlax-false (vla-get-constant obj)) (= (strcase tag) (strcase (vla-get-tagstring obj))) ) (progn (if (vlax-property-available-p obj 'objectid32) (setq oid (vla-get-objectid32 obj)) (setq oid (vla-get-objectid obj)) ) (if (vlax-method-applicable-p mld 'setblockattributevalue32) (vla-setblockattributevalue32 mld oid val) (vla-setblockattributevalue mld oid val) ) (exit) ) ) ) ) ) ) ) ) Call the above with an MLeader vla-object, attribute tag and attribute value. Various performance improvements could be incorporated based on the methods I used in my Auto Label Attributes program. Edited November 14, 2019 by Lee Mac Quote
broncos15 Posted March 15, 2016 Author Posted March 15, 2016 Here's a function for you to consider: [color=green];; Set MLeader Block Attribute Value - Lee Mac[/color] [color=green];; mld - [vla] MLeader object with attributed block content[/color] [color=green];; tag - [str] Attribute tag whose value will be modified[/color] [color=green];; val - [str] New attribute value[/color] ([color=blue]defun[/color] LM:setmleaderblockattributevalue ( mld tag val ) ([color=blue]if[/color] ([color=blue]=[/color] [color=blue]acblockcontent[/color] ([color=blue]vla-get-contenttype[/color] mld)) ([color=blue]vl-catch-all-error-p[/color] ([color=blue]vl-catch-all-apply[/color] '([color=blue]lambda[/color] ( [color=blue]/[/color] oid ) ([color=blue]vlax-for[/color] obj ([color=blue]vla-item[/color] ([color=blue]vla-get-blocks[/color] ([color=blue]vla-get-document[/color] mld)) ([color=blue]vla-get-contentblockname[/color] mld) ) ([color=blue]if[/color] ([color=blue]and[/color] ([color=blue]=[/color] [color=maroon]"AcDbAttributeDefinition"[/color] ([color=blue]vla-get-objectname[/color] obj)) ([color=blue]=[/color] [color=blue]:vlax-false[/color] ([color=blue]vla-get-constant[/color] obj)) ([color=blue]=[/color] ([color=blue]strcase[/color] tag) ([color=blue]strcase[/color] ([color=blue]vla-get-tagstring[/color] obj))) ) ([color=blue]progn[/color] ([color=blue]if[/color] ([color=blue]vlax-property-available-p[/color] obj 'objectid32) ([color=blue]setq[/color] oid ([color=blue]vla-get-objectid32[/color] obj)) ([color=blue]setq[/color] oid ([color=blue]vla-get-objectid[/color] obj)) ) ([color=blue]if[/color] ([color=blue]vlax-method-applicable-p[/color] mld 'setblockattributevalue32) ([color=blue]vla-setblockattributevalue32[/color] mld oid val) ([color=blue]vla-setblockattributevalue[/color] mld oid val) ) ([color=blue]exit[/color]) ) ) ) ) ) ) ) ) Call the above with an MLeader vla-object, attribute tag and attribute value. Various performance improvements could be incorporated based on the methods I used in my Auto Label Attributes program. Thanks Lee, that worked perfectly! I want to make sure that I understand it all correctly. I haven't ever seen those 32 functions before, are those for 32 bit systems? Quote
Lee Mac Posted March 15, 2016 Posted March 15, 2016 Thanks Lee, that worked perfectly! You're most welcome I want to make sure that I understand it all correctly. I haven't ever seen those 32 functions before, are those for 32 bit systems? Actually, the *32 functions are for compatibility with 64-bit architecture. Quote
broncos15 Posted March 16, 2016 Author Posted March 16, 2016 Oh interesting. I'll have to look into them so more, I haven't seen any documentation for those functions. Thanks again for the help! 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.