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

Need to check if blocks exist in drawing.

18 REPLIES 18
Reply
Message 1 of 19
mid-awe
754 Views, 18 Replies

Need to check if blocks exist in drawing.

Hey all, I've been working on a LISP mostly composed of bits and pieces from this message board, but I can't figure out what's wrong with this code. Aside from it's bulk ACAD reports that I have to many arguments. Please help me optimize and fix this. I'm sure it's an easy issue I'm just too new to LISP to see the answer. Thank you.
[code](DEFUN C:CHKDWG (/ ss1 blknam blknam1 blknam2
blknam3 blknam4 blknum blknum1 blknum2
blknum3 blknum4
)
(SETQ blknam "NSKIM")
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam))
)
)
(if ss1
(progn (SETQ blknum (sslength ss1)))
)
(SETQ blknam1 "LIGHT")
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam1))
)
)
(if ss1
(progn (SETQ blknum1 (sslength ss1))
)
)
(SETQ blknam2 "MDXDRAIN")
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam2))
)
)
(if ss1
(progn
(SETQ blknum2 (sslength ss1))
)
)
(SETQ blknam3 "HLFDRAIN")
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam3))
)
)
(if ss1
(progn
(SETQ blknum3 (sslength ss1))
)
)
(SETQ blknam4 "DPTHCALL")
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam4))
)
)
(if ss1
(progn
(SETQ blknum4 (sslength ss1))
)
)
(cond
((= blknam "NSKIM") (SETQ blknam "skimmer"))
((= blknam1 "LIGHT") (SETQ blknam1 "light"))
((= blknam2 "MDXDRAIN") (SETQ blknam2 "main drain"))
((= blknam3 "HLFDRAIN")(SETQ blknam3 "secondary main drain or MDX vent"))
((= blknam4 "DPTHCALL") (SETQ blknam "depth markers"))
(t nil)
)
(alert
(strcat "No " blknam " found")
(strcat "No " blknam1 " found")
(strcat "No " blknam2 " found")
(strcat "No " blknam3 " found")
(strcat "No " blknam4 " found")
)
(princ)
)[/code]
18 REPLIES 18
Message 2 of 19
Anonymous
in reply to: mid-awe

I think your "too many arguments" problem is because you've sent five strings to ALERT which only takes a single string as an argument. Try this:

(DEFUN C:CHKDWG (/ ss1 blknam blknam1 blknam2
blknam3 blknam4 blknum blknum1 blknum2
blknum3 blknum4
)
(SETQ blknam "NSKIM" blknum 0)
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam))
)
)
(if ss1
(progn (SETQ blknum (sslength ss1)))
)
(setq ss1 nil)
(SETQ blknam1 "LIGHT" blknum1 0)
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam1))
)
)
(if ss1
(progn (SETQ blknum1 (sslength ss1))
)
)
(setq ss1 nil)
(SETQ blknam2 "MDXDRAIN" blknum 0)
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam2))
)
)
(if ss1
(progn
(SETQ blknum2 (sslength ss1))
)
)
(setq ss1 nil)
(SETQ blknam3 "HLFDRAIN" blknum3 0)
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam3))
)
)
(if ss1
(progn
(SETQ blknum3 (sslength ss1))
)
)
(setq ss1 nil)
(SETQ blknam4 "DPTHCALL" blknum 0)
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam4))
)
)
(if ss1
(progn
(SETQ blknum4 (sslength ss1))
)
)
(setq ss1 nil)
(alert
(strcat
(itoa blknum)
" skimmers found\n"
(Itoa blknum1)
" lights found\n"
(itoa blknum2)
" main drains found\n")
(itoa blknum3)
" secondary main drains found\n"
(itoa blknum4)
"depth markers found."
)
)
(princ)
)

Note that I have set ss1to nil each time after you're done with it. You can only have, I think, 128 selection sets at a time. After that AutoCAD starts acting awfully strange. If you create a selection set ss1 and you don't later set it to nil, it takes up one of the pool. If you overwrite the selection set, e.g.

(setq ss1 (ssget "x" (list (cons 0 "LINE"))))
(setq ss1 (ssget "x" (list (cons 0 "CIRCLE"))))

you've taken up two of the availble selection sets. So when your program is done with a selection set, it's a good idea to "nil it out."

Another tip is that you can set several variables with a single SETQ statement, thus

(SETQ blknam "NSKIM")
(SETQ blknum 0)
(SETQ ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam))
)
)

is the equivalent of

(SETQ blknam "NSKIM"
blknum 0
ss1
(ssget "X"
(list (cons 0 "INSERT") (cons 2 blknam))
)
)
Message 3 of 19
Anonymous
in reply to: mid-awe

Not to pick nits here, I just want to clear up one little thing.... ;-) "wkiernan" wrote in message ... > Note that I have set ss1to nil each time after you're done with it. You > can only have, I think, 128 selection sets at a time. After that AutoCAD > starts acting awfully strange. If you create a selection set ss1 and you > don't later set it to nil, it takes up one of the pool. If you overwrite > the selection set, e.g. > > (setq ss1 (ssget "x" (list (cons 0 "LINE")))) > (setq ss1 (ssget "x" (list (cons 0 "CIRCLE")))) > > you've taken up two of the availble selection sets. So when your program > is done with a selection set, it's a good idea to "nil it out. This is not true. The 128 selection sets refers to "open" selection sets. Once you overwrite a SS the old one is gone......as long as you declare your ss's as local variables you won't need to set them to nil. Here are two little lisps that demonstrate this. The first will error out, the second will not...... (defun c:sstest1 (/ count *error*) (defun *error* (msg) (princ (strcat "\nError message: " msg)) (princ (strcat "\nError number: " (itoa (getvar "errno")))) (princ (strcat "\nCreated " (itoa (1- count)) " selections sets.....")) ) (setq count 0) (repeat 150 (setq count (1+ count)) (set (read (strcat "ss" (itoa count))) (ssget "x")) ) ) (defun c:sstest2 (/ sscount ss) (setq sscount 0) (repeat 1000 (setq sscount (1+ sscount)) (setq ss (ssget "x")) ) (princ (strcat "\nCreated " (itoa sscount) " selections sets.....")) (princ) ) This will clear them back out: (defun c:ssclear () (vl-load-com) (foreach x (atoms-family 1) (if (= (type (eval (read x))) 'PICKSET) (set (read x) nil) ) ) (vlax-for x (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) (vla-delete x) ) (gc) (princ) ) HTH, Jeff
Message 4 of 19
mid-awe
in reply to: mid-awe

Hey thanks 🙂

Works but for some reason no matter how many "NSKIM" block are in the drawing it always returns 0.
Any ideas?
Message 5 of 19
Anonymous
in reply to: mid-awe

Command: ssx Select object : Enter filter option [Block name/Color/Entity/Flag/LAyer/LType/Pick/Style/Thickness/Vector]: b >>Enter block name to add : NSKIM Current filter: ((2 . "NSKIM")) Enter filter option [Block name/Color/Entity/Flag/LAyer/LType/Pick/Style/Thickness/Vector]: 9 found. "MiD-AwE" wrote in message news:1193888.1110314971510.JavaMail.jive@jiveforum1.autodesk.com... > Hey all, I've been working on a LISP mostly composed of bits and pieces from this message board, but I can't figure out what's wrong with this code. Aside from it's bulk ACAD reports that I have to many arguments. Please help me optimize and fix this. I'm sure it's an easy issue I'm just too new to LISP to see the answer. Thank you. > [code](DEFUN C:CHKDWG (/ ss1 blknam blknam1 blknam2 > blknam3 blknam4 blknum blknum1 blknum2 > blknum3 blknum4 > ) > (SETQ blknam "NSKIM") > (SETQ ss1 > (ssget "X" > (list (cons 0 "INSERT") (cons 2 blknam)) > ) > ) > (if ss1 > (progn (SETQ blknum (sslength ss1))) > ) > (SETQ blknam1 "LIGHT") > (SETQ ss1 > (ssget "X" > (list (cons 0 "INSERT") (cons 2 blknam1)) > ) > ) > (if ss1 > (progn (SETQ blknum1 (sslength ss1)) > ) > ) > (SETQ blknam2 "MDXDRAIN") > (SETQ ss1 > (ssget "X" > (list (cons 0 "INSERT") (cons 2 blknam2)) > ) > ) > (if ss1 > (progn > (SETQ blknum2 (sslength ss1)) > ) > ) > (SETQ blknam3 "HLFDRAIN") > (SETQ ss1 > (ssget "X" > (list (cons 0 "INSERT") (cons 2 blknam3)) > ) > ) > (if ss1 > (progn > (SETQ blknum3 (sslength ss1)) > ) > ) > (SETQ blknam4 "DPTHCALL") > (SETQ ss1 > (ssget "X" > (list (cons 0 "INSERT") (cons 2 blknam4)) > ) > ) > (if ss1 > (progn > (SETQ blknum4 (sslength ss1)) > ) > ) > (cond > ((= blknam "NSKIM") (SETQ blknam "skimmer")) > ((= blknam1 "LIGHT") (SETQ blknam1 "light")) > ((= blknam2 "MDXDRAIN") (SETQ blknam2 "main drain")) > ((= blknam3 "HLFDRAIN")(SETQ blknam3 "secondary main drain or MDX vent")) > ((= blknam4 "DPTHCALL") (SETQ blknam "depth markers")) > (t nil) > ) > (alert > (strcat "No " blknam " found") > (strcat "No " blknam1 " found") > (strcat "No " blknam2 " found") > (strcat "No " blknam3 " found") > (strcat "No " blknam4 " found") > ) > (princ) > )[/code]
Message 6 of 19
Anonymous
in reply to: mid-awe

Sorry all... forgot I was in the customization group ;-) Names ARE case sensitive. Is the name in upper or lower case in the block table? "TRJ" wrote in message news:422e26c9_2@newsprd01... > Command: ssx > Select object : > Enter filter option [Block > name/Color/Entity/Flag/LAyer/LType/Pick/Style/Thickness/Vector]: b > >>Enter block name to add : NSKIM > Current filter: ((2 . "NSKIM")) > Enter filter option [Block > name/Color/Entity/Flag/LAyer/LType/Pick/Style/Thickness/Vector]: > 9 found. > > "MiD-AwE" wrote in message > news:1193888.1110314971510.JavaMail.jive@jiveforum1.autodesk.com... > > Hey all, I've been working on a LISP mostly composed of bits and pieces > from this message board, but I can't figure out what's wrong with this code. > Aside from it's bulk ACAD reports that I have to many arguments. Please help > me optimize and fix this. I'm sure it's an easy issue I'm just too new to > LISP to see the answer. Thank you. > > [code](DEFUN C:CHKDWG (/ ss1 blknam blknam1 blknam2 > > blknam3 blknam4 blknum blknum1 blknum2 > > blknum3 blknum4 > > ) > > (SETQ blknam "NSKIM") > > (SETQ ss1 > > (ssget "X" > > (list (cons 0 "INSERT") (cons 2 blknam)) > > ) > > ) > > (if ss1 > > (progn (SETQ blknum (sslength ss1))) > > ) > > (SETQ blknam1 "LIGHT") > > (SETQ ss1 > > (ssget "X" > > (list (cons 0 "INSERT") (cons 2 blknam1)) > > ) > > ) > > (if ss1 > > (progn (SETQ blknum1 (sslength ss1)) > > ) > > ) > > (SETQ blknam2 "MDXDRAIN") > > (SETQ ss1 > > (ssget "X" > > (list (cons 0 "INSERT") (cons 2 blknam2)) > > ) > > ) > > (if ss1 > > (progn > > (SETQ blknum2 (sslength ss1)) > > ) > > ) > > (SETQ blknam3 "HLFDRAIN") > > (SETQ ss1 > > (ssget "X" > > (list (cons 0 "INSERT") (cons 2 blknam3)) > > ) > > ) > > (if ss1 > > (progn > > (SETQ blknum3 (sslength ss1)) > > ) > > ) > > (SETQ blknam4 "DPTHCALL") > > (SETQ ss1 > > (ssget "X" > > (list (cons 0 "INSERT") (cons 2 blknam4)) > > ) > > ) > > (if ss1 > > (progn > > (SETQ blknum4 (sslength ss1)) > > ) > > ) > > (cond > > ((= blknam "NSKIM") (SETQ blknam "skimmer")) > > ((= blknam1 "LIGHT") (SETQ blknam1 "light")) > > ((= blknam2 "MDXDRAIN") (SETQ blknam2 "main drain")) > > ((= blknam3 "HLFDRAIN")(SETQ blknam3 "secondary main drain or MDX > vent")) > > ((= blknam4 "DPTHCALL") (SETQ blknam "depth markers")) > > (t nil) > > ) > > (alert > > (strcat "No " blknam " found") > > (strcat "No " blknam1 " found") > > (strcat "No " blknam2 " found") > > (strcat "No " blknam3 " found") > > (strcat "No " blknam4 " found") > > ) > > (princ) > > )[/code] > >
Message 7 of 19
Anonymous
in reply to: mid-awe

Command: -block Enter block name or [?]: test Specify insertion base point: Select objects: Specify opposite corner: 1 found Select objects: Command: (tblsearch "block" "TEST") ((0 . "BLOCK") (2 . "test") (70 . 0) (10 0.0 0.0 0.0) (-2 . )) As you can see, the names are NOT case sensitive in the table. -- Autodesk Discussion Group Facilitator "TRJ" wrote in message news:422e295f$1_2@newsprd01... > Names ARE case sensitive. Is the name in upper or lower case in the block > table?
Message 8 of 19
Anonymous
in reply to: mid-awe

Yep, my mistake, change the line which reads

(SETQ blknam4 "DPTHCALL" blknum 0)

to

(SETQ blknam4 "DPTHCALL" blknum4 0)
Message 9 of 19
Anonymous
in reply to: mid-awe

Not sure but when I create a "list" with "NSKIM" in it and then do a (member expr lst) where expression is "nskim", it returns nil. Does it not for you? "Jason Piercey" wrote in message news:422e2bba_3@newsprd01... > Command: -block > > Enter block name or [?]: test > Specify insertion base point: > Select objects: Specify opposite corner: 1 found > > Select objects: > > Command: (tblsearch "block" "TEST") > ((0 . "BLOCK") (2 . "test") (70 . 0) (10 0.0 0.0 0.0) > (-2 . )) > > > As you can see, the names are NOT case sensitive > in the table. > > > > -- > Autodesk Discussion Group Facilitator > > > > "TRJ" wrote in message news:422e295f$1_2@newsprd01... > > > Names ARE case sensitive. Is the name in upper or lower case in the block > > table? > >
Message 10 of 19
Anonymous
in reply to: mid-awe

The member function is case sensitive when dealing with strings. Jason's point was the two arguments supplied to the tblsearch function are not case sensitive. Joe Burke > Not sure but when I create a "list" with "NSKIM" in it and then do a (member > expr lst) where expression is "nskim", it returns nil. Does it not for you? > > "Jason Piercey" wrote in message > news:422e2bba_3@newsprd01... >> Command: -block >> >> Enter block name or [?]: test >> Specify insertion base point: >> Select objects: Specify opposite corner: 1 found >> >> Select objects: >> >> Command: (tblsearch "block" "TEST") >> ((0 . "BLOCK") (2 . "test") (70 . 0) (10 0.0 0.0 0.0) >> (-2 . )) >> >> >> As you can see, the names are NOT case sensitive >> in the table. >> >> >> >> -- >> Autodesk Discussion Group Facilitator >> >> >> >> "TRJ" wrote in message > news:422e295f$1_2@newsprd01... >> >> > Names ARE case sensitive. Is the name in upper or lower case in the > block >> > table? >> >> > >
Message 11 of 19
Anonymous
in reply to: mid-awe

(defun c:ChkDwg (/ BlkNams blknam)
(setq BlkNams (list "NSKIM" "LIGHT" "MDXDRAIN" "HLFDRAIN" "DPTHCALL")
)
;---;
(foreach n BlkNams
(cond ((= n "NSKIM")
(setq blknam "skimmer")
)
((= n "LIGHT")
(setq blknam "light")
)
((= n "MDXDRAIN")
(setq blknam "main drain")
)
((= n "HLFDRAIN")
(setq blknam "secondary main drain or MDX vent")
)
((= n "DPTHCALL")
(setq blknam "depth markers")
)
)
(if (setq ss (ssget "X" (list (cons 0 "INSERT")(cons 2 n))))
(princ (strcat "\n " blknam " found < " (itoa (sslength ss)) " > time(s)."))
(princ (strcat "\n " blknam " NOT found."))
)
)
;---;
(princ)
)
Message 12 of 19
Anonymous
in reply to: mid-awe

Given. However I do not see where the OP is calling tblsearch in his code. Did I overlook it? Is case sensitivity possibly why the OP is not finding his blocks? "Joe Burke" wrote in message news:422edeef$1_1@newsprd01... > The member function is case sensitive when dealing with strings. > > Jason's point was the two arguments supplied to the tblsearch function are not case > sensitive. > > Joe Burke > > > > Not sure but when I create a "list" with "NSKIM" in it and then do a (member > > expr lst) where expression is "nskim", it returns nil. Does it not for you? > > > > "Jason Piercey" wrote in message > > news:422e2bba_3@newsprd01... > >> Command: -block > >> > >> Enter block name or [?]: test > >> Specify insertion base point: > >> Select objects: Specify opposite corner: 1 found > >> > >> Select objects: > >> > >> Command: (tblsearch "block" "TEST") > >> ((0 . "BLOCK") (2 . "test") (70 . 0) (10 0.0 0.0 0.0) > >> (-2 . )) > >> > >> > >> As you can see, the names are NOT case sensitive > >> in the table. > >> > >> > >> > >> -- > >> Autodesk Discussion Group Facilitator > >> > >> > >> > >> "TRJ" wrote in message > > news:422e295f$1_2@newsprd01... > >> > >> > Names ARE case sensitive. Is the name in upper or lower case in the > > block > >> > table? > >> > >> > > > > > >
Message 13 of 19
mid-awe
in reply to: mid-awe

Sweet,

Much better than what I had. My main goal was not to count the number of times the block was found though that is a very useful function, but I needed to check if the block exists in the drawing and this rewrite is excellent for that. I need to develop this into a full featured checker for our work. For about 75% of our drawings there will only be 1 of each of these items in our drawings (swimming pools are considerably different from standard architecture). So, checking for the existence of said blocks will suffice but on our commercial division counting blocks is essential.

I have made a simple modification of the code to serve both purposes (posted below). Basically, I only added the alert for items not found at all). I'd like to do other functions as well as alert the user if the block is not found at all.

Thanks again to everyone and especially BillZ who seems to always surprise me with near wizardry of LISP 🙂
[code](defun c:CHDWG (/ BlkNams blknam)
(setq BlkNams (list "NSKIM" "LIGHT" "MDXDRAIN" "HLFDRAIN" "DPTHCALL" "NAWL")
)
;---;
(foreach n BlkNams
(cond ((= n "NSKIM")
(setq blknam "skimmer")
)
((= n "LIGHT")
(setq blknam "light")
)
((= n "MDXDRAIN")
(setq blknam "main drain")
)
((= n "HLFDRAIN")
(setq blknam "secondary main drain or MDX vent")
)
((= n "DPTHCALL")
(setq blknam "depth markers")
)
((= n "NAWL")
(setq blknam "automatic water leveler")
)
)
(if (setq ss (ssget "X" (list (cons 0 "INSERT")(cons 2 n))))
(princ (strcat "\n " blknam " found < " (itoa (sslength ss)) " > time(s)."))
(ALERT (strcat "\nNo " blknam " found in drawing!"))

)
)
;---;
(princ)
)[/code]
Message 14 of 19
Anonymous
in reply to: mid-awe

You're welcome.

Glad I could help.

Just add the progn(s) and closing parens.

(if (setq ss (ssget "X" (list (cons 0 "INSERT")(cons 2 n))))
(progn
(princ (strcat "\n " blknam " found < " (itoa (sslength ss)) " > time(s)."))
do something else here if found.
) ;end progn
(progn (ALERT (strcat "\nNo " blknam " found in drawing!")))<<<
Do whatever if not found.
) ;end progn
)
Message 15 of 19
Anonymous
in reply to: mid-awe

I don't know whether case is an issue since I haven't studied the thread in detail. But I see your point, so forget what I said. Joe Burke "TRJ" wrote in message news:422f06a1$1_3@newsprd01... > Given. However I do not see where the OP is calling tblsearch in his code. > Did I overlook it? Is case sensitivity possibly why the OP is not finding > his blocks?
Message 16 of 19
Anonymous
in reply to: mid-awe

No your point is well taken and educational. It will benefit someone. "Joe Burke" wrote in message news:422f1540$1_3@newsprd01... > I don't know whether case is an issue since I haven't studied the thread in detail. > > But I see your point, so forget what I said. > > Joe Burke > > "TRJ" wrote in message news:422f06a1$1_3@newsprd01... > > Given. However I do not see where the OP is calling tblsearch in his code. > > Did I overlook it? Is case sensitivity possibly why the OP is not finding > > his blocks? > >
Message 17 of 19
Anonymous
in reply to: mid-awe

You could use the BCOUNT command if all you want to do is count blocks. "MiD-AwE" wrote in message news:97931.1110379603795.JavaMail.jive@jiveforum2.autodesk.com... > Sweet, > > Much better than what I had. My main goal was not to count the number of times the block was found though that is a very useful function, but I needed to check if the block exists in the drawing and this rewrite is excellent for that. I need to develop this into a full featured checker for our work. For about 75% of our drawings there will only be 1 of each of these items in our drawings (swimming pools are considerably different from standard architecture). So, checking for the existence of said blocks will suffice but on our commercial division counting blocks is essential. > > I have made a simple modification of the code to serve both purposes (posted below). Basically, I only added the alert for items not found at all). I'd like to do other functions as well as alert the user if the block is not found at all. > > Thanks again to everyone and especially BillZ who seems to always surprise me with near wizardry of LISP :) > [code](defun c:CHDWG (/ BlkNams blknam) > (setq BlkNams (list "NSKIM" "LIGHT" "MDXDRAIN" "HLFDRAIN" "DPTHCALL" "NAWL") > ) > ;---; > (foreach n BlkNams > (cond ((= n "NSKIM") > (setq blknam "skimmer") > ) > ((= n "LIGHT") > (setq blknam "light") > ) > ((= n "MDXDRAIN") > (setq blknam "main drain") > ) > ((= n "HLFDRAIN") > (setq blknam "secondary main drain or MDX vent") > ) > ((= n "DPTHCALL") > (setq blknam "depth markers") > ) > ((= n "DPTHCALL") > (setq blknam "automatic water leveler") > ) > ) > (if (setq ss (ssget "X" (list (cons 0 "INSERT")(cons 2 n)))) > (princ (strcat "\n " blknam " found < " (itoa (sslength ss)) " > time(s).")) > (ALERT (strcat "\nNo " blknam " found in drawing!")) > > ) > ) > ;---; > (princ) > )[/code]
Message 18 of 19
mid-awe
in reply to: mid-awe

Thanks again 🙂
Message 19 of 19
mid-awe
in reply to: mid-awe

In this method of block checking, how can I excuse a missing block if another is found instead. For instance, how can I ignore the fact that "NSKIM" is missing from the drawing so long as "MDXDRAIN" exists in the drawing?

Thank you.

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

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report