Select Block by name

Select Block by name

Anieves114
Explorer Explorer
732 Views
10 Replies
Message 1 of 11

Select Block by name

Anieves114
Explorer
Explorer

Hello,

 

I'm trying to create  a command where I can select a block by name. Now I have seen where lisps where I run the command and have to type in the block name. I want the command and select it without user input.

 

This will be a small part of a larger lisp. The end goal for me is to create a lisp that updates the client existing border to their new one.

 

Here is one I found that I have to type in the block name:

 

 

 

	(defun c:fbx ( / blockname sset); filter all blocks of same name with one click
	(SETVAR "CMDECHO" 1)
		(while

			(not
				(tblsearch "block"
					(setq blockname 
						(getstring t "\nEnter Block Name: ")
					)
				)
			)

			(prompt "\nNo such Block name defined in this drawing.  Try again:")

		); while
		(if 
			(setq sset 
				(ssget "x" 
					(list 
						(cons 2 blockname)
					)
				)
			
			)

			(progn ; then
				(sssetfirst sset sset)
				(princ 
					(strcat "\nSelected " 
						(itoa 
							(sslength sset)
						) " instances of block \"" blockname "\"."
					)
				)
			); progn

			(prompt "\nNo insertions of that Block in this drawing."); else
		); if
		(SETVAR "CMDECHO" 1)
		(princ)
	)

 

 

 

I Have Shortened it to this: 

 

 

 

	(defun c:fbx ( / blockname sset); filter all blocks of same name with one click
	(SETVAR "CMDECHO" 1)

				(tblsearch "block"
					(setq blockname 
						(getstring t "\nEnter Block Name: ")
					)
				)
	
		(SETVAR "CMDECHO" 1)
		(princ)
	)

 

 

 

adding the block name to select the block is where I'm having trouble. I'm still at novice. Any explanation will help

 

Best

0 Likes
733 Views
10 Replies
Replies (10)
Message 2 of 11

CodeDing
Advisor
Advisor

@Anieves114 ,

 

You don't necessarily need a separate function to select the blocks by their name. It is merely a (ssget ...) call in most cases. the code I'm providing is basically 70% checks and notifications to the user, except for my one line where I use (ssget ...).

 

(defun c:TEST ( / blockName ss)
  (setq blockname "My Block")
  (cond
    ((not (tblsearch "BLOCK" blockName))
      (prompt (strcat "\nNo block defined in this drawing named: " blockName))
    )
    ((setq ss (ssget "_X" (list (cons 2 blockName))))
      (sssetfirst nil ss)
      (alert (princ (strcat "\nSelected " (itoa (sslength ss)) " instances of block: " blockName)))
    )
    (t (prompt (strcat "\nNo insertions in this drawing of block: " blockName)))
  );cond
  (princ)
);defun

 

 

...you can merely use this code to get a Selection Set of your blocks:

 

(setq ss (ssget "_X" (list (cons 2 blockName))))

 

 

Hope that helps.

Best,

~DD

0 Likes
Message 3 of 11

Kent1Cooper
Consultant
Consultant

It doesn't sound likely for something like a title block, but are they dynamic Blocks?  If so, (ssget) won't be able to find them -- you would probably need to have it select all Blocks, and step through the set, extracting the "effective name" to compare with your Block name.

 

You don't need to deal with the CMDECHO System Variable if you're not using any (command) functions.

 

Your shortened version only looks at whether there is a Block definition in the drawing by that name -- it includes nothing related to selection, nor anything about whether there are even any insertions of that Block.

 

It's not clear to me whether what you want to do is:

A)  hard-code the Block name into the command so that the User doesn't need to input or select anything;

-- or --

B)  have the User select a Block reference by picking, with the code getting its Block name for use somehow [to find all insertions of it, I suspect?];

-- or --

C)  something else, because I misunderstood.

Kent Cooper, AIA
Message 4 of 11

Anieves114
Explorer
Explorer

Sorry yes, I'm trying to do a hard code. user type command and it does it for you. it will take all the old information from the border and title block (4 separate blocks: border, drawing information and number, drawing title, and revision information) the first step was for me to be able select block (which being all self taught and not have much time to dedicate to learning more lisp has proven difficult) then replace and update those blocks. 

0 Likes
Message 5 of 11

Anieves114
Explorer
Explorer

Awesome! thank you this gets me started in my end goal!

 

