ERROR Converting (command) calls to (command-s) is recommended.

ERROR Converting (command) calls to (command-s) is recommended.

sunlight1
Enthusiast Enthusiast
2,312 Views
11 Replies
Message 1 of 12

ERROR Converting (command) calls to (command-s) is recommended.

sunlight1
Enthusiast
Enthusiast

hi, 

im trying to write a lisp that insert blocks fast by name with default settings (scale, angel etc) 

if im writing the name of the block ok, everything is fine. (and i have no error)

but if im wrong, the lisp repeat itself like i wanted, 

and even im writing ok, insert the block, all good. 

after that i get an error

"Can't find file in search path:"

**here is a list of all my search paths**

"error: Function cancelled
Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended.
Command: *Cancel*"

why  i get that? 
i thought if the 2nd time i do write the name of the block right, it wouldnt get me that error.

(defun c:IB (/ Bname )
		(setq Bname (getstring "enter block name: "))
		(if
			(null (findfile (strcat Blocks_path Bname ".dwg")))
			(progn
				(alert (strcat "Can't find  " Bname ".dwg in BLOCKS folder"
				"\nPlease try again"))
				(c:IB)
			);progn
		);if
		(command "_.insert" (strcat Blocks_path Bname ".dwg") pause)
		(while (> (getvar "CMDACTIVE") 0)
			(command "")	  
		);while
		(command ".explode" (entlast))
	(princ)
	);defun

 

Bname - is the block name 

Blocks_path - is my blocks path folder already set in my accaddoc file 

 

tnx for ure help 😃 

 

 

 

0 Likes
Accepted solutions (1)
2,313 Views
11 Replies
Replies (11)
Message 2 of 12

Kent1Cooper
Consultant
Consultant

If you close AutoCAD and start over, and run no other routines before you try this, does it still give you that error?  I suspect you have some other AutoLisp routine that sets an *error* handler involving some (command) function(s), which has been frowned upon since [I think] Acad 2015, but only within custom *error* handlers.  A routine with a faulty one must not be setting AutoCAD's regular one back properly, but restarting should.  If that fixes it, any routines that have *error* handling should be corrected to assure they properly reset AutoCAD's.

Kent Cooper, AIA
0 Likes
Message 3 of 12

ВeekeeCZ
Consultant
Consultant
Accepted solution

Not sure about your error but this recursive calling of yours is definitely not right. You can think of why.

Edit: I did not read your issue carefully - your issue actually is the wrong usage of recursive calling.

 

Say, you typed the wrong name. The routine re-calls itself. Now you type the right one (for simplicity). The routine will go thru to the end successfully. But after that, it continues to evaluate the rest of the routine from the initial wrong-name run.

 

(defun c:IB (/ Bname )
  (setq Bname (getstring "enter block name: "))
  (if
    (null (findfile (strcat Blocks_path Bname ".dwg")))
    (progn
      (alert (strcat "Can't find  " Bname ".dwg in BLOCKS folder"
		     "\nPlease try again"))
      (c:IB) ; it runs itself from here, and when is done, continues from here to finish the code
      );progn
    );if
  (command "_.insert" (strcat Blocks_path Bname ".dwg") pause)
  (while (> (getvar "CMDACTIVE") 0)
	   (command "")
	   );while
    (command ".explode" (entlast))
    (princ)
    );defun

Then it fails on Bname still holding a wrong name - since it's localized it's not overwritten by the correct one from the new run.

 

 

Spoiler alert!

(defun c:IB (/ Bname )
  
  (while (not (and (setq Bname (getstring t "Enter block name: "))
		   (or (findfile (strcat Blocks_path Bname ".dwg"))
		       (alert (strcat "Can't find  " Bname ".dwg in BLOCKS folder" "\nPlease try again"))))))
  
  (command "_.insert" (strcat Blocks_path Bname ".dwg") "_s" 1 "_r" 0 pause)
  (while (> (getvar "CMDACTIVE") 0) (command ""))
  (command ".explode" (entlast))
  (princ)
  )

 

0 Likes
Message 4 of 12

Sea-Haven
Mentor
Mentor

The other option is also add is this block in dwg already, (tblsearch "block" bname).

 

If you wrap your enter block name in a while you can exit by say press Enter when you get frustrated with wrong answers. 

