Just trying to clean up some code, as well as avoid evil code duplication where I can, and was wondering if I'm on the right track. I'm sure someone here will let me know ;) When I first started using ObjectDBX methods, I found some code posted by Jeff Mishler that I found very useful, and did much to get me on my way. The logic of it was basically to check through the open documents collection and, if the file was not open, return a DBX object which could then be manipulated. If the file WAS open, a prompt would be displayed telling the user to close the file, then try again. If the file didn't exist, a prompt would inform the user of that case, too. Later on, in response to another question of mine, (UCS importing), Joe Burke kindly posted some similar code, with the difference that if the document in question WAS open, IT would be returned OR, otherwise, a DBX object. (IOW, no need to close the file first.) Now as I look back over the routines I have since created (not many, yet) (currently based on JM's logic structure), I see in some of them that, at times, it would actually be useful to work over an open doc object, rather than forcing the user to close the document and re-running the routine (as in JB's logic structure). At other times, it probably doesn't matter too much. But what is more worrisome to me is that much of the code of the routines themselves is being repeated, as I copy one routine and transform it to another one. Kind of hard to explain, but the point is, I know this sort of code duplication is not a healthy practice, either. So... I'm trying to bust the routines up into smaller subfunctional chunks (as shown below), based a little more on JB's logic structure. I am assuming that whenever these functions will be called, it will most likely be in an Object DBX situtation (since the affected code at this point is ALL relating to modifications of DBX objects). But I'm wanting to at least make provisions now for the modifications of documents that may be open. The trick (I think) - and thus my question - is that later on, I'll probably need to be able to know what I 'snagged': Nothing, a DBX object, or an Open Document object - no? This is what I'm wondering about. Thus my use of the Dotted pair return in the djkGetDocObjAtPath function. My question is if this is a good way to handle the situation or if there is a more elegant way to do so. Hope this at least sort of makes sense. This is what I've got so far: ; Returns Open Document Object if found, or nil ; Based on code by Joe Burke 2004 (defun djkGetOpenDocObjAtPath (FullPath_str ; Full Path String to Document / *djkAcadObject* ; Application Object *djkDocuments* ; Documents Collection Object SourceDoc_obj ; Source Document ; / ; vl:T ) ; begin (setq *djkAcadObject* (vlax-get-acad-object)) (setq *djkDocuments* (vlax-get-property *djkAcadObject* 'Documents)) ; Iterate through the open documents collection (vlax-for OpenDoc_obj *djkDocuments* ; begin loop (if (= FullPath_str (vlax-get-property OpenDoc_obj 'FullName)) ; then - found it (setq SourceDoc_obj OpenDoc_obj) ; else - keep looking ; );_end if ; end loop );_end vlax-for ; return what was found - or nil if nothing SourceDoc_obj ; end );_end defun ;| Based on code by Joe Burke & Jeff Mishler - 2004 Modified 2005 by David Kozina Returns Open Document Object or ODBX Document Object dotted pair or nil: (# . <_obj>), #: 0 = DBX obj, 1 = Open Doc |; (defun djkGetDocObjAtPath (FullPath_str ; Full Path String to Document / SourceDoc_obj ; Source Document ; / ; (djkGetOpenDocObjAtPath ; (djkGetDBXObject ) ; begin (cond ; case source file is open... ; return Open Doc Object dotted pair ((setq SourceDoc_obj (djkGetOpenDocObjAtPath FullPath_str) );_end setq (cons 1 SourceDoc_obj) ); end case ; case - file not open but DOES exist... ; return DBX object dotted pair ((findfile FullPath_str) (cons 0 (djkGetDBXObject)) ;<- Note: DBX subfunction not posted ); end case ; default case - file doesn't exist... ; return nil... (T nil ); end case );_end cond ; end );_end defun ; Save DBX Object - Call as Needed ; based on code by Jeff Mishler - 2004 (defun djkDBXObjectSaveAs (DBX_obj ; DBX Object / ; / ; vl:T ) ; begin ; Save changes to file - Must use SaveAs, Save not implemented (vlax-invoke-method DBX_obj 'Saveas (vlax-get-property DBX_obj 'Name) ) ; end );_end defun Using the above subfunctions, I am envisioning the overall routine logic to go something like this: ;... (setq SourceDoc_dp (djkGetDocObjAtPath FullPath_str) );_end setq (cond ; case - DBX route ((zerop (car SourceDoc_dp)) ; "open" source for our use... (vlax-invoke-method (cdr SourceDoc_dp) 'Open FullPath_str ) ; do stuff here... ; use following line where needed... ; (djkDBXObjectSaveAs (cdr SourceDoc_dp)) ; we're done with it (vlax-release-object (cdr SourceDoc_dp)) ); end case ; case - OpenDoc route ((SourceDoc_dp) ; do stuff here... ); end case ; default case - no file existed (T (alert "File does not exist") ); end case );_end cond ;... The second half of my question relates to the routine logic of the last bit, itself. Typically, the general cond statement logic will be duplicated in the DBX routines themselves. (The parts that will change would be the "do stuff here..." sections.) Is there any way to break this down any more, or is this about as good as it gets? Any guidance or suggestions regarding the above would be appreciated. Best regards, David Kozina