PDuMont Posted December 16, 2016 Posted December 16, 2016 Hello All, Can anyone tell me why this routine will not undo as a group? The undo steps back through the routine. Any help would be appreciated. ; CONTINUOUS COPY & ALIGN (defun c:CA (/ *error* cmde doc pt1 pt2 pt3 pt4 sset sset2 mark) (defun *error* (msg) (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")) ) ;_ end of and (princ (strcat "\nError: " msg)) ) ;_ end of if (if cmde (setvar 'cmdecho cmde) ) ;_ end of if (if doc (vla-endundomark doc) ) (princ) ) ;_ end of defun (setq doc (vla-get-activedocument (vlax-get-acad-object))) (vla-startundomark doc) (setq cmde (getvar 'cmdecho)) (setvar 'cmdecho 0) (setq sset (ssget)) (setq pt1 (getpoint "\nPick 1st base point to copy from:")) (setq pt2 (getpoint "\nPick 2nd base point to align from:")) (while (setq pt3 (getpoint "\nPick 1st point to copy TO: <Return to Exit>") ) (setq pt4 (getpoint "\nPick 2nd point for NEW entities:") ) (setq mark (entlast)) (setq sset2 (ssadd)) (command "copy" sset "" "0,0" "0,0") (while (setq mark (entnext mark)) (ssadd mark sset2) ) ;_ end of while (command "align" sset2 "" pt1 pt3 pt2 pt4 "" "n") ) ;_ end of while (setvar 'cmdecho cmde) (vla-endundomark doc) (princ) ) ;_ end of defun (vl-load-com) Quote
tombu Posted December 18, 2016 Posted December 18, 2016 Not sure if case matters, but I've always used vla-StartUndoMark & vla-EndUndoMark. Could using mark as a local variable be causing an issue as in undo to mark? Quote
Lee Mac Posted December 18, 2016 Posted December 18, 2016 I think the issue is because the ALIGN command creates its own undo groups which interfere with those created by the AutoLISP program - the same undo behaviour is observed when using both the ActiveX startundomark/endundomark methods, and the UNDO command with Begin/End options in conjunction with the ALIGN command. I don't immediately see a way around this, but to offer an alternative: you could have your program set an UNDO Mark, and then use the UNDO Back option to undo all operations back to the Mark: (defun c:ca ( / *error* new pt1 pt2 pt3 pt4 sel val var ) (defun *error* ( msg ) (mapcar '(lambda ( a b ) (if b (setvar a b))) var val) (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))) (princ (strcat "\nError: " msg)) ) (princ) ) (if (and (setq sel (ssget "_:L")) (setq pt1 (getpoint "\nSpecify 1st base point to align FROM: ")) (setq pt2 (getpoint "\nSpecify 2nd base point to align FROM: ")) ) (progn (setq var '(cmdecho copymode) val (mapcar 'getvar var) ) (mapcar '(lambda ( a b c ) (if a (setvar b c))) val var '(0 1)) (vl-cmdf "_.undo" "_mark") (while (and (setq pt3 (getpoint "\nSpecify 1st point to align TO <exit>: ")) (setq pt4 (getpoint "\nSpecify 2nd point to align TO <exit>: ")) ) (setq mrk (LM:entlast (entlast)) new (ssadd) ) (command "_.copy" sel "" "_non" '(0 0) "_non" '(0 0)) (foreach ent (LM:entnexttoend mrk) (ssadd ent new)) (command "_.align" new "" "_non" pt1 "_non" pt3 "_non" pt2 "_non" pt4 "" "_N") (setq new nil) ) ) ) (*error* nil) (princ) ) ;; Entnext to End - Lee Mac ;; Returns a list of all primary entities after a given entity in the drawing database (defun LM:entnexttoend ( ent / tmp ) (if (setq tmp (entnext ent)) (if (member (cdr (assoc 0 (entget ent))) '("ATTRIB" "VERTEX" "SEQEND")) (LM:entnexttoend tmp) (cons tmp (LM:entnexttoend tmp)) ) ) ) ;; Entlast - Lee Mac ;; Returns the last entity in the drawing database after a given entity (defun LM:entlast ( ent / tmp ) (if (setq tmp (entnext ent)) (LM:entlast tmp) ent) ) (princ) Quote
PDuMont Posted December 19, 2016 Author Posted December 19, 2016 Thank you for the reply tombu & Lee. It seems to me, obviously incorrect, that undo would act as a "wrapper" for everything that is inside. It's odd I've not seen this before as I am sure(?) I have used other commands within a lisp that had built in undo. ...but maybe not. Thanks for that Lee, that gives me something to study/consider. I appreciate it. Quote
Recommended Posts
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.