Thank you!

0 Likes
Message 6 of 11

MrJSmith
Advocate
Advocate

@Anieves114Did the block reference change or are you trying to update attributes inside the block?

0 Likes
Message 7 of 11

paullimapa
Mentor
Mentor

Here's the code for user to select an already inserted Block with Attributes and get the BlockName

; selection filter for block with attributes returning block name
  (setq blk nil)
  (while (not blk) 
   (princ"\nSelect Block with Attributes...")
   (setq blk (ssget "_+.:E:S" '((0 . "INSERT")(66 . 1))))
  )
  (setq blockName (vla-get-EffectiveName (vlax-ename->vla-object (ssname blk 0))))

Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 8 of 11

Kent1Cooper
Consultant
Consultant

@Anieves114 wrote:

.... I'm trying to do a hard code. user type command and it does it for you. it will take all the old information from the border and title block (4 separate blocks: border, drawing information and number, drawing title, and revision information) the first step was for me to be able select block.... 


 

(defun C:COMMANDNAME ()
  (setq
    brdr (ssget "_X" '((2 . "BorderBlockName")))
    info (ssget "_X" '((2 . "InfoBlockName")))
    title (ssget "_X" '((2 . "TitleBlockName")))
    rev (ssget "_X" '((2 . "RevisionBlockName")))
  )
)

 

That will put selection sets in those variable names.  The border Block itself will then be (ssname brdr 0), etc.  After that first step, do you then know how to "replace and update those blocks"?  You don't say what their content is like, which will determine what to do with them -- I assume Attributes for some of them, but probably not all.  Consider to consolidate into one Block with Attributes for the variable parts.

 

I assume there will never be more than one of each of those four Blocks, but I can imagine there might be if you have multiple paper space Layouts in a drawing.  It can be made to check whether there are any at all, as well as whether there are more than one.

Kent Cooper, AIA
0 Likes
Message 9 of 11

ВeekeeCZ
Consultant
Consultant

This is what I am using...

 

(vl-load-com)

(defun c:SelectBlocks* ( / :getBlockName s n i e) (defun :getBlockName (obj) (if (= (type obj) 'ENAME) (setq obj (vlax-ename->vla-object obj))) (if (vlax-property-available-p obj 'EffectiveName) (vla-get-EffectiveName obj) (vla-get-Name obj))) (or (and (setq s (ssget "_I" '((0 . "INSERT")))) (sssetfirst nil)) (and (setq n (getstring "\nSpecify blockname w/wildcards <pick>: ")) (/= n "")) (setq s (car (entsel "\nPick a block: ")))) (if s (setq n (lisped (:getBlockName (setq s (if (= 'ENAME (type s)) s (ssname s 0))))))) (if s (sssetfirst nil)) (if (setq s (ssget "_X" (list (cons 0 "INSERT") (cons 2 (strcat n ",`*U*")) (cons 410 (getvar 'ctab))))) (repeat (setq i (sslength s)) (setq e (ssname s (setq i (1- i)))) (if (not (wcmatch (strcase (:getBlockName e)) (strcase n))) (ssdel e s)))) (if (and s (> (sslength s) 0)) (progn (sssetfirst nil s) (princ (strcat "\n>> " (itoa (sslength s)) " blocks found.")))) (princ) )

 

0 Likes
Message 10 of 11

andkal
Collaborator
Collaborator

Hello Anieves114
Maybe this will interrest you too. The lisp filters the selection and the user can select what blocks he is looking for. It also works with dynamic blocks.
It is available to download from >my website< or from the >Autodesk App store<.

 

FBB.gif


• www.autolisps.blogspot.com - Productivity plugins for Autocad and Autocad MEP
• Autodesk AppStore
0 Likes
Message 11 of 11

Anieves114
Explorer
Explorer

Awesome Thank you!

 

This is all done in Model space as per the clients(utility set in their ways) standards. The border itself is a block without any attributes. The Revisions, Drawing info, and Title are all block with text attributes. So 4 block total 1 just line work and 3 with just text attributes. 

 

Because I'm learning still I was just going to figure it out with my good friend google. So the order of how i would do this is:

 

get scale of current border

Delete current border

Purge old border

Move text blocks into space 

place New border (in theory they all should be at 0,0)

scale appropriately

(burst new block)

Run a script call MTB to copy all of the attributes

delete old border and info. 

Save

0 Likes