PDuMont Posted July 24, 2019 Posted July 24, 2019 (edited) Hello All, Long time no post, but I visit often. I have a routine that updates constant attributes nicely. I have 1000's of blocks to update and while what I have is working, it is failing on dynamic blocks' block definition, although it works on dynamic blocks' block reference. I have looked at using effective name as well as LeeMac's dynamic properties subroutines, but am failing to grasp an elegant and efficient way to accomplish what I need. Any ideas or pointers in the right direction would be appreciated. Edit, I know I can reset the blocks before updating the attributes, but I don't necessarily want that. (defun C:AttMod (/ doc x att catt ans) (vl-load-com) (setq doc (vla-get-activedocument (vlax-get-acad-object))) (vla-startundomark doc) (CatPrompt) (cond ((ssget (list (cons 0 "INSERT"))) (vlax-for item (vla-get-ActiveSelectionSet doc) (cond ((= (vla-get-HasAttributes item) :vlax-true) (setq catt (variant-value (vla-getconstantattributes item))) (foreach x (safearray-value catt) (and (= (vla-get-tagstring x) "CATEGORY") (vla-put-textstring x ans) ) ;_ end of and ) ;_ end of foreach (vla-update item) ) ((alert "\nNo CATEGORY attribute in selection.")) ) ;_ end of cond ) ;_ end of vlax-for ) ) ;_ end of cond (vla-endundomark doc) (princ) ) ;_ end of defun (defun CatPrompt () (initget "A-MTL B-ACC C-DOOR D-LGHT E-TOP F-SHLF G-GPAN H-PAN I-OVRLY J-CPAN K-MISC" ) ;_ end of initget (setq ans (getkword "Select new category for blocks: \n [A-MTL/B-ACC/C-DOOR/D-LGHT/E-TOP/F-SHLF/G-GPAN/H-PAN/I-OVRLY/J-CPAN/K-MISC]: <A> " ) ;_ end of getkword ) ;_ end of setq (if (not ans) (setq ans "A-MTL") ) ;_ end of if ) ;_ end of defu Edited July 24, 2019 by PDuMont Quote
dlanorh Posted July 24, 2019 Posted July 24, 2019 You need to interate the block definitions. Try this (defun C:AttMod (/ doc blks b_name b_def x att catt ans b_lst) (vl-load-com) (setq doc (vla-get-activedocument (vlax-get-acad-object)) blks (vla-get-blocks doc) ) (vla-startundomark doc) (CatPrompt) (cond ( (ssget (list (cons 0 "INSERT"))) (vlax-for item (vla-get-ActiveSelectionSet doc) (setq bname (vlax-get-property obj (if (vlax-property-available-p obj 'effectivename) 'effectivename 'name)) b_def (vla-item blks bname) ) (cond ( (= (vla-get-HasAttributes item) :vlax-true) (setq catt (variant-value (vla-getconstantattributes item))) (foreach x (safearray-value catt) (and (= (vla-get-tagstring x) "CATEGORY") (vla-put-textstring x ans) ) ;_ end of and ) ;_ end of foreach (vla-update item) ) ((alert "\nNo CATEGORY attribute in selection.")) ) ;_ end of cond (cond ( (and (= :vlax-false (vlax-get-property b_def 'islayout)) (= :vlax-false (vlax-get-property b_def 'isxref)) (not (wcmatch bname "*|*")) (= :vlax-true (vlax-get-property b_def 'isdynamicblock)) );end_and (vlax-for obj b_def (cond ( (and (= (vlax-get-property obj 'objectname) "AcDbAttributeDefinition") (= (vlax-get-property obj 'tagstring) "CATEGORY") (/= (vlax-get-property obj 'textstring) ans) );end_and (vla-put-property obj 'textstring ans) ) );end_cond );end_for ) );end_cond ) ;_ end of vlax-for ) ) ;_ end of cond (vla-endundomark doc) (princ) ) ;_ end of defun (defun CatPrompt () (initget "A-MTL B-ACC C-DOOR D-LGHT E-TOP F-SHLF G-GPAN H-PAN I-OVRLY J-CPAN K-MISC" ) ;_ end of initget (setq ans (getkword "Select new category for blocks: \n [A-MTL/B-ACC/C-DOOR/D-LGHT/E-TOP/F-SHLF/G-GPAN/H-PAN/I-OVRLY/J-CPAN/K-MISC]: <A> " ) ;_ end of getkword ) ;_ end of setq (if (not ans) (setq ans "A-MTL") ) ;_ end of if ) ;_ end of defu Quote
PDuMont Posted July 24, 2019 Author Posted July 24, 2019 Thanks for the reply dlanorh. You had a couple miscues in the vlax-for item: (vlax-for item (vla-get-ActiveSelectionSet doc) (setq bname (vlax-get-property obj (if (vlax-property-available-p obj 'effectivename) 'effectivename 'name)) b_def (vla-item blks bname) ) When I updated that, the values returned were correct: (vlax-for item (vla-get-ActiveSelectionSet doc) (setq bname (vlax-get-property item (if (vlax-property-available-p item 'effectivename) 'effectivename 'name)) b_def (vla-item blks bname) ) However, I believe there is no vla-put-property as no function definition was returned. That seems like the right way to go though. Quote
dlanorh Posted July 24, 2019 Posted July 24, 2019 3 hours ago, PDuMont said: Thanks for the reply dlanorh. You had a couple miscues in the vlax-for item: (vlax-for item (vla-get-ActiveSelectionSet doc) (setq bname (vlax-get-property obj (if (vlax-property-available-p obj 'effectivename) 'effectivename 'name)) b_def (vla-item blks bname) ) When I updated that, the values returned were correct: (vlax-for item (vla-get-ActiveSelectionSet doc) (setq bname (vlax-get-property item (if (vlax-property-available-p item 'effectivename) 'effectivename 'name)) b_def (vla-item blks bname) ) However, I believe there is no vla-put-property as no function definition was returned. That seems like the right way to go though. Yes, very sloppy of me That should have been vlax-put-property. I wasn't in a position to test code, but have since and it works for me in 2012. Once the lisp has run, any new insert of the dynamic block has the updated constant attribute. Can't speak for dynamic blocks with visibility states but it should work. Quote
PDuMont Posted July 25, 2019 Author Posted July 25, 2019 That did the trick dlanorh! Tested and working here as well, thank you very much. Works on blocks with visibility states as well. Where do you want me to mail your beer to? Thanks again. Quote
dlanorh Posted July 25, 2019 Posted July 25, 2019 13 minutes ago, PDuMont said: That did the trick dlanorh! Tested and working here as well, thank you very much. Works on blocks with visibility states as well. Where do you want me to mail your beer to? Thanks again. No problem 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.