Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

QSelect multiple specific blocks

14 REPLIES 14
SOLVED
Reply
Message 1 of 15
JCprog
1433 Views, 14 Replies

QSelect multiple specific blocks

Hello Everyone!

 

I need help to modify a simple code that selects a specific block by its effective name. The lisp works perfect on a single entity but I need it to select multiple blocks. Thanks in advance Smiley Happy

 

(defun c:QSBlocks (/ blkname found objs ss i blk name)
  (vl-load-com)

  (if (and (setq blkname "BLOCK1");Change the name of the block in quotes
           (setq found (tblsearch "BLOCK" blkname))
           (setq objs (ssadd)
                 ss   (ssget "_x" '((0 . "INSERT")))
           )
      )
    (progn
      (repeat
        (setq i (sslength ss))
         (setq name (vla-get-effectivename
                      (vlax-ename->vla-object
                        (setq blk (ssname ss (setq i (1- i))))
                      )
                    )
         )
         (if (eq (strcase blkname) (strcase name))
           (ssadd blk objs)
         )
      )
      (if objs
        (sssetfirst nil objs)
      )
    )
    (cond ((not blkname)
           (princ "\n Missed name of block ***")
          )
          ((not found)
           (princ "\n Block not found in drawing !!!")
          )
          (t
           (princ "\n couldn't find any block !!! ")
          )
    )

  )
  (princ)
)

 I was hoping to be as simple as changing this line:

  (if (and (setq blkname "BLOCK1");Change the name of the block in quotes

 to this:

  (if (and (setq blkname "BLOCK1,BLOCK2,BLOCK3");Change the name of the block in quotes

but that doesnt work as I expected.

14 REPLIES 14
Message 2 of 15
Kent1Cooper
in reply to: JCprog

I think [without testing] that it may work if you make that change [multiple comma-delimited Block names in the blkname variable] and change this:

 

(if (eq (strcase blkname) (strcase name))

 

to this:

 

(if (wcmatch (strcase name) (strcase blkname))

 

[Note the switch of the order of the (strcase) functions -- (wcmatch) wants the specific string first, then the pattern to match it to.]

Kent Cooper, AIA
Message 3 of 15
JCprog
in reply to: Kent1Cooper

Hello Kent,

Thanks for the reply. tried ur suggestion but it didnt work.

Message 4 of 15
Kent1Cooper
in reply to: JCprog


@JCprog wrote:

Hello Kent,

Thanks for the reply. tried ur suggestion but it didnt work.


Tell us more.  What didn't work about it?  Did it do nothing?  Did it do something, but not what you expected?  Did it put values into all of the variables?  Was there a message of any kind?

Kent Cooper, AIA
Message 5 of 15
dbroad
in reply to: JCprog

You don't need to filter twice,

 

Change this:

(if (and (setq blkname "BLOCK1");Change the name of the block in quotes
           (setq found (tblsearch "BLOCK" blkname))
           (setq objs (ssadd)
                 ss   (ssget "_x" '((0 . "INSERT")))
           )
      )
    (progn

 to this

(setq blknames (list "BLOCK1""BLOCK2"))
(setq objs (ssadd))
(IF (setq ss (ssget "_x" '((0 . "INSERT"))))
   (progn

 and this:

(if (eq (strcase blkname) (strcase name))
           (ssadd blk objs)
         )
      )

 to this:

(if (member (strcase name) blknames)
           (ssadd blk objs)
         )

 (not tested but should work.  might've missed a parenthesis).

Architect, Registered NC, VA, SC, & GA.
Message 6 of 15
JCprog
in reply to: dbroad

Hello dbroad,

I did change the code per ur intructions but I get this message "malformed list on input"

Message 7 of 15
hmsilva
in reply to: JCprog

Trying to keep your code logic, modified for multiple block names

(defun c:QSBlocks (/ a blkname found lst obj objs ss i blk name)
  (vl-load-com)

  (if (and (setq blkname '("BLOCK1" "BLOCK2" "BLOCK3"));;Change the name of the block in quotes
	   (foreach x blkname
	     (if (member x
			 (while	(setq a (tblnext "BLOCK" (null a)))
			   (setq lst (cons (strcase (cdr (assoc 2 a))) lst))
			   lst
			 )
		 )
	       (setq found (cons x found))
	     )
	     found
	   )
	   (setq objs (ssadd)
		 ss   (ssget "_x" '((0 . "INSERT")))
	   )
      )
    (progn
      (repeat
	(setq i (sslength ss))
	 (setq blk (ssname ss (setq i (1- i))))
	 (setq obj (vlax-ename->vla-object blk))
	 (setq name
		(if (vlax-property-available-p obj 'effectivename)
		  (vla-get-effectivename obj)
		  (vla-get-name obj)
		)
	 )
	 (if (member (strcase name) blkname)
	   (ssadd blk objs)
	 )
      )
      (if objs
	(sssetfirst nil objs)
      )
    )
    (cond ((not blkname)
	   (princ "\n Missed name of block ***")
	  )
	  ((not found)
	   (princ "\n Blocks not found in drawing !!!")
	  )
	  (t
	   (princ "\n couldn't find any block !!! ")
	  )
    )
  )
  (princ)
)

HTH
Henrique

EESignature

Message 8 of 15

Hi,

 

There is a way easier ways to do it.

 

here is what I use

 

(defun GetDynBlNames (name / i ent ss AllNames)
  (setq AllNames "" i 0)
  (if (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 (strcat name ",`*U*")))))
    (while (setq ent (ssname ss i))
      (if (eq name (vla-get-EffectiveName (vlax-ename->vla-object ent)))
        (setq AllNames (strcat AllNames ",`"  (dxf 2(entget ent))))
      )
      (setq i (1+ i))
    )
  )
  AllNames
)

 This function reterns all related names.

 

So now you can use it in other lisp, sometnig like this:

 

(setq ss (sssget "x" (list (cons 2 (GetDynBlNames "YourBlockName")))))

or

(setq ss (sssget "x" (list (cons 8 "LayerName") (cons 2 (GetDynBlNames "YourBlockName")))))

 

 

Message 9 of 15
dbroad
in reply to: JCprog

Yeah, I did say I might have missed a parenthesis.  I think I took too many away from this

(if (member (strcase name) blknames)
           (ssadd blk objs)
         ))

 

Architect, Registered NC, VA, SC, & GA.
Message 10 of 15
JCprog
in reply to: hmsilva

Hello Henrique,

Thank you very much for the code it worked perfectly!!!!!! Smiley Very Happy

 

Also thanks to all who chipped in.....very much appreciated.

Message 11 of 15
hmsilva
in reply to: JCprog


@JCprog wrote:

Hello Henrique,

Thank you very much for the code it worked perfectly!!!!!! Smiley Very Happy


You're welcome, JCprog
Glad I could help

 

Henrique

EESignature

Message 12 of 15
krazeymike
in reply to: JCprog

Hi all, I'm trying to run the command posted by Henrique.
However while it selects my point crosses fine, my dynamic Contour Labels are not added to the selection set. Could somebody please take a look at the attached please and let me know where I've gone wrong. Thankyou 

Message 13 of 15
hmsilva
in reply to: krazeymike


@krazeymike wrote:

Hi all, I'm trying to run the command posted by Henrique.
However while it selects my point crosses fine, my dynamic Contour Labels are not added to the selection set. Could somebody please take a look at the attached please and let me know where I've gone wrong. Thankyou 


@krazeymike change

(if (and (setq blkname '("POINT_CROSS" "Label - Contour Minor" "Label - Contour"));;Change the name of the block in quotes

to

 (if (and (setq blkname (mapcar 'strcase '("Label - Contour" "Label - Contour Minor" "POINT_CROSS")));;Change the name of the block in quotes

 

Hope this helps,
Henrique

EESignature

Message 14 of 15
krazeymike
in reply to: hmsilva

Worked perfectly thankyou

Message 15 of 15
hmsilva
in reply to: krazeymike

You're welcome, @krazeymike 
Glad I could help

Henrique

EESignature

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost