I have a number lisp programs that work fine for modifying or inserting values into blocks with attributes but they all fail if you select blocks without attributes. How would you prevent a program from selecting blocks without attributes?
;copyright Rod Borland, London 2001
;Set object
(defun restore () ;restore variables
(setq *error* olderr)
(princ)
)
(defun trap (er) ;error trapping
(princ "\nPROGRAM ABORTED ")
(princ er)
(setq *error* olderr)
(princ)
)
(defun c:setobject (/ ss ct sl e1 e2 ck sl ctr)
(graphscr)
(setq olderr *error*
*error* trap)
(if (equal users5 nil)
(setq users5 "1"))
(prompt"\nObject No.. <")
(princ users5)
(princ ">")
(setq ctch5 (getstring))
(if (not (equal ctch5 ""))(setq users5 ctch5))
(setq object users5)
(prompt "\nPick your Blocks..")
(setq ss (ssget '((0 . "insert")))
sl (sslength ss)
ct 0
ctr 0)
(repeat sl
(setq e1 (ssname ss ct))
(setq ck 2)
(while (not (equal ck "SEQEND"))
(setq e1 (entnext e1)
e2 (entget e1)
ck (cdr (assoc 0 e2)))
(if (= (cdr (assoc 2 e2)) "OBJECT")
(progn
(setq e2 (subst (cons 1 object)(assoc 1 e2)e2))
(entmod e2)
(entupd e1)
)
)
)
(setq ct (+ ct 1))
)
(princ ct)
(princ " Blocks were changed to object: ")
(princ object)
(restore)
)
*************************
Then for selecting through the database without picking using (setq ss (ssget "_X" (list (cons 0 "INSERT" ) the same thing happens. A real pain! The programs all work fine if all the blocks in the drawing have attributes. It would be a big help if this could be sorted out please! P.S. sorry about the badly composed lisp but I have been doing it badly for ages.
And it seems I cannot attach an AutoCAD drawing because I get "The contents of the attachment doesn't match its file type." although it is a dwg and its filename is test.dwg
Solved! Go to Solution.
Solved by hmsilva. Go to Solution.
Solved by dbroad. Go to Solution.
Hi I get this error message when loading it into AutoCAD
"; error: bad argument type: fixnump: nil"
It does not seem to like (66 . 1)
"; error: bad argument type: fixnump: nil"
means that a function neads a numerical argument and is receiving a nil...
Has nothing to do with (66 . 1)
Henrique
Rob,
As hmsilva states, the error has nothing to do with the additional filter EXCEPT if the extra filter results in a null selection set.
So change
...
(setq ss (ssget '((0 . "insert")(66 . 1)))
sl (sslength ss)
ct 0
ctr 0)
(repeat sl
...
to
....
(if
(setq ss (ssget '((0 . "insert")(66 . 1))))
(progn
(setq
sl (sslength ss)
ct 0
ctr 0)
(repeat sl
....
))
..
Always check for the existance of a selection set before either checking the length of the selection set or a loop based on that count.
Tested without error, some minor modifications
(defun restore ();restore variables (setq *error* olderr) (princ) ) (defun trap (er);error trapping (princ "\nPROGRAM ABORTED ") (princ er) (setq *error* olderr) (princ) ) (defun c:setobject (/ ss ct sl e1 e2 ck sl ctr) (graphscr) (setq olderr *error* *error* trap ) (if (equal users5 nil) (setq users5 "1") ) (prompt "\nObject No.. <") (princ users5) (princ ">") (setq ctch5 (getstring)) (if (not (equal ctch5 "")) (setq users5 ctch5) ) (setq object users5) (prompt "\nPick your Blocks..") (if (setq ss (ssget '((0 . "INSERT") (66 . 1)))) (progn (setq sl (sslength ss) ct 0 ctr 0 ) (repeat sl (setq e1 (ssname ss ct)) (setq ck 2) (while (not (equal ck "SEQEND")) (setq e1 (entnext e1) e2 (entget e1) ck (cdr (assoc 0 e2)) ) (if (= (cdr (assoc 2 e2)) "OBJECT") (progn (setq e2 (subst (cons 1 object) (assoc 1 e2) e2)) (entmod e2) (entupd e1) (setq ct (+ ct 1)) ) ) ) ) (princ ct) (princ " Blocks were changed to object: ") (princ object) ) ) (restore) )
HTH
Henrique
You guys are awesome, I wish I understood lisp that well, but the test first is perfect so that you anly process the blocks that fit the test, which is exactly what I need. Great thanks, will check it first thing tomorrow morning....
Henrique beat me to it
Since I've already written the code, I may as well post my suggestion:
(defun c:setobject ( / *error* cnt ent enx idx num sel tmp ) (defun *error* ( msg ) (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")) (princ (strcat "\nError: " msg)) ) (princ) ) (if (null num) (setq num 1)) (initget 6) (if (setq tmp (getint (strcat "\nObject number <" (itoa num) ">: "))) (setq num tmp) ) (setq cnt 0) (if (setq sel (ssget "_:L" '((0 . "INSERT") (66 . 1)))) (repeat (setq idx (sslength sel)) (setq ent (entnext (ssname sel (setq idx (1- idx)))) enx (entget ent) ) (while (= "ATTRIB" (cdr (assoc 0 enx))) (if (= "OBJECT" (strcase (cdr (assoc 2 enx)))) (if (entmod (subst (cons 1 (itoa num)) (assoc 1 enx) enx)) (progn (entupd ent) (setq cnt (1+ cnt)) ) ) ) (setq ent (entnext ent) enx (entget ent) ) ) ) ) (if (< 0 cnt) (princ (strcat "\n" (itoa cnt) (if (= 1 cnt) " block was" " blocks were") " changed to Object " (itoa num) ) ) (princ "\nNo blocks were modified.") ) (princ) )
Awesome I have just got back in front of my computer and your program works perfectly Henrique, its also closer to mine so will go with that. I also want to use it without the block selection process ie picking the blocks and searching the whole drawing instead but should be able to do that now. Great thanks!!!
And thank you too Lee Mac, I will print yours out and study it and learn a bit more about lisp from it.
You're welcome Rod - if you have any questions about the code, just ask.