This is a new thread to get a final solution instead of trolling another user's thread.
I've been getting help from @hmsilva who has helped create a routine to list all the dyanmic blocks in my drawing with a specific visibilty parameter name. The problem with the blocks that I'm trying to search for in my draiwng is that the visibility names are very similar with the only differences being CASE sensitivity (ie. OBJECT vs. Object). I'm very new to LISP so any help is greatly appreciated. Thanks in Advance.
Chris
(defun c:test (/ BNAME DATA E I PNAME SS VIS) (if (setq data nil vis (getstring T "\nEnter the Visibility Parameter Name: ") ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 "`*U*") ) ) ) ;; setq (progn (repeat (setq i (sslength ss)) (cond ((and (setq bname (vla-get-EffectiveName (setq e (vlax-ename->vla-object (ssname ss (setq i (1- i)) ) ) ) ) ) (setq Pname (car (vl-remove-if-not '(lambda (j) (eq (strcase (vla-get-PropertyName j)) (strcase vis) ) ) (vlax-invoke e 'GetDynamicBlockProperties) ) ) ) (not (member bname data)) ) (setq data (cons bname data)) (foreach itm data (print itm)) ) );; cond );; repeat );; progn );; if (if (null data) (princ "\nBlock/Parameter Name not found")) (princ) )
Solved! Go to Solution.
Solved by Lee_Mac. Go to Solution.
Chris,
in order to make this "demo" case sensitive, just change
(eq (strcase (vla-get-PropertyName j)) (strcase vis))
to
(eq (vla-get-PropertyName j) vis)
Look at the strcase function...
HTH
Henrique
If I have understood the task correctly, I would suggest the following:
(defun c:test ( / bln idx lst obj par rtn sel ) (cond ( (= "" (setq par (strcase (getstring t "\nEnter parameter name: "))))) ( (or (null (setq sel (ssget "_X" '((0 . "INSERT"))))) (progn (repeat (setq idx (sslength sel)) (if (and (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx))))) (vlax-property-available-p obj 'isdynamicblock) (= :vlax-true (vla-get-isdynamicblock obj)) (setq bln (vla-get-effectivename obj)) (not (member bln lst)) ) (progn (if (vl-some '(lambda ( p ) (= par (strcase (vla-get-propertyname p)))) (vlax-invoke obj 'getdynamicblockproperties) ) (setq rtn (cons bln rtn)) ) (setq lst (cons bln lst)) ) ) ) (null rtn) ) ) (princ (strcat "\nNo dynamic blocks found with parameter \"" par "\"")) ) ( (foreach blk rtn (print blk))) ) (princ) ) (vl-load-com) (princ)
@paduch_chris wrote:
This is a new thread to get a final solution instead of trolling another user's thread.
@I've been getting help from @hmsilva who has helped create a routine to list all the dyanmic blocks in my drawing with a specific visibilty parameter name. The problem with the blocks that I'm trying to search for in my draiwng is that the visibility names are very similar with the only differences being CASE sensitivity (ie. OBJECT vs. Object). I'm very new to LISP so any help is greatly appreciated. Thanks in Advance.
Chris
Are you just after a "list" of DB's with target Visibility name? Or you need to process the blocks as well?
For the first option :
This approach searches the block table definiton rather than block entities
(defun c:DEmo (/ blocks parname a blk Bnames dbp par) ;;; idea taken from LMs' LM:getvisibilityparametername function ;;; ;; pBe Dec2013 ;;; (setq blocks (vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object)))) (if (and (setq Bnames nil parname (strcase (getstring t "\nEnter parameter name: "))) (while (setq a (tblnext "BLOCK" (null a))) (setq blk (vla-item Blocks (setq bn (Cdr (assoc 2 a))))) (if (and (setq dbp (dictsearch (vlax-vla-object->ename (vla-getextensiondictionary blk)) "ACAD_ENHANCEDBLOCK" )) (setq dbp (assoc 360 dbp)) (= "BLOCKVISIBILITYPARAMETER" (cdr (assoc 0 (setq ent (Entget (Cdr dbp)))))) (wcmatch (Strcase (setq par (cdr (assoc 301 ent)))) (strcase parname)) ) (setq Bnames (cons bn Bnames)) Bnames));while ) (foreach bnm Bnames (print bnm)) (princ (strcat "\nNo dynamic blocks found with parameter \"" parname "\"")) ) (princ) )
Holler If you need to process the blocks than just making list Chris
HTH
Great idea pbejse! - and thank you for the attribution.
The code could also be written without using ActiveX, e.g.:
;; Prints the names of dynamic blocks which contain a visibility parameter ;; with parameter name equal to that specified by the user. ;; Lee Mac - 2013-12-21 - www.lee-mac.com (defun c:getblockswithvispar ( / def dic par rtn ) (if (/= "" (setq par (strcase (getstring t "\nEnter parameter name: ")))) (progn (while (setq def (tblnext "block" (null def))) (if (and (setq dic (cdr (assoc 360 (entget (cdr (assoc 330 (entget (tblobjname "block" (cdr (assoc 2 def) ) ) ) ) ) ) ) ) ) (= par (vl-some '(lambda ( x ) (if (and (= 360 (car x)) (= "BLOCKVISIBILITYPARAMETER" (cdr (assoc 0 (entget (cdr x)))) ) ) (strcase(cdr(assoc 301(entget(cdr x))))) ) ) (dictsearch dic "acad_enhancedblock") ) ) ) (setq rtn (cons (cdr (assoc 2 def)) rtn)) ) ) (if rtn (foreach blk rtn (print blk)) (princ (strcat "\nNo dynamic blocks found with visibility parameter \"" par "\"" ) ) ) ) ) (princ) )
@ Lee_Mac
Nicely coded, Lee!
@pbejse
Nice approach, pBe!
don't we need to go through all dxf 360 until we find the "BLOCKVISIBILITYPARAMETER" one?
Cheers
Henrique
Hi All, Thanks so much for weighing in! I tried each of these solutions today and had mixed results. I'm going to reply to all in a single post so here it goes:
@HMSilva: Removing the strcase function worked in the original code, but it duplicated the listing of the blocks with the visibility parameter that I was searching. I'm wondering if it's searching for all blocks defined in the drawing including the "U" versions that occur when you adjust any dynamic block. I tried your other version but it wasn't picking up the visability parameter.
@Lee_Mac Your versions both worked but they weren't case sensitve. I tried removing the strcase function but it wasn't working for me. I'm very new to lisp so if somone could break down what exactly is going on in the code, it would be much appreciated from a learning standpoint!
Also, I'm trying to make it loud and clear when the block visabilities are incorrect so I was trying to add and alert function instead of foreach (print blk), but I can't get the alert to do anything but a single block at a time. Instead of foreach, what should the function be? And if I don't want it to be a getstring with user input but a preset visability parameter, how do I do that? Thanks again all.
Chris
@paduch_chris wrote:
..
@hmsilva: Removing the strcase function worked in the original code, but it duplicated the listing of the blocks with the visibility parameter that I was searching. I'm wondering if it's searching for all blocks defined in the drawing including the "U" versions that occur when you adjust any dynamic block. I tried your other version but it wasn't picking up the visability parameter.
..
Chris,
the code at the #1 post (made from a pbejse code ), shouldn't duplicate the blocks "EffectiveName" and I can't reproduce that behavior, if possible, attach a sample dwg with some blocks to be able to test...
"...I tried your other version..."
The other version, was not posted by me, it's from pbejse, is a very well designed code, just need a small adjustment, and I am sure that pbejse will do that.
Henrique
@hmsilva wrote:@ Lee_Mac
Nicely coded, Lee!
Thank you Henrique!
@paduch_chris wrote:@Lee_Mac Your versions both worked but they weren't case sensitve. I tried removing the strcase function but it wasn't working for me. I'm very new to lisp so if somone could break down what exactly is going on in the code, it would be much appreciated from a learning standpoint!
Also, I'm trying to make it loud and clear when the block visabilities are incorrect so I was trying to add and alert function instead of foreach (print blk), but I can't get the alert to do anything but a single block at a time. Instead of foreach, what should the function be? And if I don't want it to be a getstring with user input but a preset visability parameter, how do I do that? Thanks again all.
Sorry Chris, since most programs of this nature are usually written to be case-insensitive, I had overlooked the fact that you wanted the Visibility Parameter to exactly match the string entered by the user.
Please try the following code instead:
;; Prints the names of dynamic blocks which contain a visibility parameter ;; with parameter name equal to that specified by the user. ;; Lee Mac - 2013-12-21 - www.lee-mac.com (defun c:getblockswithvispar ( / def dic par rtn ) (if (/= "" (setq par (getstring t "\nEnter parameter name: "))) (progn (while (setq def (tblnext "block" (null def))) (if (and (setq dic (cdr (assoc 360 (entget (cdr (assoc 330 (entget (tblobjname "block" (cdr (assoc 2 def) ) ) ) ) ) ) ) ) ) (= par (vl-some '(lambda ( x ) (if (and (= 360 (car x)) (= "BLOCKVISIBILITYPARAMETER" (cdr (assoc 0 (entget (cdr x)))) ) ) (cdr (assoc 301 (entget (cdr x)))) ) ) (dictsearch dic "acad_enhancedblock") ) ) ) (setq rtn (vl-list* "\n" (cdr (assoc 2 def)) rtn)) ) ) (if rtn (alert (apply 'strcat (cons "The following blocks were found:\n" rtn) ) ) (princ (strcat "\nNo dynamic blocks found with visibility parameter \"" par "\"" ) ) ) ) ) (princ) )
Lee Mac,
Any chance this could be revised to Prompt for which parameter you wish to search for rather than only the BLOCKVISIBILITYPARAMETER ?
@hmsilva wrote:@Lee_Mac wrote:
(setq rtn (vl-list* "\n" (cdr (assoc 2 def)) rtn))
Nice one, Lee!
Henrique
Hello all,
what does that bit of code accomplish, i was intrigued but this is over my head---
still curious!
Hi Brandon,
with
(setq rtn (vl-list* "\n" (cdr (assoc 2 def)) rtn))
using the vl-list* function, Lee built the rtn list without having to use twice the cons function...
(setq rtn (cons "\n" (cons (cdr (assoc 2 def)) rtn)))
HTH
Henrique
@hmsilva wrote:@Lee_Mac wrote:
(setq rtn (vl-list* "\n" (cdr (assoc 2 def)) rtn))
Nice one, Lee!
Henrique
Thank you Henrique!
@Anonymous wrote:Lee Mac,
Any chance this could be revised to Prompt for which parameter you wish to search for rather than only the BLOCKVISIBILITYPARAMETER ?
I have a few more ideas for this program - I'll look to work on it when I have some more time
@paduch_chris wrote:
This is perfect! Thanks so much! 🙂
Chris
You're welcome Chris!