How do I make my lisp so that it doesn't stop working when I click nothing

How do I make my lisp so that it doesn't stop working when I click nothing

mkataQU96G
Explorer Explorer
1,006 Views
12 Replies
Message 1 of 13

How do I make my lisp so that it doesn't stop working when I click nothing

mkataQU96G
Explorer
Explorer

I've been trying to add 3 things to my code
1. When the user clicks nothing, the code continues to run and doesn't increment
2. When the user clicks a something that isn't the correct block, it notifies the user to select the correct block
3. The only valid selection is either block "EQP_LBD-CMB" or "Trunk Cable", when the user selects either block it runs and increments.

I've tried a variety of things that I've found on the forums, but none seem to work. Here is my base code:

 

(defun C:EINC (/ *PCS* *block* *EQP* *EQP_Num*)
(vl-load-com)

(setq *PCS* (getstring "\nInput PCS Number: "))
(setq *EQP* (getint "\nInput Equipment Starting Number: "))

(while

(setq *block* (car (entsel "\nSelect Block: ")))

(setpropertyvalue *block* "PCS_NUM" *PCS*)
(setq *EQP_Num* (itoa *EQP*))
(setpropertyvalue *block* "EQP_NUM" *EQP_Num*)
(setq *EQP* (+ *EQP* 1))
)
(princ)
)

 

 

0 Likes
Accepted solutions (1)
1,007 Views
12 Replies
Replies (12)
Message 2 of 13

ВeekeeCZ
Consultant
Consultant

You need to check the ERRNO sysvar.

 

See Lee's example here

https://www.lee-mac.com/selectif.html

 

 

 

BTW, The common formatting style is to use asterisks *variable* only for global variables. As you have all your variables localized...

 

