Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

A SIMPLE CLEANUP ROUTINE

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
timothy_crouse
484 Views, 12 Replies

A SIMPLE CLEANUP ROUTINE

 

Here is a simple routine I have always performed prior to closing a file.  (dbl pu with dbl qsave catches some unwanted garbage from block editing, at least that was passed onto me via adsk support).  I do know if I open a file that displays a recover msg and I choose no but rather perform these tasks the file opens without the recover notice.

 

Anyways take that info as you whish . . .

 

;; PURGE TWICE
;; ZOOM EXTENTS
;; REGEN ALL 2X
;; QUICK SAVE 2X
(defun c:CLN (/ response)
;; Run PURGE ALL twice with a slight pause in between
(command "._-PURGE" "ALL" "*" "N")
(command "._delay" 250)
(command "._-PURGE" "ALL" "*" "N")

;; Zoom extents
(command "_ZOOM" "_EXTENTS")

;; Regen all
(command "_REGENALL")
(command "._delay" 250)
(command "_REGENALL")

;; Quick save
(command "_QSAVE")

;; Short delay to avoid write error
(command "._delay" 250)

;; Quick save again
(command "_QSAVE")

;; Display completion message and sound
(alert "CLEAN AS A WHISTLE")

;; Prompt to close the file
(setq response (getstring "\nDo you want to close the file? (Y/N) <N>: "))

;; Close the file if the response is "Y" or "y"
(if (or (= response "Y") (= response "y"))
(command "_CLOSE")
(princ "\n")
)
(princ)
)

;; Display message after LISP is loaded
(princ "\nType \"CLN\" To Initiate Cleanup and Exit with Choice.")
(princ "\n")

 

 

 

-Best Regards

-Tim C.

 

 

 

 

 

Tags (2)
12 REPLIES 12
Message 2 of 13
Moshe-A
in reply to: timothy_crouse

@timothy_crouse  hi,

 

Except for the purge, no need to run 2 times regen & qsave,  AutoCAD does not need the delay (unless you need, it will not run the next command until it finish current running) 

 

Moshe

 

(defun c:cln ()
 (repeat 2
  (command "._purge" "_all" "*" "_N")
 )

 (command "._zoom" "_extents")
 (command "._regenall")
 (command "._qsave")
 ;; Display completion message and sound
 (alert "CLEAN AS A WHISTLE")

 ;; Prompt to close the file
 (initget "Yes No")
 (setq response (getkword "\nDo you want to close the file? (Y/N) <N>: "))

 (if (eq reponse "Yes")
  (command "._close")
 )

 (princ)
)

 

Message 3 of 13
CodeDing
in reply to: timothy_crouse

I would add a Purge to the Regapps also:

(command "._-PURGE" "R" "*" "N")

 

And a good Audit to finish up :winking_face:

(command "_.AUDIT" "y")

 

Best,

~DD


Need AutoLisp help? Try my custom GPT 'AutoLISP Ace':
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace
Message 4 of 13
paullimapa
in reply to: timothy_crouse

Have you tried just opening the file using the Recover command, do a qsave, close and reopen again to see if message is gone?


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 5 of 13
Sea-Haven
in reply to: timothy_crouse

If your using this as a do before closing cleanup I would add zoom extents all layouts also. Maybe something like this.

(setq curtab (getvar "Ctab"))
(setq this_dwg (vlax-get-acad-object))
(foreach d (layoutlist)
    (setvar "CTAB" d)
    (vla-ZoomExtents this_dwg)
)
(setvar "ctab" curtab)

 

Message 6 of 13
timothy_crouse
in reply to: paullimapa

Using recover on a drawing with dynamic blocks that have both visstates and attributes runs a risk of damaging the blocks, at times acad will duplicate all the objects inside a dynamic block under certain conditions.

Message 7 of 13
timothy_crouse
in reply to: Moshe-A

I agree on the regen but the 2x QSAVE is what pulls block garbage out of the drawing.  I understand it's not a documented topic but it's how it actually works through testing and recommended by adsk support.

Message 8 of 13
timothy_crouse
in reply to: Sea-Haven

Here are the updates,  it works faster thanks to MOSH-A pointing out the command sequence timing:

;; CLEAN ROUTINE TIM C./w FORUM HELP 04DEC2024
;;

