I would like to be able to pick a block and then have the program select all those blocks in the drawing but am having problems passing the black name as a variable to ssget:
(prompt "\nPick your Fitting..")
(setq desc (entget (entlast)))
(print desc)
(setq dd (cdr (assoc '2 desc)))
(print dd)
(setq ss (ssget '(2 . dd))
sl (sslength ss)
ct 0
ctr 0)
(princ "\nUpdating all Fittings for new description....")
the print statements are so I can see where its failing and it fails here
(setq ss (ssget '(2 . dd))
Am I right in thinking ssget only searches for main entities and won't find entities by block names?
Solved! Go to Solution.
Solved by hmsilva. Go to Solution.
You can try this:
(setq blkname (cdr (assoc 2 (entget (car (entsel "\Select block: ")))))) (setq blksel (ssget "X" (list (cons 0 "INSERT")(cons 2 blkname))))
You may be interested in my new book "AutoCAD expert's Visual LISP" which deals in extent with all this.
A sample of its contents can be seen in my Autodesk Universitry class at http://au.autodesk.com/?nd=au_player#0%0:3202
Regards,
I'm going to hedge a guess and say replace:
(setq ss (ssget '(2 . dd))
with:
(setq ss (ssget (list '2 dd))
Reason: you're quoting a variable ("dd") which tells (ssget to look for this (2 . dd), not (2 . blockname)
(if ("mysolution"=answer) then (click "Accept As Solution"))
------------------------------------------------------------------------------------
@Anonymous wrote:I would like to be able to pick a block and then have the program select all those blocks in the drawing but am having problems passing the black name as a variable to ssget:
....
As others have pointed out, you can't use a quoted [i.e. apostrophe-prefixed] list with a variable name in it, because "quoting" it means it won't evaluate anything in it, so it won't extract the Block name out of that variable.
But rather than pull the Block name out of its association in a dotted pair with a 2, and then put it back into one of those for use in (ssget), you could skip some intermediate steps and just leave it associated, and even skip some variables, and get the selection of all such Blocks directly out of your selection of one of them:
(setq ss (ssget "_X" (list (assoc 2 (entget (car (entsel "\nSelect Block: ")))))))
I love the way with lisp you can put so much into one line using brackets so I will for sure being trying your example, very neat!
But selecting only by group code 2 is not of my liking.
Group code 2 can mean a lot of things, for example some of them:
Dimension style name
Table name
Name of the block that contains the entities that make up the dimension picture
Underlay Name
Linetype name
Mline style name
Field code string
Shape name
Name of view
Layer name
UCS name
The logical selection process should be in my opinion:
1.- From ALL the entitie in the drawing ("X")
2.- From all the INSERTS among them (0 . "INSERT")
3.- Select only those whose block name is (2 . "whatever")
Of course variables can be (should be) avoided in our programs. Only using them in an example can clarify the concepts.
@Anonymous wrote:But selecting only by group code 2 is not of my liking.
Group code 2 can mean a lot of things, ....
It's true that there are (assoc 2) entries in a lot of things, but the great majority of them can't go in a selection set, i.e. are never drawn entities that are going to be looked for by (ssget) -- any of the style, linetype, view, layer, or UCS names. The Dimension "block names" are all *D followed by numbers only, so unless you give other Blocks names like that, you don't need to worry about those. I would probably never use anything like the same kinds of names for Blocks as I would for the other possibilities, so I've never needed to search for more than just the Block's name. But for anyone who might have conflicts like that, and needs to limit a search to Insert entities only, it can still be done without pulling the Block name apart from its associated 2 and then re-associating it with another 2:
(setq
bdata (entget (car (entsel "\nPick your Fitting..")))
ss (ssget "_X" (list '(0 . "INSERT") (assoc 2 bdata)))
)
Kent1Cooper,
using your method, and avoiding variables
(setq ss (ssget "_X" (list (cons 0 "INSERT" )(assoc 2 (entget (car (entsel "\nSelect Block: ")))))))
Henrique
This has been fascinating, thank you all, I have learned so much and my lisp which is very rusty will be improved now. I was hoping by going directly to the assoc 2 the program would run faster. Will it slow down the program to first select all the blocks with "insert" and then go through the set looking for only the ones with a certain block name?
@Anonymous wrote:This has been fascinating, thank you all, I have learned so much and my lisp which is very rusty will be improved now. I was hoping by going directly to the assoc 2 the program would run faster. Will it slow down the program to first select all the blocks with "insert" and then go through the set looking for only the ones with a certain block name?
Yup, tghere will be a considerable diffrence in speed. But there are cases that you need to provide a filter for wildcard match in conjunction with ssget "_X" argument, specially for Dynamic Blocks
(ssget "_X" (list '(0 . "INSERT")(cons 2 (strcat bname ",`*U*"))));<-- DB Anonymous Name
Then itirate thru the selection set to match the "Effectivename"
(equal (vla-get-effectivename vlaobject) bname)
HTH
Well it works perfectly using
(setq ss (ssget "_X" (list (cons 0 "INSERT" )(assoc 2 (entget (car (entsel "\nSelect Block: ")))))))
from
Henrique
I will test it on a big drawing in the office but have a feeling it will be fast enough with the new computers, very pleased about it, thanks all.
@Anonymous wrote:Well it works perfectly using
(setq ss (ssget "_X" (list (cons 0 "INSERT" )(assoc 2 (entget (car (entsel "\nSelect Block: ")))))))
Sure it does, BUT it wont work with Dynamic Blocks Anonymous names
IMO, Shorter doesnt mean faster and certainly not efficient
(defun c:test ( / ss) (if (setq ss (ssget "_X" (list (cons 0 "INSERT") (assoc 2 (entget (car (entsel "\nSelect Block: "))))))) (princ (strcat "\n " (itoa (sslength ss)) " Objects Selected"))) (princ) )
Say for instance you select another entity other than a "block"
Command: TEST
Select Block: ; error: bad SSGET list
or you missed a selection. What will you see?
Command: test
Select Block: ; error: bad argument type: lentityp nil
While this:
(defun c:test2 (/ ss) (if (setq ss (ssget "_+.:S:E" '((0 . "INSERT")))) (cond ((and (setq ss (ssget "_X" (list (cons 0 "INSERT") (assoc 2 (entget (ssname ss 0)))))) (princ (strcat "\n " (itoa (sslength ss)) " Objects Selected"))))) (princ "\nNo Block selected:") ) (princ) )
Will not produce an error and still use one variable name (ss)
But still, if the user selects a Dynamic Block Anonymuous name it will still not give you an accurate count
Try this:
(defun c:test3 (/ _effname bname ss ss2 ) (setq _effname (lambda (e) (vla-get-effectivename (vlax-ename->vla-object e)) )) (if (and (setq ss2 (ssadd) ss (ssget "_+.:S:E" '((0 . "INSERT")))) (setq bname (_effname (ssname ss 0))) (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 (strcat bname ",`*U*")) ))) ) (progn (repeat (sslength ss) (if (eq (_effname (ssname ss 0)) bname) (ssadd (ssname ss 0) ss2)) (ssdel (ssname ss 0) ss)) (princ (strcat "\n " (itoa (sslength ss2)) " Objects Selected"))) (princ "\nNo Block selected:") ) (princ) )
Better have and not need than need and not have, I'm just saying
HTH
Very good! I am still using this
(defun restore () ;restore variables
(setq *error* olderr)
(princ)
)
(defun trap (er) ;error trapping
(princ "\nPROGRAM ABORTED ")
(princ er)
(setq *error* olderr)
(princ)
)
which I guess I made up about 25 years ago!
Can't find what you're looking for? Ask the community or share your knowledge.