liuhaixin88 发表于 2022-7-5 23:02:39

Lee, Ask for advice.

This code can judgment “dim” layer , if not exist ,built it ,if alread exist ,set it to current Layer. I can put it in front of the other programs.
 

(if (not (tblsearch "LAYER" "dim"))   (entmake '((0 . "LAYER") (100 . "AcDbSymbolTableRecord") (100 . "AcDbLayerTableRecord") (2 . "dim") (70 . 0) (62 . 3) (6 . "Continuous")))   (prompt "\nLayer : \"dim\" already exist - setting it to current and proceeding with routine...") ) (setvar 'clayer "dim")
 
But I want: At the end of the program , and then change back to the previous layer.
When use "ESC" key to exits or Error exits, change back to the previous layer too.
 
How to do this? Thanks!

Tharwat 发表于 2022-7-5 23:10:22

Try this routine
 

(defun c:Test (/ *error* cl) (defun *error* (msg)   (if cl   (setvar 'clayer cl)   )   (if (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")   (princ msg)   (princ (strcat "\n** Error: " msg " **"))   ) ) (setq cl (getvar 'clayer)) (if (not (tblsearch "LAYER" "dim"))   (progn (entmake '((0 . "LAYER")                     (100 . "AcDbSymbolTableRecord")                     (100 . "AcDbLayerTableRecord")                     (2 . "dim")                     (70 . 0)                     (62 . 3)                     (6 . "Continuous")                  )          )          (setvar 'clayer "dim")   )   (setvar 'clayer "dim") ) (setvar 'clayer cl) (princ))

Bhull1985 发表于 2022-7-5 23:15:37

In order to save user settings a certain way if a routine is loaded and executed- and specifically, if it fails during running, as OP mentioned "escaping" out...
These all require use of an error handler from within the autolisp program.
Typically error handlers are defined just under the main function for the routine and will accept one argument, that for MSG. Most of these error handlers will prompt the message when an error occurs, displaying it to the user, as well as execute any additional code found within the error handler, which is where you'd put such code to restore the clayer to a specific layer, it's where you'd ensure that system variables are reset as well.
You can see in tharwats example that is exactly what he has done

(defun *error* (msg)   (if cl   (setvar 'clayer cl)   )   (if (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")   (princ msg)   (princ (strcat "\n** Error: " msg " **"))   ) )
Can see this code to do exactly two things. One is to display a message using (WCMATCH), (princ) and (strcat), and the other is to check if the variable exists in the routine called CL
If this variable is found to have a value then set the clayer system variable to that value. Cursory glances would have me think that upon changing the layer in the non-error-handling part of that code, just before the clayer is changed that there is a call to (setq cl (getvar "clayer")) in order to establish that variable into the systems memory for later use or for restoring via the error handler.
 
HTH
 
Edit: Yes in fact it's the very first line after the error handler. Guess he got right to the point

liuhaixin88 发表于 2022-7-5 23:21:26

 
Tharwat,Thank you for your hard work !!!
 
If I want add your routine to following code , how do to?
 

(defun c:2ptri ( / d1 d2 p1 p2 p3 p4 p5 v1 v2 x1 )   (if (and (setq p1 (getpoint "\n1st point: "))            (setq p2 (getpoint "\n2nd point: " p1))            (setq v1 (trans(mapcar '- p1 p2) 1 0 t)                  v2 (trans '(0 0 1) 1 0 t)                  d1 (/ (distance p1 p2) 2)                  d2 (/ d1 (sqrt 3))                  p3 (trans p1 1 v1)                  x1 (car p3)            )            (progn                (while (= 5 (car (setq p4 (grread t 13 0))))                  (redraw)                  (setq p5 (trans (list ((if (< x1 (car (trans (cadr p4) 1 v1))) + -) x1 d2) (cadr p3) (- (caddr p3) d1)) v1 1))                  (grdraw p1 p2 1 1)                  (grdraw p1 p5 1 1)                  (grdraw p2 p5 1 1)                )                (list (cadr p4))            )      )      (entmake            (list               '(000 . "LWPOLYLINE")               '(100 . "AcDbEntity")               '(100 . "AcDbPolyline")               '(090 . 3)               '(070 . 1)                (cons 010 (trans p1 1 v2))                (cons 010 (trans p2 1 v2))                (cons 010 (trans p5 1 v2))                (cons 210 v2)            )      )   )   (redraw) (princ))

Tharwat 发表于 2022-7-5 23:26:49

Like this .
 

(defun c:2ptri (/ *error* cl d1 d2 p1 p2 p3 p4 p5 v1 v2 x1) (defun *error* (msg)   (redraw)   (if cl   (setvar 'clayer cl)   )   (if (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")   (princ msg)   (princ (strcat "\n** Error: " msg " **"))   ) ) (setq cl (getvar 'clayer)) (if (not (tblsearch "LAYER" "dim"))   (entmake '((0 . "LAYER")            (100 . "AcDbSymbolTableRecord")            (100 . "AcDbLayerTableRecord")            (2 . "dim")            (70 . 0)            (62 . 3)            (6 . "Continuous")             )   ) ) (setvar 'clayer "dim") (if (and (setq p1 (getpoint "\n1st point: "))          (setq p2 (getpoint "\n2nd point: " p1))          (setq v1 (trans (mapcar '- p1 p2) 1 0 t)                v2 (trans '(0 0 1) 1 0 t)                d1 (/ (distance p1 p2) 2)                d2 (/ d1 (sqrt 3))                p3 (trans p1 1 v1)                x1 (car p3)          )          (progn (while (= 5 (car (setq p4 (grread t 13 0))))                   (redraw)                   (setq p5 (trans (list ((if (< x1 (car (trans (cadr p4) 1 v1)))                                          +                                          -                                          )                                           x1                                           d2                                       )                                       (cadr p3)                                       (- (caddr p3) d1)                                 )                                 v1                                 1                            )                   )                   (grdraw p1 p2 1 1)                   (grdraw p1 p5 1 1)                   (grdraw p2 p5 1 1)               )               (list (cadr p4))          )   )   (entmake (list '(000 . "LWPOLYLINE")                  '(100 . "AcDbEntity")                  '(100 . "AcDbPolyline")                  '(090 . 3)                  '(070 . 1)                  (cons 010 (trans p1 1 v2))                  (cons 010 (trans p2 1 v2))                  (cons 010 (trans p5 1 v2))                  (cons 210 v2)            )   ) ) (redraw) (setvar 'clayer cl) (princ))

liuhaixin88 发表于 2022-7-5 23:31:12

 
Tharwat,Thank you very much !
 
I modify it, test, it's ok ,cool
 

(defun bz ( / *error* clname1 name2 name3) (setq ty (getvar "TEXTSTYLE")) (setq kd1 (caadr (textbox (list '(0 . "text")(cons 1 txt1)(cons 40 300)(cons 41 0.7)(cons 7 ty))))) (setq kd2 (caadr (textbox (list '(0 . "text")(cons 1 txt2)(cons 40 300)(cons 41 0.7)(cons 7 ty))))) (setq kd (max kd1 kd2) kd (+ kd 50)) (setq p (getpoint "\nSpecify the basis points:")) (setq pd t) (while pd   (setq gr (grread t 4 1) mode (car gr) pt (cadr gr))   (if (= kd3 0) (setq kd kd1))   (if (and (listp pt) (>= (car pt) (car p))) (progn   (setq p0 (polar pt 0 kd))   (setq p1 (polar pt 0 (/ (- kd kd1) 2)) p1 (polar p1 (angtof "90") 50))   (setq p2 (polar pt 0 (/ (- kd kd2) 2)) p2 (polar p2 (angtof "270") 350))))   (if (and (listp pt) (< (car pt) (car p))) (progn   (setq p0 (polar pt pi kd))   (setq p1 (polar p0 0 (/ (- kd kd1) 2)) p1 (polar p1 (angtof "90") 50))   (setq p2 (polar p0 0 (/ (- kd kd2) 2)) p2 (polar p2 (angtof "270") 350))))   (if (= mode 5) (progn   (if name1 (entdel name1))   (entmake (list '(0 . "LWPOLYLINE")'(100 . "AcDbEntity")'(100 . "AcDbPolyline")'(90 . 3)       (cons 10 p)(cons 10 pt)(cons 10 p0)))   (setq name1 (entlast))   (if name2 (entdel name2))   (entmake (list '(0 . "text")(cons 1 txt1)(cons 40 300)(cons 41 0.7)(cons 10 p1)(cons 7 ty)))   (setq name2 (entlast))   (if name3 (entdel name3))   (if (= kd3 1) (entmake (list '(0 . "text")(cons 1 txt2)(cons 40 300)(cons 41 0.7)(cons 10 p2)(cons 7 ty))))   (if (= kd3 1) (setq name3 (entlast)))))   (if (= mode 3) (setq pd nil))   (if (or (= mode 2) (= mode 25)) (progn (setq pd nil) (entdel name1) (entdel name2) (if name3 (entdel name3))))) (princ))(defun getdata () (setq txt1 (get_tile "a1")) (setq txt2 (get_tile "a2")) (if (= (get_tile "a3") "0") (setq kd3 0) (setq kd3 1)))(defun c:TEST ()(defun *error* (msg)   (redraw)   (if cl   (setvar 'clayer cl)   )   (if (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")   (princ msg)   (princ (strcat "\n** Error: " msg " **"))   ) ) (setq cl (getvar 'clayer)) (if (not (tblsearch "LAYER" "dim"))   (entmake '((0 . "LAYER")            (100 . "AcDbSymbolTableRecord")            (100 . "AcDbLayerTableRecord")            (2 . "dim")            (70 . 0)            (62 . 3)            (6 . "Continuous")             )   ) ) (setvar 'clayer "dim") (setq tempname (vl-filename-mktemp "temp.dcl") filen (open tempname "w"))(foreach stream   '("yxbz:dialog{"   "\nlabel = "Dynamic lead ";"   "\n:edit_box {key = \"a1\"; label = \"text on the line:\"; width = 40 ;}"   "\n:toggle {key = \"a3\"; label = \"add text under the line\"; value = "0";}"   "\n:edit_box {key = \"a2\"; label = \"text under the line:\"; width = 40; is_enabled = false;}"   "\nok_cancel;}") (princ stream filen)) (close filen) (setq dclname tempname) (setq dcl_re (load_dialog dclname))(if (not (new_dialog "yxbz" dcl_re)) (exit)) (if txt1 (set_tile "a1" txt1) (set_tile "a1" "Dynamic dimension")) (if txt2 (set_tile "a2" txt2) (set_tile "a2" "Dynamic dimension")) (if kd3 (set_tile "a3" (rtos kd3)))(if (= kd3 0) (mode_tile "a2" 1)) (if (= kd3 1) (mode_tile "a2" 0)) (action_tile "a3" "(if (= (get_tile \"a3\") \"0\") (mode_tile \"a2\" 1) (mode_tile \"a2\" 0))")(action_tile "accept" "(getdata)(done_dialog 1)") (action_tile "cancel" "(done_dialog)") (setq std (start_dialog)) (unload_dialog dcl_re) (vl-file-delete dclname) (if (= std 1) (bz))(setvar 'clayer cl) (princ))

Tharwat 发表于 2022-7-5 23:35:44

 
You're very welcome .
 
You can include the name of layer "dim" in every entmake and avoid the use of system variable SETVAR to set the new created layer current although the first example is not considered wrong at all but I am trying to give another example to you to go with if you would like .

liuhaixin88 发表于 2022-7-5 23:40:43

 
Of course, I would like your another example.

liuhaixin88 发表于 2022-7-5 23:45:12

 
Tharwat , I modify this lisp ,Leader can change to "dim" layer ,but Tolerance symbol can't change to "dim" layer, why?
My question is how to change Tolerance symbol to "dim" layer too, and set colour by index color 4 ,not ByLayer.( Leader color is ByLayer ,Tolerance symbol color is by index color4)
 

(defun c:QS (/ *error* DICEN)(defun *error* (msg)   (redraw)   (if cl   (setvar 'clayer cl)   )   (if (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")   (princ msg)   (princ (strcat "\n** Error: " msg " **"))   ) ) (setq cl (getvar 'clayer)) (if (not (tblsearch "LAYER" "dim"))   (entmake '((0 . "LAYER")            (100 . "AcDbSymbolTableRecord")            (100 . "AcDbLayerTableRecord")            (370 . 18)               (2 . "dim")            (70 . 0)            (62 . 3)            (6 . "Continuous")             )   ) ) (setvar 'clayer "dim")(setq DICEN (namedobjdict)) (if (dictsearch DICEN "AcadDim")   (dictremove DICEN "AcadDim") ) (dictadd DICEN          "AcadDim"         (entmakex '((0 . "XRECORD")                     (100 . "AcDbXrecord")                     (280 . 1)                     (90 . 990106)                     (3 . "")                        (60 . 2)                        (61 . 0)                        (62 . 1)                        (63 . 1)                        (64 . 0)                        (65 . 0)                        (66 . 0)                        (67 . 3)                        (68 . 1)                        (69 . 0)                        (70 . 0)                        (71 . 0)                        (72 . 0)                        (40 . 0.0)                     (170 . 2)                      )             )   ) (command "Qleader") (setvar 'clayer cl)(princ))

BIGAL 发表于 2022-7-5 23:49:13

This can be done very easy by not adding all the code but rather making it a Autoloaded defun then you need only 1-2 lines in each program that you create. it would look something like this. Layset is name of defun. You put all your library defuns in the autoload "Acaddoc.lsp" as an example.
(layset layername Ltype Color)or(layset "Dim" "continuous" 3)
页: [1] 2
查看完整版本: Lee, Ask for advice.