Nomad Posted December 10, 2015 Posted December 10, 2015 Hi, I have a dwg with a bunch of the same block in it (called Cabinet). This particular block has a number of visibility states. I have assigned an attribute (called SetVisState) to the block that I can modify via ATTOUT and ATTIN. I want a LISP routine to check this attribute in each block, then update it's visibility state based on this attribute. Unfortunately I have next to no experience with LISP, so any guidance would be appreciated. I have tried looking around this forum and others, but so far have only managed to run a LISP that checks the current visibility state and then toggles between states (I need it to check attribute value then change vis state accordingly). I tried Lee Macs code for getting attributes, but couldn't figure out how to apply that to my scenario either. Thanks in advance. 1 Quote
iconeo Posted December 10, 2015 Posted December 10, 2015 Lee Mac has some helper functions on his website for manipulating the visibility states of blocks. 1 Quote
Lee Mac Posted December 10, 2015 Posted December 10, 2015 Consider the following example: (defun c:test ( / i o s ) (if (setq s (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "`*U*,Cabinet")))) (repeat (setq i (sslength s)) (setq o (vlax-ename->vla-object (ssname s (setq i (1- i))))) (if (and (vlax-property-available-p o 'effectivename) (= "cabinet" (strcase (vla-get-effectivename o) t)) ) (if (setq v (LM:vl-getattributevalue o "SetVisState")) (LM:setvisibilitystate o v) ) ) ) ) (princ) ) (vl-load-com) (princ) You will need to first download & load the required attribute & dynamic block functions from my site. @iconeo, thank you for the recommendation 1 Quote
Nomad Posted December 11, 2015 Author Posted December 11, 2015 Thanks for the responses. Lee, I haven't been able to get that code to work yet. I copied the code above into a text file and renamed it Test.LSP. I then copied all of the subfunctions from the two links you provided beneath the provided code in the Test.LSP file. I dragged and dropped this file into the dwg. I typed Test in the command line. Literally nothing happens haha. Am I doing something obviously wrong? Or should I start learning how to debug LISP haha. Thanks again for your help. 1 Quote
Lee Mac Posted December 11, 2015 Posted December 11, 2015 No problem - the following updated code will print a number of messages to the command-line to let you know what's going on: (defun c:test ( / i o s ) (if (setq s (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "`*U*,Cabinet")))) (repeat (setq i (sslength s)) (setq o (vlax-ename->vla-object (ssname s (setq i (1- i))))) (if (and (vlax-property-available-p o 'effectivename) (= "cabinet" (strcase (vla-get-effectivename o) t)) ) (progn (princ (strcat "\nFound cabinet block \"" (vla-get-handle o) "\".")) (if (setq v (LM:vl-getattributevalue o "SetVisState")) (progn (princ (strcat "\nValue of \"SetVisState\" attribute = " v)) (if (LM:setvisibilitystate o v) (princ (strcat "\nVisibility state set to \"" v "\".")) (princ (strcat "\nUnable to set visibility state to \"" v "\".")) ) ) (princ "\n\"SetVisState\" attribute not found in Cabinet block.") ) ) ) ) (princ "\nNo attributed 'Cabinet' blocks found in the drawing.") ) (princ) ) (vl-load-com) (princ) 1 Quote
Nomad Posted December 14, 2015 Author Posted December 14, 2015 Thanks Lee. I am still getting nothing. I have copied the following code from your reply above, and the subfunctions from the links you provided above, into a single .LSP file named "Test.LSP". I've dragged and dropped this into the dwg. I then type "Test" in the command line. All that shows up in the command line once is as follows: Command: (LOAD "C:/Users/.../Desktop/Data Extract/Test.LSP") LM:SETVISIBILITYSTATE Command: TEST (defun c:test ( / i o s ) (if (setq s (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "`*U*,Cabinet")))) (repeat (setq i (sslength s)) (setq o (vlax-ename->vla-object (ssname s (setq i (1- i))))) (if (and (vlax-property-available-p o 'effectivename) (= "cabinet" (strcase (vla-get-effectivename o) t)) ) (progn (princ (strcat "\nFound cabinet block \"" (vla-get-handle o) "\".")) (if (setq v (LM:vl-getattributevalue o "SetVisState")) (progn (princ (strcat "\nValue of \"SetVisState\" attribute = " v)) (if (LM:setvisibilitystate o v) (princ (strcat "\nVisibility state set to \"" v "\".")) (princ (strcat "\nUnable to set visibility state to \"" v "\".")) ) ) (princ "\n\"SetVisState\" attribute not found in Cabinet block.") ) ) ) ) (princ "\nNo attributed 'Cabinet' blocks found in the drawing.") ) (princ) ) (vl-load-com) (princ) ;; Get Attribute Value - Lee Mac ;; Returns the value held by the specified tag within the supplied block, if present. ;; blk - [vla] VLA Block Reference Object ;; tag - [str] Attribute TagString ;; Returns: [str] Attribute value, else nil if tag is not found. (defun LM:vl-getattributevalue ( blk tag ) (setq tag (strcase tag)) (vl-some '(lambda ( att ) (if (= tag (strcase (vla-get-tagstring att))) (vla-get-textstring att))) (vlax-invoke blk 'getattributes) ) ) ;; 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) ) ) ;; Set Attribute Values - Lee Mac ;; Sets attributes with tags found in the association list to their associated values. ;; blk - [vla] VLA Block Reference Object ;; lst - [lst] Association list of ((<tag> . <value>) ... ) ;; Returns: nil (defun LM:vl-setattributevalues ( blk lst / itm ) (foreach att (vlax-invoke blk 'getattributes) (if (setq itm (assoc (vla-get-tagstring att) lst)) (vla-put-textstring att (cdr itm)) ) ) ) ;; Get Attributes - Lee Mac ;; Returns an association list of attributes present in the supplied block. ;; blk - [vla] VLA Block Reference Object ;; Returns: [lst] Association list of ((<Tag> . <Value>) ... ) (defun LM:vl-getattributes ( blk ) (mapcar '(lambda ( att ) (cons (vla-get-tagstring att) (vla-get-textstring att))) (vlax-invoke blk 'getattributes) ) ) ;; Get Dynamic Block Property Value - Lee Mac ;; Returns the value of a Dynamic Block property (if present) ;; blk - [vla] VLA Dynamic Block Reference object ;; prp - [str] Dynamic Block property name (case-insensitive) (defun LM:getdynpropvalue ( blk prp ) (setq prp (strcase prp)) (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'value))) (vlax-invoke blk 'getdynamicblockproperties) ) ) ;; Set Dynamic Block Property Value - Lee Mac ;; Modifies the value of a Dynamic Block property (if present) ;; blk - [vla] VLA Dynamic Block Reference object ;; prp - [str] Dynamic Block property name (case-insensitive) ;; val - [any] New value for property ;; Returns: [any] New value if successful, else nil (defun LM:setdynpropvalue ( blk prp val ) (setq prp (strcase prp)) (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (progn (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x)))) (cond (val) (t)) ) ) ) (vlax-invoke blk 'getdynamicblockproperties) ) ) ;; Get Dynamic Block Properties - Lee Mac ;; Returns an association list of Dynamic Block properties & values. ;; blk - [vla] VLA Dynamic Block Reference object ;; Returns: [lst] Association list of ((<prop> . <value>) ... ) (defun LM:getdynprops ( blk ) (mapcar '(lambda ( x ) (cons (vla-get-propertyname x) (vlax-get x 'value))) (vlax-invoke blk 'getdynamicblockproperties) ) ) ;; Set Dynamic Block Properties - Lee Mac ;; Modifies values of Dynamic Block properties using a supplied association list. ;; blk - [vla] VLA Dynamic Block Reference object ;; lst - [lst] Association list of ((<Property> . <Value>) ... ) ;; Returns: nil (defun LM:setdynprops ( blk lst / itm ) (setq lst (mapcar '(lambda ( x ) (cons (strcase (car x)) (cdr x))) lst)) (foreach x (vlax-invoke blk 'getdynamicblockproperties) (if (setq itm (assoc (strcase (vla-get-propertyname x)) lst)) (vla-put-value x (vlax-make-variant (cdr itm) (vlax-variant-type (vla-get-value x)))) ) ) ) ;; Get Dynamic Block Property Allowed Values - Lee Mac ;; Returns the allowed values for a specific Dynamic Block property. ;; blk - [vla] VLA Dynamic Block Reference object ;; prp - [str] Dynamic Block property name (case-insensitive) ;; Returns: [lst] List of allowed values for property, else nil if no restrictions (defun LM:getdynpropallowedvalues ( blk prp ) (setq prp (strcase prp)) (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'allowedvalues))) (vlax-invoke blk 'getdynamicblockproperties) ) ) ;; Toggle Dynamic Block Flip State - Lee Mac ;; Toggles the Flip parameter if present in a supplied Dynamic Block. ;; blk - [vla] VLA Dynamic Block Reference object ;; Return: [int] New Flip Parameter value (defun LM:toggleflipstate ( blk ) (vl-some '(lambda ( prp / rtn ) (if (equal '(0 1) (vlax-get prp 'allowedvalues)) (progn (vla-put-value prp (vlax-make-variant (setq rtn (- 1 (vlax-get prp 'value))) vlax-vbinteger)) rtn ) ) ) (vlax-invoke blk 'getdynamicblockproperties) ) ) ;; Get Visibility Parameter Name - Lee Mac ;; Returns the name of the Visibility Parameter of a Dynamic Block (if present) ;; blk - [vla] VLA Dynamic Block Reference object ;; Returns: [str] Name of Visibility Parameter, else nil (defun LM:getvisibilityparametername ( blk / vis ) (if (and (vlax-property-available-p blk 'effectivename) (setq blk (vla-item (vla-get-blocks (vla-get-document blk)) (vla-get-effectivename blk) ) ) (= :vlax-true (vla-get-isdynamicblock blk)) (= :vlax-true (vla-get-hasextensiondictionary blk)) (setq vis (vl-some '(lambda ( pair ) (if (and (= 360 (car pair)) (= "BLOCKVISIBILITYPARAMETER" (cdr (assoc 0 (entget (cdr pair))))) ) (cdr pair) ) ) (dictsearch (vlax-vla-object->ename (vla-getextensiondictionary blk)) "ACAD_ENHANCEDBLOCK" ) ) ) ) (cdr (assoc 301 (entget vis))) ) ) ;; Get Dynamic Block Visibility State - Lee Mac ;; Returns the value of the Visibility Parameter of a Dynamic Block (if present) ;; blk - [vla] VLA Dynamic Block Reference object ;; Returns: [str] Value of Visibility Parameter, else nil (defun LM:getvisibilitystate ( blk ) (LM:getdynpropvalue blk (LM:getvisibilityparametername blk)) ) ;; Set Dynamic Block Visibility State - Lee Mac ;; Sets the Visibility Parameter of a Dynamic Block (if present) to a specific value (if allowed) ;; blk - [vla] VLA Dynamic Block Reference object ;; val - [str] Visibility State Parameter value ;; Returns: [str] New value of Visibility Parameter, else nil (defun LM:SetVisibilityState ( blk val / vis ) (if (and (setq vis (LM:getvisibilityparametername blk)) (member (strcase val) (mapcar 'strcase (LM:getdynpropallowedvalues blk vis))) ) (LM:setdynpropvalue blk vis val) ) ) 1 Quote
Lee Mac Posted December 14, 2015 Posted December 14, 2015 Are you certain that is the full command-line output? What happens if you press F2 to view the text window? Quote
Nomad Posted December 15, 2015 Author Posted December 15, 2015 Lee, I checked through everything again and it turns out I had actually named the block "Cabient" Thanks so much for your help - it works perfectly. 1 Quote
morgancain Posted April 18, 2018 Posted April 18, 2018 Hi, Sorry for hijacking an old thread, I would like to achieve the same as the OP. I have copied the code and changed all instances of the OP's block reference (Cabinet) so it calls for my block (Revision Table) however it doesn't work. When I then rename my block to be called cabinet it works perfectly. So I am clearly missing something, would someone be able to assist with this please as its driving me mad. Thanks! 1 Quote
Roy_043 Posted April 18, 2018 Posted April 18, 2018 Make sure that on this line the block name is lower case: (= "cabinet" (strcase (vla-get-effectivename o) t)) Quote
morgancain Posted April 18, 2018 Posted April 18, 2018 That has worked a treat! Thank you very much! Quote
Ecko Posted June 30, 2020 Posted June 30, 2020 Hi Lee, I know the threat is old... but the problem is still there. :-) Maybe you can help me! I created an block named 'cabinet' with an attribute "SetVisState" with two values: state1 und state2 Then I drag an droped the test.lsp with the code up there into my DWG and I got the following messages: Command:(LOAD "C:/.../Desktop/test.lsp") Command: LM:SETVISIBILITYSTATE Command:test Found cabinet block "44D4". Value of "SetVisState" attribute = State2 Unable to set visibility state to "State2". Hm... what went wrong? Thanks for help! Ecko Quote
Lee Mac Posted June 30, 2020 Posted June 30, 2020 To get the obvious question out of the way, I assume that your block 'Cabinet' has a Visibility Parameter with a Visibility State called 'State2'? Quote
Ecko Posted June 30, 2020 Posted June 30, 2020 Yo that's right. Visibility Parameter with a Visibility State called 'State2' and another one with 'State1' Quote
Ecko Posted July 1, 2020 Posted July 1, 2020 Maybe I did not understand how to use it!? (My english is bad.) Quote
dlanorh Posted July 2, 2020 Posted July 2, 2020 Upload an example of your block so everyone knows what they are dealing with. It is near impossible to correctly diagnose a problem without seeing the "patient" Quote
dlanorh Posted July 2, 2020 Posted July 2, 2020 (edited) The problem is the block is called "circle", not "cabinet". Either rename the block "cabinet" or change every instance of "cabinet" to "circle" in the lisp. Just noticed you have a "cabinet" block. When this is used the lisp works. If you don't have all the required "bits", I've attached a complete lisp and your drawing set up to test. test1.dwg test.lsp Edited July 2, 2020 by dlanorh attachments 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.