loveboatcaptain Posted September 26, 2011 Posted September 26, 2011 I have many drawings where the xref has been repathed, but xref manager pallate does not update the reference name. For example: Reference Name = "Elevation" but actual file name/found at path is "BN00-CT-TH001" I want to change the reference name to match the filename, You can do this by typing over the reference name manually, but a lisp would be better as I have to change multiple xrefs in over 200 dwgs. Any one help? Quote
irneb Posted September 26, 2011 Posted September 26, 2011 Something like this: (vl-load-com) (defun c:RenameXRefs (/ name) (vlax-for bo (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object))) (if (= (vla-get-IsXref bo) :vlax-true) (progn (setq name (vla-get-Path bo)) (while (wcmatch name "*\\*") (setq name (substr name (+ (vl-string-search "\\" name) 2))) ) (while (wcmatch name "*.[dD][wW][gG]") (setq name (substr name 1 (- (strlen name) 4))) ) (vl-catch-all-apply 'vla-put-Name (list bo name)) ) ) ) (princ) ) Note though it doesn't update the manager's display immediately. But once you've re-opened the DWG it works fine. I'd advise running it through a script on multiple DWGs. There's 2 possible problems though: You cannot rename nested xrefs. For those you need to open the DWG where it is a 1st level xref. And if there's nested together with 1st level, you could run into problems with those. It is possible that the same DWG file is loaded into 2 differently named XRefs. This will only rename the 1st, not merge the 2nd into the same XRef name. Quote
JeepMaster Posted September 26, 2011 Posted September 26, 2011 Here's another version that I use. It has the ability to refresh the dwgs so it will show up right away, and the ability to repath to a new folder location if needed. ;............................................................................... ; ; << Replace old xref files with a set of new xref files >> ; << By MH, June 2010 >> ; << Version 1.1 >> ; ; NOTE: If new xrefs are in a different folder, you must enter new paths ; in STEP 2 to run XrefPathChange routine from the code, otherwise ; remove all code in STEP 2. ; ;............................................................................... (defun c:xrefnamechange (/ b bcol path) (vl-load-com) (setq bcol (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))) (foreach blk '( ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;>>>>> STEP 1. >>>>>> ;>>>>> Enter all xref names below in this format >>>>>> ;>>>>> ("OldXrefName" . "NewXrefName") >>>>>> ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ("SJS-E-TBLK-A0" . "SJS-E-TBLK-A0_NEW") ("SJS-E-LP0B" . "SJS-E-LP0B_NEW") ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ) (if (and (not (vl-catch-all-error-p (setq b (vl-catch-all-apply 'vla-item (list bcol (car blk)))))) (= (vla-get-isxref b) :vlax-true) ) (progn (vla-put-name b (cdr blk)) (if (= (setq path (vl-filename-directory (vla-get-path b))) "") (vla-put-path b (strcat (cdr blk) ".dwg")) (vla-put-path b (strcat path "\\" (cdr blk) ".dwg")) ) (vla-reload b) ) ) ) ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;>>> STEP 2. >>>> ;>>> If xref path is unchanged, add ; in front of each line of code >>>> ;>>> in this section to block the xrefpathchange command. Otherwise, >>>> ;>>> enter all xref paths to be changed in this format. >>>> ;>>> (xrefpathchange "c:\\Oldfolder\\oldfolder" "c:\\newfolder\\newfolder") >>>> ;>>> >>>> ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (xrefpathchange "L:\\Buildings\\E01048\\E" "c:\\temp\\TEST\\XREF") (xrefpathchange "L:\\Buildings\\E01048\\01\\BLK-E" "c:\\temp\\TEST\\XREF") (XReload) ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (princ) );end of c:XrefNameChange ;........................................................... ;.... Xref Path Change sub routine ...... ;........................................................... (defun xrefpathchange (path1 path2 / newpath xrpath) (vl-load-com) (vlax-map-collection (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) (function (lambda (x) (if (= (vla-get-isxref x) :vlax-true) (progn (setq xrpath (strcase (vlax-get x 'path) t) path1 (strcase path1 t) path2 (strcase path2 t) ) (if (and (vl-string-search path1 xrpath) (setq newpath (vl-string-subst path2 path1 xrpath)) (findfile newpath) ) (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-put-path (list x newpath))) (princ (strcat "\n**OLD path found but was not changed!\n" xrpath)) (princ (strcat "\n" newpath)) ) ) ) ) ) ) ) (princ) ); end of XrefPathChange ;............................................................. ;.... Xref Reload sub routine ....... ;............................................................. (defun XReload (/ cObj cName); Updated 2007-10-1: added error trap (defun *error*(msg) (setvar "modemacro" ".") (setvar "cmdecho" 1) (princ "\n...Reload xref terminated!!! ") (princ) ); end of *error* (setvar "modemacro" "Reloading loaded xrefs......please wait......") (setvar "cmdecho" 0) (setq cObj(tblnext "BLOCK" T)) (while cObj (setq cName(cdr(assoc 2 cObj))) (if (and (=(logand(cdr(assoc 70 cObj))32)32) (=(logand(cdr(assoc 70 cObj))4)4) ); end and (progn (vl-cmdf "_.xref" "_unload" cName) (vl-cmdf "_.xref" "_reload" cName) ); end progn ); wnd if (setq cObj(tblnext "BLOCK")) ); end while (setvar "modemacro" ".") (setvar "cmdecho" 1) (prompt "\n--- Xref change finished! ---") (princ) ); end of XReload Quote
Lee Mac Posted September 27, 2011 Posted September 27, 2011 Irne, Unless I've overlooked something, couldn't this: (while (wcmatch name "*\\*") (setq name (substr name (+ (vl-string-search "\\" name) 2))) ) (while (wcmatch name "*.[dD][wW][gG]") (setq name (substr name 1 (- (strlen name) 4))) ) Become: (vl-filename-base name) Quote
irneb Posted September 28, 2011 Posted September 28, 2011 Thanks yes, I can't remember what I was thinking when I wrote that lot. It couldn't've been to avoid vla, since it's used elsewhere. Quote
Lee Mac Posted September 28, 2011 Posted September 28, 2011 It couldn't've been to avoid vla, since it's used elsewhere. Ah, the joys of Mac Quote
caddcop Posted October 25, 2012 Posted October 25, 2012 Actually, the new line of code needs to be: (setq name (vl-filename-base name)) But I am a newbee to the world of lisp and VL, so it took me a while to figure that out. I also combined the XReload into my version. ;================================================================================= ; RenameXRefs - renames xref name to match filename (base name) ;================================================================================= (vl-load-com) (defun c:RenameXRefs (/ name) (vlax-for bo (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object))) (if (= (vla-get-IsXref bo) :vlax-true) (progn (setq name (vla-get-Path bo)) (setq name (vl-filename-base name)) (vl-catch-all-apply 'vla-put-Name (list bo name)) ) ) ) (XReload) (princ) ) ;================================================================================= ;==== Xref Reload routine - Reloads XRef's after rename ==== ;================================================================================= (defun XReload (/ cObj cName); Updated 2007-10-1: added error trap (defun *error*(msg) (setvar "modemacro" ".") (setvar "cmdecho" 1) (princ "\n...Reload xref terminated!!! ") (princ) ); end of *error* (setvar "modemacro" "Reloading loaded xrefs......please wait......") (setvar "cmdecho" 0) (setq cObj(tblnext "BLOCK" T)) (while cObj (setq cName(cdr(assoc 2 cObj))) (if (and (=(logand(cdr(assoc 70 cObj))32)32) (=(logand(cdr(assoc 70 cObj))4)4) ); end and (progn (vl-cmdf "_.xref" "_unload" cName) (vl-cmdf "_.xref" "_reload" cName) ); end progn ); wnd if (setq cObj(tblnext "BLOCK")) ); end while (setvar "modemacro" ".") (setvar "cmdecho" 1) (prompt "\n--- Xref change finished! ---") (princ) ); end of XReload Quote
Lee Mac Posted October 25, 2012 Posted October 25, 2012 Actually, your code could be shortened to: (defun c:renamexrefs ( ) (vlax-for b (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) (if (= :vlax-true (vla-get-isxref b)) (progn (vl-catch-all-apply 'vla-put-name (list b (vl-filename-base (vla-get-path b)))) (vla-reload b) ) ) ) (princ) ) (vl-load-com) (princ) Quote
iconeo Posted May 6, 2016 Posted May 6, 2016 Actually, your code could be shortened to: (defun c:renamexrefs ( ) (vlax-for b (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) (if (= :vlax-true (vla-get-isxref b)) (progn (vl-catch-all-apply 'vla-put-name (list b (vl-filename-base (vla-get-path b)))) (vla-reload b) ) ) ) (princ) ) (vl-load-com) (princ) I receive the following error when running the above code. However, the code does work. Thanks. ; error: Automation Error. File access error Quote
Vincenthatch Posted October 5, 2023 Posted October 5, 2023 Hi, Is it possible to get the same lisp but able to rename the xref even if they are in different folder ? Thnaks 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.