(defun C:EINC (/ *PCS* *block* *EQP* *EQP_Num*)

 

...which is a good and recommended practice, then you should not use asterisks. Use just plain names...  

 

PCS block EQP EQP_Num

0 Likes
Message 3 of 13

mkataQU96G
Explorer
Explorer

Understood, thanks! I'll check out the selectif lisp you recommended

0 Likes
Message 4 of 13

Moshe-A
Mentor
Mentor

@mkataQU96G  hi,

 

Check my version - untested 😀

 

Moshe

 

 

(vl-load-com)

(defun C:EINC (/ *PCS* *block* *EQP* *EQP_Num* pick elist)

 (if (and
      (setq *PCS* (getstring "\nInput PCS Number: "))
      (setq *EQP* (getint "\nInput Equipment Starting Number: "))
     )
  (while (and
	  (setq pick (entsel "\nSelect Block: "))				; pick object
	  (not (member (getvar "errno") '(7 52)))				; yes, object is selected (errno = 7 means empty pick, errno = 52 means ESC or empy enter)
	  (setq elist (entget (setq *block* (car pick))))			; get object database list
	  (eq (cdr (assoc '0 elist)) "INSERT")					; is it a block?
	  (wcmatch (cdr (assoc '2 elist)) "EQP_LBD-CMB,Trunk Cable")	; is it "EQP_LBD-CMB,Trunk Cable"?
	 )
	  
   (setpropertyvalue *block* "PCS_NUM" *PCS*)
   (setq *EQP_Num* (itoa *EQP*))
   (setpropertyvalue *block* "EQP_NUM" *EQP_Num*)
   (setq *EQP* (+ *EQP* 1))
  ); while
 ); if
   
 (princ)
)

 

 

0 Likes
Message 5 of 13

mkataQU96G
Explorer
Explorer

Running it, it exits the command no matter what i click on after i input the equpment and pcs numbers

0 Likes
Message 6 of 13

Moshe-A
Mentor
Mentor

@mkataQU96G ,

 

Sorry, here is fix.

 

i notice that (setpropertyvalue) return error if you pass the propertyname as uppercase string so i switched to lowercase.

as you get more experience you'll learn a more safe method to modify block attributes.

 

Moshe

 

 

 

 

 

(vl-load-com)

(defun C:EINC (/ *PCS* *block* *EQP* *EQP_Num* pick elist)
 (setvar "errno" 0)
  
 (if (and
      (setq *PCS* (getint "\nInput PCS Number: "))
      (setq *EQP* (getint "\nInput Equipment Starting Number: "))
     )
  (while (and
	  (setq pick (entsel "\nSelect Block: "))				; pick object
	  (not (member (getvar "errno") '(7 52)))				; yes, object is selected (errno = 7 means empty pick, errno = 52 means ESC or empy enter)
	  (setq elist (entget (setq *block* (car pick))))			; get object database list
	  (eq (cdr (assoc '0 elist)) "INSERT")					; is it a block?
	  (wcmatch (cdr (assoc '2 elist)) "EQP_LBD-CMB,Trunk Cable")		; is it "EQP_LBD-CMB,Trunk Cable"?
	 )
 
   (setpropertyvalue *block* "pcs_num" (itoa *PCS*))
   (setq *EQP_Num* (itoa *EQP*))
   (setpropertyvalue *block* "eqp_num" (itoa *EQP*))
   (setq *EQP* (+ *EQP* 1))

   (setvar "errno" 0)	 
  ); while
 ); if

 (princ)
)

 

 

 

0 Likes
Message 7 of 13

ec-cad
Collaborator
Collaborator

This model gets you a little further. But, 'and  condition excludes 'Text' or other items like a Line,

if that's selected. So, maybe a 'Filter and SSGET might do it ?

 

ECCAD

 

(vl-load-com)

(defun C:EINC (/ *PCS* *block* *EQP* *EQP_Num* pick elist)
 (setq bn "")
 (setvar "errno" 0)
 (if (and
      (setq *PCS* (getstring "\nInput PCS Number: "))
      (setq *EQP* (getint "\nInput Equipment Starting Number: "))
     );and
  (while (and
   (setq pick (entsel "\nSelect Block: "))                      ; pick object
          (not (member (getvar "errno") '(7 52)))		; yes, object is selected (errno = 7 means empty pick, errno = 52 means ESC or empy enter)
          (setq elist (entget (setq *block* (car pick))))	; get object database list
          (eq (cdr (assoc '0 elist)) "INSERT")			; is it a block?
          (setq bn (strcase (cdr (assoc '2 elist))))            ; get block name
          (setq etype (cdr (assoc 0 elist)))                    ; check entity type of pick
         ); and
         (if pick
          (progn
            (if (/= etype "INSERT")
              (alert "Item Selected is not a Block:")
            ); if
            (if (and (/= bn "TRUNK CABLE")
                     (/= bn "EQP_LBD-CMB")
                ); and
                (alert "Please select the correct Block:")
            ); if
           (if (or (= bn "TRUNK CABLE")(= bn "EQP_LBD-CMB"))
            (progn
             (setpropertyvalue *block* "PCS_NUM" *PCS*)
             (setq *EQP_Num* (itoa *EQP*))
             (setpropertyvalue *block* "EQP_NUM" *EQP_Num*)
             (setq *EQP* (+ *EQP* 1))
            ); progn
            (alert "Please select the correct Block:")
           ); if
          ); progn
         ); if
    (setvar "errno" 0); reset error
  ); while
 ); if
 (princ)
)
0 Likes
Message 8 of 13

paullimapa
Mentor
Mentor
Accepted solution

I'm assuming you want to only select Blocks (named either "EQP_LBD-CMB,Trunk Cable") containing Attributes (Tag names: "PCS_NUM" & "EQP_NUM")

What I would do is use the ssget function that (1) mimics the entsel function & (2) supports filters "_+.:E:S:L" so you can only select a Block on Layer that's not locked with Attributes'((0 . "INSERT") (66 . 1)):

 

(defun C:EINC (/ *PCS* *block* *EQP* *EQP_Num* nam nam-match)
  (if (and
      (setq *PCS* (getstring "\nInput PCS Number: "))
      (setq *EQP* (getint "\nInput Equipment Starting Number: "))
      (setq nam-match "EQP_LBD-CMB,Trunk Cable")
     )
  (while (not *block*)
   (princ"\nSelect Block: ")
   (setq *block* (ssget "_+.:E:S:L"'((0 . "INSERT") (66 . 1)))) ; select only blocks with attributes on unlocked layers
   (if *block*
    (progn
     (setq *block* (ssname *block* 0) ; get entity from selection
           nam (getpropertyvalue *block* "BlockTableRecord/Name") ; get block name
     )
     (if(wcmatch nam nam-match) ; chk for block name match
       (progn ; then
        (setpropertyvalue *block* "PCS_NUM" *PCS*)
        (setq *EQP_Num* (itoa *EQP*))
        (setpropertyvalue *block* "EQP_NUM" *EQP_Num*)
        (setq *EQP* (+ *EQP* 1))
       ) ; progn
       (progn ; else
        (princ(strcat"\nBlock Selected is Named " nam " Does NOT Match..."))
        (setq *block* nil) ; reset selection
       )
     ) ; if
    ) ; progn
   ) ; if 
  ) ; while
 ) ; if
 (princ)
)

 

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 9 of 13

mkataQU96G
Explorer
Explorer

This works exactly how I need it to! I had to add a space between princ and "\nSelect Block: ") in order for it to fully function, but aside from that, it's perfect! thanks!

0 Likes
Message 10 of 13

mkataQU96G
Explorer
Explorer

Thank you all for the support and suggestions! I definitely learned a lot!

0 Likes
Message 11 of 13

paullimapa
Mentor
Mentor

Glad that worked out for you…cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 12 of 13

ec-cad
Collaborator
Collaborator

I tried the last example, and it only does (1) block. Seems to me that you would want to pick several in order

to make use of the 'incrementing' of the *EQP* variable (number), so I suggest something like this,

IF you want to do more than just 1 block..

(defun C:EINC (/ *PCS* *block* *EQP* *EQP_Num* nam nam-match)
 (setq FLAG 0); Set Exit Flag 0
  (if (and
      (setq *PCS* (getstring "\nInput PCS Number: "))
      (setq *EQP* (getint "\nInput Equipment Starting Number: "))
      (setq nam-match "EQP_LBD-CMB,Trunk Cable")
     ); and

  (while (= FLAG 0); While FLAG is still 0
   (princ "\nSelect Block: ")
   (setq *block* (ssget "_+.:E:S:L"'((0 . "INSERT") (66 . 1)))) ; select only blocks with attributes on unlocked layers
   (if (not *block*); must have not picked anything..so set Exit Flag 1
    (setq FLAG 1)
   ); if
   (if *block*
    (progn
     (setq *block* (ssname *block* 0) ; get entity from selection
           nam (getpropertyvalue *block* "BlockTableRecord/Name") ; get block name
     )
     (if (wcmatch nam nam-match) ; chk for block name match
       (progn ; then
        (setpropertyvalue *block* "PCS_NUM" *PCS*)
        (setq *EQP_Num* (itoa *EQP*))
        (setpropertyvalue *block* "EQP_NUM" *EQP_Num*)
        (setq *EQP* (+ *EQP* 1))
       ) ; progn
       (progn ; else
        (princ (strcat"\nBlock Selected is Named " nam " Does NOT Match..."))
        (setq FLAG 1) ; reset exit Flag
       ); progn
     ) ; if
    ) ; progn
   ) ; if 
  ) ; while
 ) ; if
 (princ)
)

 

ECCAD

0 Likes
Message 13 of 13

Sea-Haven
Mentor
Mentor

Why not add the block names to the ssget ?

(setq *block* (ssget "_+.:E:S:L"'((0 . "INSERT")(2 . ""EQP_LBD-CMB,Trunk Cable"")(66 . 1))))

 

0 Likes