(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(setq edoc (vlax-vla-object->ename (vla-get-modelspace doc)))
(cd:ProxyClean edoc)
Coincidently, I was playing to this right now.This thread also started my journey.
Here's where I am using .NET (work in progress inspired by this thread (http://adndevblog.typepad.com/autocad/2013/04/search-and-erase-proxies.html)).
symbol table records and in eventual extension dictionaries for all.
AcDbProxyEntity::kEraseAllowed = 0x1Looking at your drawing the ProxyFlag property is 129 so looks like allows cloning and erasing.
AcDbProxyEntity::kTransformAllowed = 0x2
AcDbProxyEntity::kColorChangeAllowed = 0x4
AcDbProxyEntity::kLayerChangeAllowed = 0x8
AcDbProxyEntity::kLinetypeChangeAllowed = 0x10
AcDbProxyEntity::kLinetypeScaleChangeAllowed = 0x20
AcDbProxyEntity::kVisibilityChangeAllowed = 0x40
AcDbProxyEntity::kCloningAllowed = 0x80
AcDbProxyEntity::kLineWeightChangeAllowed = 0x100
AcDbProxyEntity::kPlotStyleNameChangeAllowed = 0x200
or
AcDbProxyEntity::kAllButCloningAllowed = 0x37F
AcDbProxyEntity::kAllAllowedBits = 0x3FF
Autodesk.AutoCAD.Runtime.Exception was unhandled by user code
Message=eInvalidOpenState
Source=Acdbmgd
StackTrace:
at Autodesk.AutoCAD.DatabaseServices.OpenCloseTransaction.GetObject(ObjectId id, OpenMode mode, Boolean openErased, Boolean forceOpenOnLockedLayer)
at Autodesk.AutoCAD.DatabaseServices.OpenCloseTransaction.GetObject(ObjectId id, OpenMode mode)
at CADDOG_LispExpansionPack1.LispFunctions.CleanProxies(Database db, Transaction tr) in C:\Users\medleyr\Documents\Visual Studio 2010\Projects\CADDOG_LispExpansionPack1\CADDOG_LispExpansionPack1\CADDOG_LispExpansionPack1.cs:line 374
at CADDOG_LispExpansionPack1.LispFunctions.ProxyClean(ResultBuffer rb) in C:\Users\medleyr\Documents\Visual Studio 2010\Projects\CADDOG_LispExpansionPack1\CADDOG_LispExpansionPack1\CADDOG_LispExpansionPack1.cs:line 357
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.InvokeLisp()
InnerException:
;;ProxyClean v0.1
;;
;;by Ricky Medley - CADDOG Computing
;;ricky.medley@caddog.net
;;Additional Credit: LeeMac LM:GetFiles LM:ODBX Wrapper LM:GetFilesAll LM:BrowseForFolder
;; Thank you Lee for making my life easier
;;
;;GNU GPLv3 licensed
;;http://www.gnu.org/licenses/gpl.html for preamble
;;This means you can modify, and distribute as long as the source code or any derivitive of this
;;code is provided and distributed as well. You can even compile and sell, but you must provide
;;this source code in the package, and notify the recipient of the license as well. Porting to
;;other languages as far as form and structure are also applicable to this license.
;;Modification to any code must be submitted back to ricky.medley@caddog.net for as long as the
;;address is valid.
;;The idea is not copyrighted.
;;Feel free to change the name of the command
;;
;;Program Description: Cleans all proxy objects from drawing or batch of drawings.
;; The command used, cd:ProxyClean, is indescriminate, and will
;; clean proxy objects from their proxy data regardless if object
;; enablers are installed. Please use with caution.
;;
;;Dependencies:
;;;LM:GETFILES - http://www.lee-mac.com/getfilesdialog.html
;;;LM:ODBX - http://www.lee-mac.com/odbxbase.html
;;;LM:GETALLFILES
;;;LM:BROWSEFORFOLDER
;;
;;Future: cd:proxyclean to report back the name/description of the application of the proxy that
;; was cleaned. This data will need to be handled and will be in a list format.
;;
;;History:
;;6/26/2013 v0.1 - Initial Build v0.1:
;; -
;;
(defun c:ProxyClean (/
*Error*
releaseobj
get-time
get-utime
_getsavefile
process
cd:dependency
cd:Get-WebUtils
vl:list->string
doc
process
opt
)
(vl-load-com)
(defun *error* (msg)
(cd:setworkingdatabase (vlax-vla-object->ename (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))))
(releaseobj doc)
(if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
(progn
(princ (strcat "\nXref Clean Error: " msg))
(vl-bt)
)
(princ)
);if
);defun *Error*
;from LeeMac
(defun releaseobj (obj)
(if
(and
(eq 'VLA-OBJECT (type obj))
(not (vlax-object-released-p obj))
)
(vl-catch-all-apply 'vlax-release-object (list obj))
)
);defun releaesobj
(defun Get-Time (format rev ;return time in two string parts ("5-2-2011";format derives 12 or 24 (feed integer) - default is 24
;rev refers to reversing the order from american(relevance order) to logical(numberical order)
;rev is t or nil
/
ctime cy cm cd ch cm cs suf
)
(setq ctime (rtos (getvar "CDATE") 2 6)
cy (substr ctime 1 4)
cm (substr ctime 5 2)
cd (substr ctime 7 2)
ch (atoi (substr ctime 10 2))
cmn (substr ctime 12 2)
cs (substr ctime 14 2)
suf "")
(if (= format 12)
(progn
(if (> ch 12)
(setq ch (- ch 12)
suf " PM")
(setq suf " AM")
);if
);progn
);if
(if (= rev t)
(list (strcat cm "-" cd "-" cy) (strcat (itoa ch) ":" cmn ":" cs suf))
(list (strcat cy "-" cm "-" cd) (strcat (itoa ch) ":" cmn ":" cs suf))
);if
);defun
(defun get-utime ()
(* 86400 (getvar "tdusrtimer"))
)
(defun vl:list->string (delim ls / out)
(setq out "")
(mapcar (function (lambda (x)
(setq out (strcat out x delim))))
ls)
(if out (vl-string-right-trim delim out))
);defun list->string
(defun _getsavefile (prmpt dfltFile fileExt / saveFileName)
(if (not prmpt) (setq prmpt "Choose Save File"))
(if (not dfltFile) (setq dfltFile "Output"))
(if (not fileExt) (setq fileExt "txt"))
(setq saveFileName (getfiled prmpt dfltFile fileExt 129))
);defun _getsavefile
;need to optimize to accept a list of dependencies
(defun cd:dependency (/
LM:GetFiles_url
LM:ODBX_url
opt
resource_directory
)
;;lee-macs site is not responding... for the past month or so.
(setq LM:GetFiles_url "http://www.caddog.net/opensource/lisp/lee-mac/GetFilesV1-1.lsp")
(setq LM:ODBX_url "http://www.caddog.net/opensource/lisp/lee-mac/ObjectDBXWrapperV1-1.lsp")
(setq resource_directory (strcat (getenv "appdata") "\\Autodesk\\ApplicationPlugins\\Lee-Mac-Utils"))
;check for required functions
(if (or (not LM:ODBX)(not LM:GetFiles)(not LM:GetAllFiles)(not LM:BrowseForFolder))
;check for variations of the lisp files that might contain the functions
(if (or (and (setq LM:GetFiles (findfile "GetFiles.lsp"))
(or (setq LM:ODBX (findfile "ObjectDBXWrapper.lsp"))
(setq LM:ODBX (findfile "ODBX.lsp"))))
(and (setq LM:GetFiles (findfile (strcat resource_directory "\\" (vl-filename-base LM:GetFiles_url) (vl-filename-extension LM:GetFiles_url))))
(setq LM:ODBX (findfile (strcat resource_directory "\\" (vl-filename-base LM:ODBX_url) (vl-filename-extension LM:ODBX_url)))))
);or
;found them, so load them
(progn
(load LM:GetFiles)
(load LM:ODBX)
);
;else, let's ask to download them.
(progn
(princ "\nIn order to proceed, Lee-Mac lisp functions must be downloaded:")
(princ (strcat "\n\t" LM:GetFiles_url))
(princ (strcat "\n\t" LM:ODBX_url))
(initget "Yes No")
(setq opt (getkword "\nAllow connection to CADDOG.net [Yes/No] <Yes>: "))
(cond ((= opt "No")
;(vl-exit-with-error "Cannot Continue") ;this exit method may not be right
;(princ "Cannot Continue")
;(exit)
)
;(cd:Get-LeeMacUtils DownloadDestination
(t
(if (setq return (cd:Get-WebUtils resource_directory (list LM:GetFiles_url LM:ODBX_url)))
(mapcar 'load return))
)
);cond
);progn
);if LM files exists
);if LM functions defined
(if (and LM:ODBX LM:GetFiles)
t
nil)
);defun cd:dependency
(defun cd:Get-WebUtils (dest url_list
/
*error*
dest
url
msxml
ADOstream
return
)
(defun *error* (msg /)
(if msxml (vlax-release-object msxml))
(if ADOstream (vlax-release-object ADOstream))
(setq msxml nil
ADOstream nil)
(vl-exit-with-error "Get-WebUtils Failed")
)
(if (setq msxml (vlax-create-object "MSXML2.XMLHTTP"))
(progn
(vl-mkdir dest)
(foreach url url_list
;test if web location exists
(vlax-invoke-method msxml 'Open "GET" url :vlax-false)
(vlax-invoke-method msxml 'Send)
(princ (strcat "\nInquiring: " url))
(setq status (vlax-get-property msxml "status"))
(if (= 200 status)
(progn
;start a stream to download
(setq ADOstream (vlax-create-object "ADODB.Stream"))
(vlax-invoke-method ADOstream 'Open nil nil nil nil nil)
(vlax-put-property ADOstream "Type" 1)
(vlax-invoke-method ADOstream 'Write (vlax-get-property msxml "responseBody"))
(vlax-put-property ADOstream "Position" 0)
(setq return (append (list (strcat dest "\\" (vl-filename-base url) (vl-filename-extension url))) return))
(vlax-invoke-method ADOstream 'SaveToFile (car return) 2)
(vlax-invoke-method ADOstream 'Close)
(vlax-release-object ADOstream)
(princ (strcat "\nSaving To: " (car return)))
);progn status = 200
;else, tell user
(princ (strcat "\nFileGet Error: " (vlax-get-property msxml "statusText")
"\n\t" url))
);if status = 200
);for each url url_list
(vlax-release-object msxml)
);progn
(princ "Connection could not be established.")
);if createobject
return
);defun cd:Get-WebUtils
(defun _write_data (data filename
/
file
dwg
xref
)
(if (and data filename
(setq file (open filename "w"))
);and
(progn
(write-line (vl:list->string "\t" '("dwg" "proxy_clean_status")) file)
(foreach dwg data
(foreach xref (cdr dwg)
(setq clean (mapcar (function (lambda (x) (if x x ""))) xref))
(write-line (vl:list->string "\t" (append (list (car dwg)) clean)) file)
);foreach xref
);foreach dwg
(close file)
);progn
);if data and filename
);defun _write_data
(defun cd:proxy_clean (doc
/
docpath
outdata
logdata
clean-status
)
;this test is the difference between dbx and current file
(if (vlax-property-available-p doc 'FullName) ;only available in UI drawings
(setq docpath (vl-filename-directory (vla-get-fullname doc)))
;else we are in DBX, and need to get a different property and load xrefs
;and try set dbx doc as working database
(progn
(setq docpath (vl-filename-directory (vla-get-name doc)))
(cd:setworkingdatabase (vlax-vla-object->ename (vla-get-modelspace doc)))
);progn
);if current dwg
(if (cd:proxyclean (vlax-vla-object->ename (vla-get-modelspace doc)))
(setq clean-status "clean-ran")
(setq clean-status "clean-failed")
);if cd:proxyclean
(cd:setworkingdatabase (vlax-vla-object->ename (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))))
(list (list clean-status))
);defun cd:proxy_clean
(defun process (runfolder simulate /
doc
dwgname
data
name
save
)
(setq save (not simulate)) ;usage is opposite on LM:ODBX which is a save or notsave var
;so simulate=true is save=false
(setq doc (vla-get-activedocument (vlax-get-acad-object))
dwgname (vla-get-fullname doc))
(cond ((not runfolder)
(setq data (list (append (list dwgname) (cd:proxy_clean doc))))
)
((and (setq name (strcat (vl-filename-directory dwgname) "\\"))
(setq runfolder (LM:GetFiles "Select Files to Strip Proxy Data" name "dwg"))
(setq name (strcat (vl-filename-directory dwgname) "\\ProxyClean-Log_" (car (get-time 12 nil))))
(setq name (_getsavefile "Choose Log Save File" name "TSV"))
(setq ctime (get-utime))
(setq data (LM:ODBX 'cd:proxy_clean runfolder save))
);and
)
);cond
(cond
((and data name)
(_write_data data name)
(princ "\nProxyClean Complete")
(princ (strcat "\nOpening " name))
(startapp "notepad" name)
(princ (strcat "\Time: " (rtos (- (get-utime) ctime) 2 2) " seconds"))
)
(data
(princ "\nProxyClean Complete")
)
(t (princ "\nProxyClean Failed!!!"))
);cond
);defun process
(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(setq version "v0.1")
(initget "Select Current")
(setq opt (getkword "ProxyClean: Process [Select files/Current dwg] <Current dwg>: "))
(cond
((= opt "Select")
(if (cd:dependency)
(progn
(initget "Yes No")
(setq opt (getkword "\nSimulated Run? [Yes/No] <No>: "))
(cond
((= opt "Yes")
(process t t))
(t (process t nil)
)
);cond
);t all components in place, can batch
(princ "Required Items Not Loaded for Batch")
);if cd:dependency
)
;else
(t ;t Current drawing only
(if (cd:dependency)
(progn
(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(vla-endundomark doc)
(vla-startundomark doc)
(process nil nil)
(vla-endundomark doc)
);progn
);if cd:dependency
);t Current drawing only
);cond
(releaseobj doc)
(princ)
);defun c:XrefBindAll
You could even simply add the proxy objects to a queue and start a thread which runs through this queue until it's empty. The try can then simply fail and leave said object on the queue -
This implementation implements irneb's suggestion of finding, collecting, then cleaning in a while loop. Worked like a charm.Glad it worked for you.