Jump to content

Error While Running Lisp More Than 2 Times


bijoyvm

Recommended Posts

Hi,

The below lisp code is to import points from a txt file. In this file I am facing an error , like when I run this lisp for the first time it does its job properly, but when I delete the points and run it again, some points are not placed in correct coordinate. If anyone has an idea about correcting this issue please let me know.

Please down load attached txt files for coordinate and check the points 08, 29,30, 39 etc

;; ----------------------------------sub function error--------------------------------

(defun trap1 (errmsg)
          (setvar "attdia" ad)
   (setvar "attreq" aq)
          (setq *error* temperr)
          (prompt "\n *** File not Found or Incorrect Format ***")
(princ)
) ;defun
;;-----------------------------------sub function to create block-----------------------

;;;--- create block function -----
(defun crb ( )
   
   (if (not (tblsearch "BLOCK" "CRBLK"))
       (progn
           (if (not (tblsearch "STYLE" "Gen-Text"))
               (entmake
                   (list
                       (cons 0 "STYLE")
                       (cons 100 "AcDbSymbolTableRecord")
                       (cons 100 "AcDbTextStyleTableRecord")
                       (cons 2 "Gen-Text")
                       (cons 70 0)
                       (cons 40 2.5)
                       (cons 3 "Arial.ttf")
                   )
               )
           )
           (entmake
               (list
                   (cons 0 "BLOCK")
                   (cons 8 "0")
                   (cons 370 0)
                   (cons 2 "CRBLK")
                   (cons 70 2)
                   (cons 4 "Block to Place Coordinate Points")
                   (list 10 0.0 0.0 0.0)
               )
           )
           (entmake
               (list
                   (cons 0 "CIRCLE")
                   (cons 8 "0")
                   (cons 370 0)
                   (list 10 0.0 0.0 0.0)
                   (cons 40 1.25)
               )
           )
           (entmake
               (list
                   (cons 0 "ATTDEF")
                   (cons 8 "0")
                   (cons 370 0)
                   (cons 7 "Gen-Text")
                   (list 10 3.0 2.5 0.0)
                   (list 11 3.0 2.5 0.0)
                   (cons 40 2.5)
                   (cons 1 "00")
                   (cons 3 "Coordinate Point")
                   (cons 2 "00")
                   (cons 70 0)
                   (cons 72 0)
                   (cons 74 2)
               )
           )
           (entmake
               (list
                   (cons 0 "ENDBLK")
                   (cons 8 "0")
               )
           )
           
  ;;;--- To set block units in metre 70-6
              
               (
                   (lambda ( lst )
                       (regapp "ACAD")
                       (entmod
                           (append (subst (cons 70 6) (assoc 70 lst) lst)
                               (list
                                  (list -3
                                      (list "ACAD"
                                          (cons 1000 "DesignCenter Data")
                                          (cons 1002 "{")
                                          (cons 1070 1)
                                          (cons 1070 1)
                                          (cons 1002 "}")
                                      )
                                  )
                              )
                           )
                       )
                   )
                   (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" "CRBLK")))))
               )
            
;;;--- To make block annotative
          
          (
               (lambda ( lst )
                   (regapp "ACAD")
                   (regapp "AcadAnnotative")
                   (entmod
                       (append (subst (cons 70 1) (assoc 70 lst) lst)
                           (list
                              (list -3
                                  (list "ACAD"
                                      (cons 1000 "DesignCenter Data")
                                      (cons 1002 "{")
                                      (cons 1070 1)
                                      (cons 1070 1)
                                      (cons 1002 "}")
                                  )
                                  (list "AcadAnnotative"
                                      (cons 1000 "AnnotativeData")
                                      (cons 1002 "{")
                                      (cons 1070 1)
                                      (cons 1070 1)
                                      (cons 1002 "}")
                                  )
                              )
                          )
                       )
                   )
               )
               (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" "CRBLK")))))
           )
       )
   )
  
;;;--- to disable allow explod-----
  
         (vl-load-com)
         (setq BLOCKS
         (vla-get-Blocks
          (vla-get-activedocument
           (vlax-get-acad-object)
          )
         )
        BLK (vla-Item BLOCKS "CRBLK")
      )
     (vla-put-explodable (vla-Item BLOCKS "CRBLK") :vlax-false)   

  (princ)
)
;;;--- create function block end -----


;; ----------------------------------Sub function--------------------------------
(DEFUN IMPPS (/ TXTF)
 (SETQ TXTF (GETVAR "dwgname"))
 (IF (WCMATCH (STRCASE TXTF) "*`.DWG")
     (SETQ
     TXTF
     (STRCAT (GETVAR "dwgprefix") TXTF)
     TXTF
     (SUBSTR TXTF 1 (- (STRLEN TXTF) 4))
   ) 
 )
 TXTF
)

;; ----------------------------------Main function--------------------------------
(defun C:IMPO (/ CRDS ENCR ENNO ENNO1 CRPT DATA)
          (command "cmdecho"0)
          (setq clay (getvar "clayer"))
          (setq ad (getvar "attdia"))
          (setq aq (getvar "attreq"))
          (setq temperr *error*)
          (setq *error* trap1)
          (setvar "attdia" 0)
          (setvar "attreq" 1)

  (SETQ Data (GETFILED "Select Text File to Import" (IMPPS) "" 0))
  (SETQ CRDS (OPEN Data "r"))

  (setq ENCR 0)
  (command "UCS" "WORLD")
 
(while (/= ENCR nil)
     (setq ENCR (read-line CRDS)) ;Read ENCR from input file
     
    
(if (/= ENCR nil)
        (progn
           (crb) ;create block            
           (setq ENCR (strcat "(" ENCR ")")) ;Correct format
           (setq ENCR (read ENCR))           ;Convert to list
           (setq ENNO (nth 0 ENCR))          ;Get the CRPT number
      (cond 
            ((= (type ENNO) 'STR)       
             (setq ENNO1 ENNO)
            )
            ((and (< ENNO 10.0)(= (type ENNO) 'INT))       
                  (setq ENNO1 (strcat "0" (rtos ENNO 2 0)))
            )
            ((and (>= ENNO 10.0)(= (type ENNO) 'INT))       
                  (setq ENNO1 (rtos ENNO 2 0))
            )
       
     
       ) ;cond
           
           (setq CRPT
              (list                  
                 (nth 1 ENCR) ;Get easting
                 (nth 2 ENCR) ;Get northing
              )
           )
;create new layer 
          (if (not (tblsearch "layer" "Coordinate Points")) (command "-LAYER" "N" "Coordinate Points" "C" "7" "Coordinate Points" "LT" "Continuous" "Coordinate Points""LW" "0.00" "Coordinate Points" ""))      
          (command "CLAYER" "Coordinate Points")                      
          (command "-insert" "CRBLK" CRPT "1" "1" "0" ENNO1)           
       )
     )
  )
  
  (command "UCS" "P")   
  (setvar "clayer" clay)
  (close CRDS)
  (prompt "\n Zoom Extend to View All Points")
) ;defun

(prompt "\nLisp Command:IMPO (to Import Coordinates Points)   ")

Sample TXT file with Name.txt

Sample TXT file.txt

Link to comment
Share on other sites

The issue is from auto OSNAP and the use of command call in your routine. It is also related to current zoom level, thus the error doesn't occur every time. Please fix this line as below:

(command "-insert" "CRBLK" [color=red]"_NON"[/color] CRPT "1" "1" "0" ENNO1)

Link to comment
Share on other sites

An oldie but it works use on most of my routines saves problems like above

 

:at start
(setq oldsnap (getvar "osmode"))
(setvar "osmode" 0)
.
.
.
; at end 

(setvar "osmode" oldsnap)

Link to comment
Share on other sites

BIGAL, this is exactly what I’m using for my routines too, but for cases like OP’s one (only a single command call) I prefer the "_NON" OSNAP mode instead due to simplicity.

Link to comment
Share on other sites

... Beware of *error*. :thumbsup:

 

Yeah, error handling is more overhead, but many users at my work think pressing escape repeatedly is how you properly terminate a command... :roll:, thusly:

 

Psuedo code:

(defun c:FOO (/ *error*)
 (vl-load-com)

 (defun *error*  (msg)
   (and oldNomutt (setvar 'nomutt oldNomutt))
   (if acDoc (vla-endundomark acDoc))
   (cond ((not msg))                                                   ; Normal exit
         ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
         ((princ (strcat "\n** Error: " msg " ** "))))                 ; Fatal error, display it
   (princ))

 ((lambda (acDoc oldNomutt / ss)
    (vla-startundomark acDoc)
    (if (and (princ "\nMy custom select prompt: ")
             (setvar 'nomutt 1)
             (setq ss (ssget)))
      (progn
        ;; <- Do something
        (*error* nil))
      (*error* "Nothing selected")))
   (vla-get-active-document (vlax-get-acad-object))
   (getvar 'nomutt)))

Link to comment
Share on other sites

Yeah, error handling is more overhead, but many users at my work think pressing escape repeatedly is how you properly terminate a command... :roll:, thusly:

 

:o What? you mean its not? :lol:

 

I know that so well Renderman, one user i know presses the 'Esc key about a hundred tiems per minute (average) the key itself is worned out.

 

I myself is guilty of not including an error routine on my codes.

 

I noticed you've been using this construct quite frequently on your code these days.

((lambda (acDoc oldNomutt / ss)
    (vla-startundomark acDoc)....
      .....(vla-get-active-document (vlax-get-acad-object))
   (getvar 'nomutt)))

 

I ddint understand it at first, and then it clicked :thumbsup:

Link to comment
Share on other sites

Another reason to use the "_NON" instead of setting and resetting the OSMode (as Mircea suggests) ... no need for an error trap to reset it back since it was never changed to begin with.

 

Don't get me wrong, an *error* routine is a must in many instances. I just think adding such plus the OSMode set and reset is factors of extra coding over adding a "_NON" into your command call.

Link to comment
Share on other sites

Another reason to use the "_NON" instead of setting and resetting the OSMode (as Mircea suggests) ... no need for an error trap to reset it back since it was never changed to begin with.

 

Don't get me wrong, an *error* routine is a must in many instances. I just think adding such plus the OSMode set and reset is factors of extra coding over adding a "_NON" into your command call.

 

1+ Especially if OSMODE is the only setting you are intending to change, and furthermore if the "_non" method is only going to be used a few times in the program so as not to render the code unreadable.

 

Another serious issue to consider is the order in which System Variables are being reset (either in the *error* handler, or at the completion of code) relative to the start and end of Undo Groups.

 

Since, when the user performs an Undo operation, all operations after the end of the last Undo group are undone before the Undo group itself is also undone. Depending on the order in which Undo Groups are closed and System Variables are reset, this can result in System Variables being changed when the user performs an Undo operation.

 

Some example code to illustrate my point:

([color=BLUE]defun[/color] c:GoodbyeOSnap ( [color=BLUE]/[/color] *error* doc osm p1 p2 )

   [color=GREEN];; Error Handler[/color]
   ([color=BLUE]defun[/color] *error* ( msg )
       ([color=BLUE]if[/color] doc ([color=BLUE]vla-endundomark[/color] doc)) [color=GREEN];; Close open Undo Group[/color]
       ([color=BLUE]if[/color] osm ([color=BLUE]setvar[/color] 'osmode osm))  [color=GREEN];; Reset OSMODE[/color]
       ([color=BLUE]if[/color] ([color=BLUE]not[/color] ([color=BLUE]wcmatch[/color] ([color=BLUE]strcase[/color] msg) [color=MAROON]"*BREAK,*CANCEL*,*EXIT*"[/color])) [color=GREEN];; If the msg is not trivial[/color]
           ([color=BLUE]princ[/color] ([color=BLUE]strcat[/color] [color=MAROON]"\nError: "[/color] msg)) [color=GREEN];; Print critical errors[/color]
       ) [color=GREEN];; End if[/color]
       ([color=BLUE]princ[/color]) [color=GREEN];; Exit Cleanly[/color]
   ) [color=GREEN];; End defun[/color]
   
   ([color=BLUE]setq[/color] osm ([color=BLUE]getvar[/color] 'osmode)) [color=GREEN];; Store OSMODE setting[/color]
   ([color=BLUE]setvar[/color] 'osmode 1) [color=GREEN];; Set OSMODE to Endpoint[/color]

   ([color=BLUE]if[/color]
       ([color=BLUE]and[/color]
           ([color=BLUE]setq[/color] p1 ([color=BLUE]getpoint[/color] [color=MAROON]"\n1st Point: "[/color]))
           ([color=BLUE]setq[/color] p2 ([color=BLUE]getpoint[/color] [color=MAROON]"\n2nd Point: "[/color] p1))
       ) [color=GREEN];; End and[/color]
       ([color=BLUE]progn[/color]
           ([color=BLUE]vla-startundomark[/color] ([color=BLUE]setq[/color] doc ([color=BLUE]vla-get-activedocument[/color] ([color=BLUE]vlax-get-acad-object[/color])))) [color=GREEN];; Start Undo Group[/color]
           ([color=BLUE]entmake[/color] ([color=BLUE]list[/color] '(0 . [color=MAROON]"LINE"[/color]) ([color=BLUE]cons[/color] 10 p1) ([color=BLUE]cons[/color] 11 p2))) [color=GREEN];; Construct a Line from the two points[/color]
           ([color=BLUE]vla-endundomark[/color] doc) [color=GREEN];; End Undo Group[/color]
       ) [color=GREEN];; End progn[/color]
   ) [color=GREEN];; End if[/color]
   
   ([color=BLUE]setvar[/color] 'osmode osm) [color=GREEN];; Reset OSMODE[/color]
   ([color=BLUE]princ[/color]) [color=GREEN];; Exit Cleanly[/color]
) [color=GREEN];; End defun[/color]
   

The above code will prompt the user to pick two points with Object Snap forced to Endpoint, then construct a Line between those two points.

 

On the surface, all looks fine: OSMODE is stored before being changed and reset at the end of the code and within the *error* handler; an Undo group is started before the Line is constructed and closed following this operation and also in the *error* handler. However, try running the code, then performing an Undo to remove the created Line...

 

Furthermore, if the program throws an error for an operation within the Undo Group, although the code is equipped with an *error* handler to close the Undo group and reset System Variables, if the user decides to use Undo, the same issues will arise.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...