;; PURGE TWICE
;; ZOOM EXTENTS Code for active or all present, donated by Sea-Haven
;; REGEN ALL12X
;; QUICK SAVE 2X
;; Pugre and Audit Code donate by CodeDing
;; Background info, I use a lot of dynamic blocks in my drawings. Typically I do not perform block edits in a production drawing
;; performing block edits may lead to hidden garbage being added to the dynamic block, prevalent in blocks with visstate + attributes
;; This routine clears/prevents that garbage from gathering. You will not know if block garbage has accumulated until you reopen the drawing
;; A clear indication is a recover notice popping up when the drawing is open.
;; I have had many instances of duplicate objects being automatically added inside all the dynamic blocks inside a drawing if I selected YES to recover
;; To avoid that issue I would manually run these commands after I exited the block editor.
;; To save time I created this routine.
;; That's my saga, I hope other folks find this useful
;; One move tip about Block editor issues
;; If I perform multiple block edits and in the mix I select MODIFY and action, specifically POINT MOVE
;; My cursor will disappear when the mouse is over top of the canvas. Moving the point to the ribbon brings it back.
;; I find it is best to restart Autocad at this point.
(defun c:CLN (/ response)
;; Run PURGE ALL twice with a slight pause in between
(command "._-PURGE" "R" "*" "N")
;;;; (command "._delay" 250)
(command "._-PURGE" "R" "*" "N")

(command "_.AUDIT" "y")

;; Zoom extents
;;(command "_ZOOM" "_EXTENTS") single tab ZE
;; ZE all Tabs
(setq curtab (getvar "Ctab"))
(setq this_dwg (vlax-get-acad-object))
(foreach d (layoutlist)
(setvar "CTAB" d)
(vla-ZoomExtents this_dwg)
)
(setvar "ctab" curtab)

 

;; Regen all
(command "_REGENALL")
;;;; (command "._delay" 250)
;;;; (command "_REGENALL")

;; Quick save
(command "_QSAVE")

;; Short delay to avoid write error
(command "._delay" 250)

;; Quick save again
(command "_QSAVE")

;; Display completion message and sound
(alert "CLEAN AS A WHISTLE")

;; Prompt to close the file
(setq response (getstring "\nDo you want to close the file? (Y/N) <N>: "))

;; Close the file if the response is "Y" or "y"
(if (or (= response "Y") (= response "y"))
(command "_CLOSE")
(princ "\n")
)
(princ)
)

;; Display message after LISP is loaded
(princ "\nType \"CLN\" To Initiate Cleanup and Exit with Choice.")
(princ "\n")

Message 9 of 13
paullimapa
in reply to: timothy_crouse

If this problem is not already documented, it should be reported to Autodesk so they would be aware of the possible problems the Recover command could cause to dynamic blocks that have both visstates and attributes. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 10 of 13

Myself, I would also include setting Layer 0 current.  If the current Layer is something else, which has nothing on it, you won't be able to Purge it.  But you can't Purge Layer 0 whether or not anything is drawn on it, so make it current first, and you'll be sure to Purge all empty Layers.

Kent Cooper, AIA
Message 11 of 13
Sea-Haven
in reply to: timothy_crouse

Might as well add for Civ3D use Purgestyleandsettings, before normal purge, else lots of stuff in a civ3D dwg will still be there but not used as CIV3D locks what it might use.

Message 12 of 13
ronjonp
in reply to: timothy_crouse

Here is a stripped down version of code I use to clean drawings daily. It uses the old WBLOCK over oneself trick .. it's fast and does a great job.

(defun c:endit (/ adoc after before c diff e file msg pct)
  (if (and (= 1 (getvar 'dwgtitled)) (getvar 'writestat))
    (progn (acad-push-dbmod)
	   (setq e	(getvar 'expert)
		 c	(getvar 'cmdecho)
		 file	(strcat (getvar 'dwgprefix) (getvar 'dwgname))
		 adoc	(vla-get-activedocument (vlax-get-acad-object))
		 before	(float (vl-file-size file))
	   )
	   (dictremove (namedobjdict) "ACAD_DGNLINESTYLECOMP")
	   (vla-save adoc)
	   (setvar 'expert 5)
	   (setvar 'cmdecho 0)
	   (setvar 'tilemode 1)
	   (if (= 0 (getvar 'worlducs))
	     (command "_.ucs" "_World")
	   )
	   (command "_.-wblock" (strcat (getvar 'dwgprefix) (getvar 'dwgname)) "*")
	   (setvar 'expert e)
	   (setvar 'cmdecho c)
	   (setq after (float (vl-file-size file)))
	   (setq diff (- before after))
	   (setq msg (strcat "<< "
			     (vl-filename-base (getvar 'dwgname))
			     " >> purged.\nSize reduced "
			     (setq pct (rtos (* (/ diff before) 100.) 2 1))
			     "%  ( "
			     (setq diff (rtos (/ diff 1048576.) 2 4))
			     " ) MB.\n\nFile will now close to complete purge..."
		     )
	   )
	   (if (= 0 (getvar 'cmdactive))
	     (alert msg)
	     (princ msg)
	   )
	   (acad-pop-dbmod)
	   (if (= 0 (getvar 'cmdactive))
	     (vl-cmdf "_.close" "_Yes")
	   )
    )
    (alert "\nThis routine only works on drawings that have been saved or not readonly.")
  )
  (princ)
)
Message 13 of 13

I noticed the original purge command was not removing unused blocks.

 

I went back and wrapped in a function

 

(defun c:purge-all ()
(vl-load-com)
(vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
(command "._-PURGE" "ALL" "*" "N")
(vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
(princ)
)

 

This code uses vl-load-com to ensure that COM libraries are loaded and wraps the PURGE command in an undo mark, which helps manage the execution context, all in all it seems to be removing unused blocks at this time.

 

 

Tags (2)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report