Da Ballz Posted June 20, 2017 Share Posted June 20, 2017 Commandobill wrote some code awhile back. I need to tweak. The blue code below needs to be changed and I'm racking my brain. Instead of the attribute values being replaced manually, I need the value for the highest REV attribute in the REV block to go into the "REV" attribute. The code currentlyfinds the highest REV attribute but then replaces that with manual text. In place of the blue I need something like: (cb:replaceAttributeValue "REV" (the attribute value for the highest REV, example: 5 for REV5) (vlax-ename->vla-object x)) Most of the code is already here, it's just getting the cb:replaceAttributeValue function to match the attribute value of "REV" with the attribute value of the highest REV in the revblock (5 for attribute REV 5, for example). (vl-load-com) (defun c:test11 ( / blockSS blockList attName attNumber) (if (setq blockSS (ssget "X" (list (cons 0 "INSERT") (cons -4 "")))) (progn (setq blockList (mapcar 'cadr (ssnamex blockSS))) (setq attName (vla-get-tagstring (car (cb:matchAtts "REV" "REV" (vlax-ename->vla-object(car blockList)))))) (setq attNumber (substr attName (strlen attName) 1)) (mapcar '(lambda (x) (cb:replaceAttributeValue (strcat "DATE" attNumber) "29-JUN-15" (vlax-ename->vla-object x)) (cb:replaceAttributeValue (strcat "DESC" attNumber) "BASELINE UPDATE - 101/111 RENOVATIONS" (vlax-ename->vla-object x))) blockList) )) (princ) ) (defun cb:matchAtts (baseAttName attPrefix Blk / ) (setq baseAtt (car (vl-remove-if-not '(lambda (x) (= baseAttName (vla-get-tagstring x))) (cb:variantToList (vla-getattributes Blk))))) (vl-remove-if-not '(lambda (x) (and (wcmatch (vla-get-tagstring x) (strcat attPrefix "*")) (not (eq (vla-get-tagstring x) baseAttName)) (eq (vla-get-textstring x) (vla-get-textstring baseAtt)) )) (cb:variantToList (vla-getattributes Blk))) ) (defun cb:variantToList (theVariant / ) (if (= 'variant (type theVariant)) (vlax-safearray->list (vlax-variant-value theVariant)) nil ) ) ;;;;;Replace Attribute Value;;;;;;;;; ;;;;;By: CommandoBill;;;;;;;;;;;;;;;;; ;;;;;01/24/15;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;Send a block to this function with an attribute you want to replace with a new value ;;;;attName = the name of the attribute which value you want to replace ;;;;attNewVal = the new value you want in the attribute ;;;;Blk = the vla-object verision of the block which the attribute is in (defun cb:replaceAttributeValue (attName attNewVal Blk / ) (mapcar '(lambda (x) (if (= attName (vla-get-tagstring x)) (vla-put-textstring x attNewVal))) (cb:variantToList (vla-getattributes Blk))) (princ) ) Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 21, 2017 Author Share Posted June 21, 2017 (cb:replaceAttributeValue (strcat "DATE" attNumber) "29-JUN-15" (vlax-ename->vla-object x)) [code] The above code replaces the attribute value (strcat "DATE" attNumber), which could be an attribute with the tag DATE1, or DATE2, or DATE3, ect. depending on which line in the revision block has the most current revision. What I want to do is replace attribute REV with the attribute value in (strcat "REV" attNumber). For this particular title block, let's say this attribute is REV5 and the value is 12. I need to pass the value of REV5 (12) to REV so they both say 12. Currently the value of REV is most likely X by default because the routine I use to swap title blocks doesn't know what REV should be. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted June 24, 2017 Share Posted June 24, 2017 Post a dwg, two blocks Title block and Rev block ? Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 25, 2017 Author Share Posted June 25, 2017 BIG AL, Thank you kind Sir. I don't have access to the actual files at the moment, but I recreated a quick temporary title block that should be good enough for proof of concept. There is a REV attribute at the bottom right corner that shows the current drawing REV. Above that there is the REV block. It can hold 6 revisions. Each attribute is named REV1, REV2 through REV6. I currently have the drawing set at revision 5, and I have added a value of 5 to the REV5 attribute. In reality, that value could be anything since there are only 6 revisions possible, for example, the drawing could be up to revision 100 at the REV5 position, but I just kept it simple. That said, I need code that will get the latest revision or most current revision attribute value (5 at REV5 in this case) and set that same value in the REV attribute at the bottom right hand corner. I literally have thousands of drawings where the old title block didn't have the REV attribute in the bottom right hand corner. The cb:matchAtts subfunction in the code I posted at the beginning of this thread seems to work in finding the most current revision. I think what needs to be tweaked is the cb:replaceAttributeValue subfunction. Currently it replaces the value at REV with REV5, the tag name, it needs to be the actual value of the attribute (5) in this case. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted June 25, 2017 Share Posted June 25, 2017 (edited) Just started from scratch much easier. This does only 1 layout as a test but can be modified pretty easy to check all layouts. Only one errror check that you don't have more than 1 block. ; daballz lisp ; by Alan H june 2017 ; hard coded for the block (defun c:daballz ( / blockss x y atts obj tagname lookfor revtemp) (setq blockSS (ssget "X" (list (cons 0 "INSERT") (cons -4 "<xor") (cons 2 "Drawing_Sheet_22x34") (cons 2 "Drawing_Sheet_22x34-H") (cons -4 "xor>")))) (if (> 1 (setq x (sslength blockss))) ; make sure only one title block (progn (Alert "You have more than 1 title block on this page\n\nprogram will exit") (exit) ; hard coded exit not vey gracefull ) (princ "ok") ; dummy statement ) (setq obj (vlax-ename->vla-object (ssname blockss 0))) ; get the 1st obj inside the selection set (setq atts (reverse (vlax-invoke obj 'getattributes))) ; get all the attributes and convert to a list (setq x 1) (repeat (setq y (length atts )) ; loop for all attributes (setq lookfor (strcat "REV" (rtos x 2 0))) ; add a number as a string to "REV" (setq tagname (vla-get-tagstring (nth (setq y (- y 1)) atts))) ; get attribute 1 at a time (if (= tagname lookfor) ; check for match tag names (setq revtemp (vla-get-textstring (nth y atts))) ; if true set temp value repeat for highest number ) (if (and (/= revtemp "" )(< x 7)) ; double check for a blank field and no more than 6 revisions (progn (setq revval revtemp) (setq x (+ x 1)) (setq revtemp "") ; needed to make sure resets inside loop ) ) ) (setq lookfor "REV" ) ; destination tag name (repeat (setq y (length atts )) ; loop through the attributes (setq tagname (vla-get-tagstring (nth (setq y (- y 1)) atts))) ; get tagstring of a attribute (if (= tagname lookfor) ; test for match (vla-put-textstring (nth y atts) revval) ; if match change value ) ) ) (c:daballz) Edited June 27, 2017 by BIGAL Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 25, 2017 Author Share Posted June 25, 2017 My friend, truly phenomenal work. It's working for now. I'll have to tweak, but the bulk of the logic in the middle of the routine is what I was struggling with. Again, thanks. Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 25, 2017 Author Share Posted June 25, 2017 I'm now running this on my actual title blocks in AutoCAD 2014, and I'm getting the following error: Command: REVMATCH ok; error: ActiveX Server returned an error: Parameter not optional I put the code within (defun c:REVMATCH ( / ) ) and added a (vl-load-com), but I'm still getting this error. Any ideas? It was working on AutoCAD 2015 with the mock block that had the exact same block name and attribute tag names... Quote Link to comment Share on other sites More sharing options...
BIGAL Posted June 26, 2017 Share Posted June 26, 2017 I have edited code above it to match your REVMATCH and checked against you sample dwg. Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 26, 2017 Author Share Posted June 26, 2017 The block name and attribute names are identical, but does it matter if the block has other properties and other attributes that aren't included in the sample drawing? I will send you the actual title block as soon as I get a chance. Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 26, 2017 Author Share Posted June 26, 2017 Here is the working title block. I may be having issues with my vcom.dll as well, working that now. If you run it on this one and it works...let me know. Also, I'm running AutoCAD 2014. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted June 26, 2017 Share Posted June 26, 2017 Very simple your rev block does not have anything in it, we would do something like PA for Preliminary "A" or maybe "-1" for work in progress. The code uses if blank then stop. Quote Link to comment Share on other sites More sharing options...
SLW210 Posted June 26, 2017 Share Posted June 26, 2017 Please read the Code Posting Guidelines and edit your Code to be included in Code Tags.[NOPARSE] Your Code Here[/NOPARSE] = Your Code Here Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 27, 2017 Author Share Posted June 27, 2017 I tried the routine on a title block with all of the attributes filled in. I still get the error: Command: REMATCH ok; error: Activex Server returned an error: Parameter not optional I debugged in Vlide, but there is no obvious issue with syntax or anything. The last break was on the following line: setq obj (vlax-ename->vlaobject (ssname blockss 0))) This is what made me think there was an issue with the vl library/activex plugin/app. But all of my other routines seem to be working fine, and they include visual lisp...so... Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 27, 2017 Author Share Posted June 27, 2017 Forgot the left ( in that code, it's there...so that isn't the problem. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted June 27, 2017 Share Posted June 27, 2017 (edited) Its very weird maybe a hidden character somewhere in code will find it. Found the mistake (setq revtemp "") See code update above so simple somewhere between testing, saving and copying dropped a line. Edited June 27, 2017 by BIGAL Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 27, 2017 Author Share Posted June 27, 2017 That did the trick my friend. Looks like it's good to go. Stupid question, how would I add one more title block to look for? There are actually 3 title different title blocks. I tried to simply add (cons 2 "Drawing_Sheet_Vendor") How do the (cons -4 "") pieces work? Would I just change the parameters associated with "cons" so I can add the third, or do I need to rewrite the ssget for the main block list? Quote Link to comment Share on other sites More sharing options...
ronjonp Posted June 27, 2017 Share Posted June 27, 2017 (edited) That did the trick my friend. Looks like it's good to go. Stupid question, how would I add one more title block to look for? There are actually 3 title different title blocks. I tried to simply add (cons 2 "Drawing_Sheet_Vendor") How do the (cons -4 "") pieces work? Would I just change the parameters associated with "cons" so I can add the third, or do I need to rewrite the ssget for the main block list? You could simplify your filter to this: (setq blockss (ssget "X" '((0 . "INSERT") (2 . "Drawing_Sheet_*")))) to grab all blocks starting with Drawing_Sheet_. Edited June 28, 2017 by ronjonp Quote Link to comment Share on other sites More sharing options...
Da Ballz Posted June 28, 2017 Author Share Posted June 28, 2017 I was going through some routines which I'm compiling in scripts and I ran into that exact same code in another lisp. Thanks! Gets the job done. Quote Link to comment Share on other sites More sharing options...
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.