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

lisp for modifying block fails if no attributes

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
rodb
618 Views, 12 Replies

lisp for modifying block fails if no attributes

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

 

 

 

 

 

12 REPLIES 12
Message 2 of 13
hmsilva
in reply to: rodb

(setq ss (ssget '((0 . "INSERT")(66 . 1))))

HTH
Henrique

EESignature

Message 3 of 13
rodb
in reply to: hmsilva

Thank you very much, I'll check it out asap......

Message 4 of 13
rodb
in reply to: hmsilva

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)

Message 5 of 13
hmsilva
in reply to: rodb

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

EESignature

Message 6 of 13
dbroad
in reply to: rodb

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.

Architect, Registered NC, VA, SC, & GA.
Message 7 of 13
hmsilva
in reply to: rodb

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

 

EESignature

Message 8 of 13
rodb
in reply to: hmsilva

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....

Message 9 of 13
Lee_Mac
in reply to: rodb

Henrique beat me to it Smiley Wink

 

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)
)
Message 10 of 13
rodb
in reply to: hmsilva

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!!!

Message 11 of 13
rodb
in reply to: Lee_Mac

And thank you too Lee Mac, I will print yours out and study it and learn a bit more about lisp from it.

Message 12 of 13
hmsilva
in reply to: rodb

You're welcome, Rod
Glad I could help

Henrique

EESignature

Message 13 of 13
Lee_Mac
in reply to: rodb

rodb wrote:

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.

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

Post to forums  

Autodesk Design & Make Report

”Boost