(while (/= (setq Bname (getstring "\nenter block name: ")) "")

 

0 Likes
Message 5 of 12

ВeekeeCZ
Consultant
Consultant

Now, a challenge for ya. Why this code, still using a recursive call, is working just fain...

 

(defun c:IB (/ Bname )
  
  (setq Bname (getstring "enter block name: "))
  
  (if (or (findfile (strcat Blocks_path Bname ".dwg"))
	  (alert (strcat "Can't find  " Bname ".dwg in BLOCKS folder"
			 "\nPlease try again"))
	  (c:IB))
    (command "_.insert" (strcat Blocks_path Bname ".dwg") "_s" 1 "_r" 0 pause
	     ".explode" (entlast)))
  
  ; (princ)
  );defun

 

0 Likes
Message 6 of 12

sunlight1
Enthusiast
Enthusiast

first of all i was busy on the weekend, so im sorry that i couldnt answer faster. 

@Kent1Cooper  i did restart and the problem didnt go anywhere. 

@ВeekeeCZ  

first of all i knew that "(c:IB)"  is probably a wrong way to go with. 

but i couldnt think of another way, myb i went for the "short lazy way" 

this is intersting what ure saying

since Bname is localized,  combine with recall IB  im ending with 2 different lisps 

1 successfully closed and 1 still open with a  wrong value. 

what a mess =(

i wont go with recalling again. 

anyway, ure spoiler is working tnx. thats a better way to do it

and for ure last messege - its working fine cos u use OR, which is filtering all wrong values of Bname and stuck them in the IF.

only 1 TRUE  Bname will send him free to the insert command, 

while i went on the NULL "way" ,  collected all the wrong values and activate PROGN on them and sent them free from the loop with calling IB again. 

i hope i got it. 

BTW u have ";" at the (princ) 🙂

 

0 Likes
Message 7 of 12

ВeekeeCZ
Consultant
Consultant

Ok, ok, you're good!!

 

 

 


@sunlight1 wrote:

BTW u have ";" at the (princ) 🙂


Yeap! That's the one! The challenge. Why I did do it? And can you fix it for me? It's not nice. 🤔

0 Likes
Message 8 of 12

sunlight1
Enthusiast
Enthusiast

@ВeekeeCZ 

no im not THAT good. 

im still learning, started 8 months ago fron 0 lol so far i know how the code goes, but sometimes not the details. 

so plz explain why did u do it. 

i know princ at the end came to clear the end line 

but why in ure code if i use princ it will get error?  
i tried to search about it but no luck. 

i guesss shame on me if u thought i know that 

i just pointed on the ";" cos u didnt activated the (princ), i thought the princ should be there. 

while the opposite is correct.

 

0 Likes
Message 9 of 12

ВeekeeCZ
Consultant
Consultant

No worries. Called it a challenge for a reason.

 

Here's a hint for you: (and (princ)) 

0 Likes
Message 10 of 12

sunlight1
Enthusiast
Enthusiast

ok i got it. 

but now please explain to me what true about that princ? or why he has to be inside ? 
and my lisp still returns nil at the end? is that cos the "and" returns nil? 
so basictly ill always get nil in that lisp structure. (i dont care much but just for explaining what happend here) 

p.s- acording to that lisp below , i dont need the while  CMDACTIVE-0 from my post? seems to me that its working just fine, even on Dynamic blocks 

(defun c:IB (/ Bname ) ;insert block by name
	(setq Bname (getstring "enter block name: "))
	(and 
		(if (or (findfile (strcat Blocks_path Bname ".dwg"))
			(alert (strcat "Can't find  " Bname ".dwg in BLOCKS folder"
						 "\nPlease try again"))
			(c:IB))
			(command "_.insert" (strcat Blocks_path Bname ".dwg") "_s" 1 "_r" 0 pause
					 ".explode" (entlast))
		);if
	(princ)
	);and
);defun

 

0 Likes
Message 11 of 12

ВeekeeCZ
Consultant
Consultant

@ВeekeeCZ wrote:

Now, a challenge for ya. Why this code, still using a recursive call, is working just fain...

 

(defun c:IB (/ Bname )
  
  (setq Bname (getstring "enter block name: "))
  
  (if (or (findfile (strcat Blocks_path Bname ".dwg"))
	  (alert (strcat "Can't find  " Bname ".dwg in BLOCKS folder"
			 "\nPlease try again"))
	  (c:IB))
    (command "_.insert" (strcat Blocks_path Bname ".dwg") "_s" 1 "_r" 0 pause
	     ".explode" (entlast)))
  
  ; (princ)
  );defun

 


 

 

Remember, any value but nil, is True.

 

 

So, when it's returning from the second run to finish the first one, you need to make sure that (c:IB) returns nil, -> OR=nil, IF=nil, therefore it's not inserting any other block.

 

(c:IB) function returns the value of the last expression inside. In this case, it was (princ), which is T. If (princ) is commented out, then the last one would be IF. And IF would return:

 

- if the condition statement of IF is T, it returns T/nil of THEN statement, which is (command...) which returns always nil.

- if cond of IF is nil, and there is no ELSE statement, then the result is nil (never happens in this case)

- if cond of IF is nil, and there is some ELSE statement, it returns T/nil of ELSE (irrelevant for this case).

 

 

So... another possible solution is:

(defun c:IB (/ Bname )
  
  (setq Bname (getstring "enter block name: "))
  
  (if (or (findfile (strcat Blocks_path Bname ".dwg"))
	  (alert (strcat "Can't find  " Bname ".dwg in BLOCKS folder"
			 "\nPlease try again"))
	  (not (c:IB))
	  )
    (command "_.insert" (strcat Blocks_path Bname ".dwg") "_s" 1 "_r" 0 pause
	     "_.explode" (entlast)))
  
  (princ)
  )

 

Your solution....It's a mess that luckily works and you have no idea why.

0 Likes
Message 12 of 12

sunlight1
Enthusiast
Enthusiast

its a mess right lol

but after ure explanation, i know what i didnt knew before

that i had to ensure c:IB is nil before the end. 

after u said it, i know why my lisp is working. 

my last expression is AND which has IF and PRINC 

the IF will always return NIL cos the THEN is a command that always returns NIL. 

so the AND will always return NIL. 

then c:IB will get NIL. 

 

yea, i didnt know that, thats why i asked for an explanation. 

tnx for the challenge it was great !