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

A problem with ssget

13 REPLIES 13
SOLVED
Reply
Message 1 of 14
rodb
2382 Views, 13 Replies

A problem with ssget

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?

13 REPLIES 13
Message 2 of 14
Rtogores
in reply to: rodb

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,

 

Message 3 of 14
bgingerich
in reply to: rodb

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"))
------------------------------------------------------------------------------------

─────────────────────────────────────────────────────────────────────────────────────────────
Brandon Gingerich
Message 4 of 14
rodb
in reply to: bgingerich

Thank you I will try both options and thanks for the link to the new book on lisp!

Message 5 of 14
Kent1Cooper
in reply to: rodb


@RodB 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: ")))))))

Kent Cooper, AIA
Message 6 of 14
rodb
in reply to: Kent1Cooper

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!

Message 7 of 14
Rtogores
in reply to: rodb

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.

 

Message 8 of 14
Kent1Cooper
in reply to: Rtogores


@Rtogores 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)))

)

Kent Cooper, AIA
Message 9 of 14
hmsilva
in reply to: Kent1Cooper

Kent1Cooper,

using your method, and avoiding variables

 

(setq ss (ssget "_X" (list (cons 0 "INSERT" )(assoc 2 (entget (car (entsel "\nSelect Block: ")))))))

 

Henrique

EESignature

Message 10 of 14
rodb
in reply to: hmsilva

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? 

Message 11 of 14
pbejse
in reply to: rodb


@RodB 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

 

 

Message 12 of 14
rodb
in reply to: pbejse

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.

Message 13 of 14
pbejse
in reply to: rodb


@RodB 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 

Message 14 of 14
rodb
in reply to: pbejse

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.

Post to forums  

Autodesk Design & Make Report

”Boost