benfleck Posted January 15, 2009 Posted January 15, 2009 I'm trying to write a lisp that will make all xrefs in a drawing be set to relative upon save. I have a save reactor created but I can't get the lisp routine to work. Save Reactor: (defun AtSaveCommand (calling-reactor b) (if (or (= (car b) "QSAVE") (= (car b) "SAVEAS") (= (car b) "SAVE") ) (xrefpath) ) ) (defun loadTheSaveReactor () (vl-load-com) (if *FileOnSave* (vlr-remove *FileOnSave*)) (setq *FileOnSave* (vlr-command-reactor nil '((:vlr-commandwillStart . AtSaveCommand))) ) ) (loadTheSaveReactor) Lisp Routine (defun xrefpath () (COMMAND "redir" "*" "") ) Quote
Lee Mac Posted January 15, 2009 Posted January 15, 2009 You can't use "Command" functions in reactors... Quote
benfleck Posted January 15, 2009 Author Posted January 15, 2009 GRRRRRR!!! not the answer I wanted But thems the breaks! Quote
Lee Mac Posted January 15, 2009 Posted January 15, 2009 As quoted from AfraLISP: A word of warning!!! Did you notice how I used ActiveX statements and functions to "Save" and "SaveAs". You cannot use interactive functions from within a reactor as AutoCAD may still be processing a command at the time the event is triggered. Therefore, avoid the use of input-acquisition methods such as "getPoint", "ensel", and "getkword", as well as "selection set" operations and the "command" function. Quote
3dwannab Posted April 8, 2017 Posted April 8, 2017 Try this: Point of reference here: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-E13A580D-04CA-46C1-B807-95BB461A0A57-htm.html ;; AtSaveCommand ;; loadTheSaveReactor ;; Found here: http://forums.augi.com/showthread.php?93534-Run-lisp-when-closing-drawing&p=926895&viewfull=1#post926895 (defun AtSaveCommand (calling-reactor b) (if (or (= (car b) "QSAVE") (= (car b) "SAVEAS") (= (car b) "SAVE") ) (progn (setq acadObj (vlax-get-acad-object)) (setq activeDoc (vla-get-ActiveDocument acadObj)) ;; Get activeDoc Help: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-ActiveX/files/GUID-161FD7E5-B739-4E09-8430-BA04A6298703-htm.html (if (= (vla-get-ActiveSpace activeDoc) 1) (progn (vla-SendCommand activeDoc (strcat "._TEXTTOFRONT A ")) ; (vla-Regen activeDoc acAllViewports) ; (vla-SendCommand activeDoc (strcat "_REGEN ")) ) (progn ; (princ "\nSwitching to ModelSpace & Back, 1 sec...")(princ) ;; (run your command here) ;; Code changed from here ;; YOu can run a command like so: See help here: ;; https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-E13A580D-04CA-46C1-B807-95BB461A0A57-htm.html (vla-SendCommand activeDoc (strcat "._TILEMODE 1 ")) (vla-SendCommand activeDoc (strcat "._TEXTTOFRONT A ")) (vla-SendCommand activeDoc (strcat "._TILEMODE 0 ")) ; (vla-SendCommand activeDoc (strcat "_REGEN ")) ; (vla-Regen activeDoc acAllViewports) ) ) ) ) ) (defun loadTheSaveReactor () (if *FileOnSave* (vlr-remove *FileOnSave*)) (setq *FileOnSave* (vlr-command-reactor nil '((:vlr-commandwillStart . AtSaveCommand))) ) ) (vl-load-com) (loadTheSaveReactor) Quote
Grrr Posted April 8, 2017 Posted April 8, 2017 3dwannab, Use :VLR-DWG-Reactor with :VLR-beginSave event and also either globalize the acDoc variable, outside the callback function, either localise it inside the callback func. Also that thread is from 2009, why are you replying? Quote
3dwannab Posted April 9, 2017 Posted April 9, 2017 3dwannab,Use :VLR-DWG-Reactor with :VLR-beginSave event and also either globalize the acDoc variable, outside the callback function, either localise it inside the callback func. Also that thread is from 2009, why are you replying? I was just trying to help others Seeing as the Thread is about running a command through a reactor. Thanks for the pointer here. It's working as it should. As sometimes that old code ran only once. (Probably due to the fact I didn't localise the vars. (defun BeginSave (objReactor lstDataBaseAndName / acadObj activeDoc cmd) (setq cmd (getvar "cmdecho")) (setvar 'cmdecho 0) (setq acadObj (vlax-get-acad-object)) (setq activeDoc (vla-get-ActiveDocument acadObj)) (if (= (vla-get-ActiveSpace activeDoc) 1) (progn (vla-SendCommand activeDoc (strcat "._TEXTTOFRONT A ")) (vla-Regen activeDoc acAllViewports) ) (progn (princ "\nSwitching to ModelSpace & Back, 1 sec...\n")(princ) (vla-SendCommand activeDoc (strcat "._TILEMODE 1 ")) (vla-SendCommand activeDoc (strcat "._TEXTTOFRONT A ")) (vla-SendCommand activeDoc (strcat "._TILEMODE 0 ")) (vla-Regen activeDoc acAllViewports) ) ) (setvar 'cmdecho cmd) ) (if (not rxnBeginSave) (setq rxnBeginSave (VLR-DWG-Reactor nil '((:VLR-beginSave . BeginSave )))) ) (princ "\nDrawOrder_Reactor.lsp Loaded..")(princ) Quote
3dwannab Posted April 10, 2017 Posted April 10, 2017 (edited) Scrap that last code: It behaves badly as ACAD fires of a SAVE when you copy opjects. So VLR-DWG-Reactor and :VLR-beginSave will not work. Instead, it's better to use vlr-command-reactor and :vlr-commandwillstart to monitor the commandline for your commands you want to fire the event on like: (if (wcmatch (strcase (car arg)) "SAVE,QSAVE,SAVEAS,PLOT") (setdraworder) ) Here are two different working solutions, the first one is the commandline TEXTTOFRONT one. Note: It's best to use vla-SendCommand throughout your progn otherwise ACAD seems to go into a nasty loop. And the second is a modified version of LeeMacs reactor to work with text and dim objs found here. I'm running with that as it doesn't require an additional save to keep the Draworder. (Another downside of (vla-SendCommand) I suppose). My command call DrawOrder Reactor using TEXTTOFRONT ;; setdraworder ;; loadTheSaveReactor ;; Found here: http://forums.augi.com/showthread.php?93534-Run-lisp-when-closing-drawing&p=926895&viewfull=1#post926895 ;; ;; You can run a command like so: See help here: ;; https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-E13A580D-04CA-46C1-B807-95BB461A0A57-htm.html ;; ;; by 3dwannab to work with all HATCH, TEXT, LEADER and DIM objects ;; ;; Known Bugs: Needs additional Save to Save DRAWORDER of Objects (defun setdraworder ( / acadObj doc activeSpe ) (setq acadObj (vlax-get-acad-object)) (setq doc (vla-get-ActiveDocument acadObj)) (setq activeSpe (vla-get-ActiveSpace doc)) (if (= 1 activeSpe) (progn (vla-SendCommand doc (strcat "._TEXTTOFRONT A ")) (vla-SendCommand doc (strcat "._HATCHTOBACK ")) ) (progn (princ "\nSwitching to ModelSpace & Back, 1 sec...")(princ) (vla-SendCommand doc (strcat "._TILEMODE 1 ")) (vla-SendCommand doc (strcat "._TEXTTOFRONT A ")) (vla-SendCommand doc (strcat "._HATCHTOBACK ")) (vla-SendCommand doc (strcat "._TILEMODE 0 ")) ) ) (vla-Regen doc acActiveViewport) (princ "\n >>> Draworder Reactor is Running ...\n")(princ) ) (defun draworder:callback ( obj arg ) (if (wcmatch (strcase (car arg)) "SAVE,QSAVE,SAVEAS,PLOT") (setdraworder) ) (princ) ) (defun loadTheSaveReactor () (vl-load-com) (if (null draworder:reactor) (setq draworder:reactor (vlr-command-reactor nil '((:vlr-commandwillstart . draworder:callback)))) ) (princ) ) (loadTheSaveReactor) LeeMac Mod: Edited so that user can turn off and on the reactor with: setdraworder-off & setdraworder-on Works with commands: SAVE,QSAVE,SAVEAS,PLOT,PUBLISH ;; Re: Send all hatch/images to background prior to printing & Saving ;; by LeeMac ;; https://www.theswamp.org/index.php?PHPSESSID=klskia7od2ku3u3kf9o6n4nl13&topic=43352.msg507568#msg507568 ;; ;; Edited on 10.04.17 by 3dwannab to work with all TEXT, LEADER and DIM objects ;; (defun setdraworder ( / exd ls1 ls2 ls3 obn sor spc ) (if (setq spc (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) exd (vla-getextensiondictionary spc) sor (cond ((catchapply 'vla-getobject (list exd "acad_sortents"))) ((catchapply 'vla-addobject (list exd "acad_sortents" "acdbsortentstable"))) ) ) (progn (vlax-for obj spc (cond ( (= "AcDbHatch" (setq obn (vla-get-objectname obj))) (setq ls1 (cons obj ls1)) ) ( (= "AcDbRasterImage" obn) (setq ls2 (cons obj ls2)) ) ( (= (wcmatch (vla-get-objectname obj) "*Dim*,*Leader*,*Text*") (setq obn (wcmatch (vla-get-objectname obj) "*Dim*,*Leader*,*Text*"))) (if (wcmatch (vla-get-objectname obj) "*Dim*,*Leader*,*Text*") (setq ls3 (cons obj ls3)) ) ) ) ) (if ls1 (vlax-invoke sor 'movetobottom ls1)) (if ls2 (vlax-invoke sor 'movetobottom ls2)) (if ls3 (vlax-invoke sor 'movetoTop ls3)) (princ "\n >>> Draworder Reactor was successful ...\n")(princ) ) (princ "\nUnable to retrieve Sortents Table.") ) (princ) ) (defun catchapply ( fun arg / rtn ) (if (not (vl-catch-all-error-p (setq rtn (vl-catch-all-apply fun arg)))) rtn) ) (defun c:setdraworder-on ( ) (if (= 'vlr-command-reactor (type draworder:reactor)) (if (vlr-added-p draworder:reactor) (princ "\nSet Draworder reactor already running.") (progn (vlr-add draworder:reactor) (princ "\nSet Draworder reactor enabled.") ) ) (progn (setq draworder:reactor (vlr-command-reactor "setdraworder-reactor" '( (:vlr-commandwillstart . draworder:callback) ) ) ) (princ "\nSet Draworder reactor enabled.") ) ) (princ) ) (defun c:setdraworder-off ( ) (if (= 'vlr-command-reactor (type draworder:reactor)) (progn (vlr-remove draworder:reactor) (setq draworder:reactor nil) (princ "\nSet Draworder reactor disabled.") ) (princ "\nSet Draworder reactor not running.") ) (princ) ) (defun draworder:callback ( obj arg ) (if (wcmatch (strcase (car arg)) "SAVE,QSAVE,SAVEAS,PLOT,PUBLISH") (setdraworder) ) (princ) ) (vl-load-com) (if (null draworder:reactor) (setq draworder:reactor (vlr-command-reactor nil '((:vlr-commandwillstart . draworder:callback)))) ) (princ "\n :: Draworder Reactor was loaded ::\n")(princ) Edited April 11, 2017 by 3dwannab Code amendment 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.