TheyCallMeJohn Posted June 21, 2013 Posted June 21, 2013 Hello All, I have a lisp for making a series of modifications one dynamic block at time. I have the lisp working but it errors out when a non-dynamic block is selected. My goal is to create a while loop that keeps looping until the user selects a dynamic block (or preferably matching a certain name.) I am not sure how to write the check... Here is an excerpt from the code. (vl-load-com) (setq acadDocument (vla-get-activedocument(vlax-get-acad-object))) (setq RX (entsel)) (setq oBkRef (vlax-Ename->Vla-Object (car RX))) Quote
BlackBox Posted June 21, 2013 Posted June 21, 2013 You should consider using SSGET in lieu of ENTSEL, as it will allow you to enter the appropriate selection set filter to catch both anonymous and actual named dynamic blocks. Additionally, you'll need to iterate the Block Collection to compile a list of dynamic BlockDefinition Names based upon an IF statement filtering for vla-Get-IsDynamicBlock == :vlax-true. That will allow you to check the EffectiveName of the BlockReference selected against the list of Dynamic BlockDefinition Names. Cheers Quote
Tharwat Posted June 21, 2013 Posted June 21, 2013 To prove what BB 's just said with codes , here is my try . To the OP , Replace the variable Blockname with your dynamic block name . (while (or (not (setq s (ssget "_+.:S" '((0 . "INSERT"))))) (not (eq (vla-get-effectivename (vlax-ename->vla-object (ssname s 0)) ) [color=blue] Blockname[/color] ) ) ) (princ "Nil or Wrong Selection !!") ) Quote
BlackBox Posted June 21, 2013 Posted June 21, 2013 ... A lil'somethin for testing purposes: (vl-load-com) (defun c:BlockIs (/ ss oBlocks blockName) (while (setq ss (ssget ":S:E" '((0 . "INSERT")))) (prompt (if (= :vlax-true (vla-get-isdynamicblock (vla-item (cond (oBlocks) ((setq oBlocks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object) ) ) ) ) ) (setq blockName (vla-get-effectivename (vlax-ename->vla-object (ssname ss 0) ) ) ) ) ) ) (strcat "\n\"" blockName "\" is dynamic block ") (strcat "\n\"" blockName "\" is not dynamic block ") ) ) ) (princ) ) Quote
TheyCallMeJohn Posted June 25, 2013 Author Posted June 25, 2013 Blackbox & Tharwat, Thank you both for your help. I am pretty sure I can get this to work though I haven't been able to get it to work for checking against multiple names. For example if I have BLOCK1, BLOCK2, BLOCK3, BLOCK4, & BLOCK5, I only want it to work if BLOCK1 or BLOCK3 is selected. I tried a few solutions but alas they did not work... (defun C:block_check () (while (or (not (setq s (ssget "_+.:S" '((0 . "INSERT"))))) (not (eq (vla-get-effectivename (vlax-ename->vla-object (ssname s 0)) ) "BLOCK1" ) ) (not (eq (vla-get-effectivename (vlax-ename->vla-object (ssname s 0)) ) "BLOCK3" ) ) ) (princ "Nil or Wrong Selection !!") ) (princ "Good choice") ) Quote
Tharwat Posted June 26, 2013 Posted June 26, 2013 Try this instead . (defun c:block_check (/ s vla) (while (or (not (setq s (ssget "_+.:S" '((0 . "INSERT"))))) (not (or (eq (strcase (vla-get-effectivename (setq vla (vlax-ename->vla-object (ssname s 0))) ) ) "BLOCK1" ) (eq (strcase (vla-get-effectivename vla ) ) "BLOCK3" ) ) ) ) (princ "Nil or Wrong Selection !!") ) (princ "\nGood choice") (princ) ) Quote
pBe Posted June 26, 2013 Posted June 26, 2013 Blackbox & Tharwat,Thank you both for your help. I am pretty sure I can get this to work though I haven't been able to get it to work for checking against multiple names. For example if I have BLOCK1, BLOCK2, BLOCK3, BLOCK4, & BLOCK5, I only want it to work if BLOCK1 or BLOCK3 is selected. Something odd about your request. if you already know the name of the block I can assume you know its a Dynamic block. Then all you really need is (ssget ":S:E" '((0 . "INSERT")(2 . Block1,Block2,`*U*"))) and a test for effectivename to check if its a match for the names you specify. Quote
TheyCallMeJohn Posted June 26, 2013 Author Posted June 26, 2013 (edited) Tharwat, this didn't seem to work... I kept getting the error for for "Nil or Wrong Selection !!". Try this instead . (defun c:block_check (/ s vla) (while (or (not (setq s (ssget "_+.:S" '((0 . "INSERT"))))) (not (or (eq (strcase (vla-get-effectivename (setq vla (vlax-ename->vla-object (ssname s 0))) ) ) "BLOCK1" ) (eq (strcase (vla-get-effectivename vla ) ) "BLOCK3" ) ) ) ) (princ "Nil or Wrong Selection !!") ) (princ "\nGood choice") (princ) ) Pbe, I ran this as a test: (setq x (ssget ":S:E" '((0 . "INSERT")(2 . "BLOCK1","BLOCK3",`*U*")))) I received this in response: ; "error: extra cdrs in dotted pair on input" All, Does anyone have any information about the filtering of ssget or a tutorial. I found these on CADPANACEA.com (Exploring the autolisp SSGET function - part 1 & part 2) but they didn't relate to dynamic blocks. The Autocad wasn't much help either. An Autolisp wiki would be nice... Edited June 26, 2013 by TheyCallMeJohn Misspelled name. Quote
Tharwat Posted June 26, 2013 Posted June 26, 2013 this didn't seem to work... I kept getting the error for for "Nil or Wrong Selection !!". Firstly , you did write me name wrongly . Secondly , are you selecting the right name block with Block1 or Block3 ? Does anyone have any information about the filtering of ssget or a tutorial. I found these on CADPANACEA.com (Exploring the autolisp SSGET function - part 1 & part 2) but they didn't relate to dynamic blocks. The Autocad wasn't much help either. An Autolisp wiki would be nice... Maybe the following filter to select Dynamic Block only . (setq ss (ssget (list '(0 . "INSERT") (cons 2 (strcat "`*U*," "Block1,Block3"))))) Quote
alanjt Posted June 26, 2013 Posted June 26, 2013 (edited) (defun _selectOnlyListedBlocks (listOfBlockNames / lst ent block) (setq lst (mapcar 'strcase (setq listOfBlockNames (vl-sort listOfBlockNames '<)))) (while (progn (setvar 'ERRNO 0) (setq ent (entsel (if (eq (length listOfBlockNames) 1) (strcat "\nSelect " (car listOfBlockNames) " block: ") (strcat "\nAcceptable blocks: " (vl-prin1-to-string listOfBlockNames) "\nSelect matching block: " ) ) ) ) (cond ((eq (getvar 'ERRNO) 7) (princ "\nMissed, try again.")) ((eq (type (car ent)) 'ENAME) (if (and (eq (cdr (assoc 0 (entget (car ent)))) "INSERT") (member (strcase (vla-get-effectivename (setq ent (vlax-ename->vla-object (car ent))))) lst ) ) (not (setq block ent)) (princ "\nInvalid object!") ) ) ) ) ) block ) eg. (_selectOnlyListedBlocks '("Block1" "Block 3")) Edited July 1, 2013 by alanjt Quote
BlackBox Posted June 26, 2013 Posted June 26, 2013 FWIW - This post may be of use. As I tried to suggest previously by sharing the link above, this sub-function requires two arguments, the first being the Document Object to search (which makes this available for use with ObjectDBX), and the second a WCMATCH string of block name(s) to match... A list of any matching dynamic BlockReference Object(s) is returned if found: (vl-load-com) (defun _GetDynamicBlocks (doc match / oBlocks blockName blocks) ;; Example: ;; (_GetDynamicBlocks acDoc "*MyBlockName*") (if (and (setq oBlocks (vla-get-blocks doc)) (setq match (strcase match)) ) (foreach space (list (vla-get-modelspace doc) (vla-get-paperspace doc)) (vlax-for x space (if (and (= "AcDbBlockReference" (vla-get-objectname x)) (wcmatch (strcase (setq blockName (vla-get-effectivename x))) match ) (= :vlax-true (vla-get-isdynamicblock (vla-item oBlocks blockName) ) ) ) (setq blocks (cons x blocks)) ) ) ) ) blocks ) ... And for those that would rather not be relegated to dynamic block returns (given the Block name argument(s)): (vl-load-com) (defun _GetBlocks (doc match / oBlocks blockName blocks) ;; Example: ;; (_GetBlocks acDoc "*MyBlockName*") (if (and (setq oBlocks (vla-get-blocks doc)) (setq match (strcase match)) ) (foreach space (list (vla-get-modelspace doc) (vla-get-paperspace doc)) (vlax-for x space (if (and (= "AcDbBlockReference" (vla-get-objectname x)) (wcmatch (strcase (setq blockName (vla-get-effectivename x))) match ) ) (setq blocks (cons x blocks)) ) ) ) ) blocks ) Quote
TheyCallMeJohn Posted June 28, 2013 Author Posted June 28, 2013 Blackbox, I apologize, I had not made time to fully review the post you suggested before my last post. Since then I reviewed the information you posted and that appears to be for selecting all the dynamic blocks in a given drawing. Much of the code was far above my current skill level. But if am correct, this is not exactly what I am looking for as I only want to select on of the blocks with that name. As I tried to suggest previously by sharing the link above, this sub-function requires two arguments, the first being the Document Object to search (which makes this available for use with ObjectDBX), and the second a WCMATCH string of block name(s) to match... A list of any matching dynamic BlockReference Object(s) is returned if found: --------------- Tharwat, Sorry for the misspelling. I found the issue but am not sure how to modify it. Your programming works for the parameters I listed (i.e. dynamic blocks named BLOCK1, BLOCK2, BLOCK3, etc) however I was only using those names as examples. I does not work with my actual block names which are similar to "Brace-Rigid-Xdata-OLD". I didn't realize it would make a difference. Is there way to make it work with those type of names? This works: (setq ss (ssget (list '(0 . "INSERT") (cons 2 (strcat "`*U*," "Block1,Block3"))))) ...But is there away to tweak it so you don't have to hit enter after selecting the objects? ----------------- Alanjt, I really like your sub-function but alas I am having the same problem as I did with Tharwat suggestion. It works great with simple names like "BLOCK1" but doesn't work with longer names like "Brace-Rigid-Xdata-OLD". ----------------- All, Thank you for you help. I am trying to learn as quickly as I am able. I appreciate your patience. Quote
alanjt Posted July 1, 2013 Posted July 1, 2013 Alanjt, I really like your sub-function but alas I am having the same problem as I did with Tharwat suggestion. It works great with simple names like "BLOCK1" but doesn't work with longer names like "Brace-Rigid-Xdata-OLD". That's because I'm a moron who doesn't capitalize the effective name before comparing it to a list of names that I capitalized. I have revised the code. Try it now. Quote
BlackBox Posted July 1, 2013 Posted July 1, 2013 Blackbox,I apologize, I had not made time to fully review the post you suggested before my last post. Since then I reviewed the information you posted and that appears to be for selecting all the dynamic blocks in a given drawing. Much of the code was far above my current skill level. But if am correct, this is not exactly what I am looking for as I only want to select on of the blocks with that name. Ahhh... Now worries; I didn't think my post would have been necessarily perfect for your situation, just that you could cull from it what you like. We all start somewhere, and I see Alan's on the case, so I'll gladly go back to what I was doing... I'm sure I'll see you around. Quote
TheyCallMeJohn Posted July 2, 2013 Author Posted July 2, 2013 That's because I'm a moron who doesn't capitalize the effective name before comparing it to a list of names that I capitalized. I have revised the code. Try it now. Thanks Alanjt. That worked like a charm. Quote
alanjt Posted July 2, 2013 Posted July 2, 2013 Thanks Alanjt. That worked like a charm. You're welcome. 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.