Carry Out Mass Project Path Updates for AutoCAD Electrical Project Files
1 Mar, 2017 By: Stan WileIMAGINiT Tricks Tutorial: Whenever AutoCAD Electrical is upgraded, the default symbol library paths must be updated on all past project files — a time-consuming process. This tutorial demonstrates using a LISP routine to make this task easier.
Editor's note: This tutorial courtesy of IMAGINiT Technologies.
For years, I have asked for a better way to update the library and icon menu paths saved in AutoCAD Electrical project files.
The problem is that each year, the default paths change because the year number in the path changes. After the previous release has been uninstalled, all past project files no longer work. The symbols can no longer be found unless the Project Properties are opened and all paths are updated by pressing the Default button on all four headings. (Pressing Default reads in the new environment file defaults and updates the paths.)
This can become a real time sink, since every project file needs to be updated individually. And even then, it’s a process since the Default button needs to be pressed on all four path types. I have been requesting a Default All button, but that still means each project file needs to be loaded and then edited.
Fortunately, I happened upon a LISP routine (which you'll find at the end of this tutorial) that is far better than my original request. It can update all project file library and icon paths in a selected folder and all subfolders. To demonstrate how, here is my demo project file with paths all set to the old 2016 paths.
Simply APPLOAD the LISP, then enter the following: (CHANGE_PROJECTS nil nil “2016” “2017”).
Next, select the desired folder from the dialog that pops up. That’s it! All paths update at once. It even works if the project is actively loaded in Electrical at the time.
From my experimentation, I found this method works as well:
(CHANGE_PROJECTS “M:/Library/Schematic/” “M:/Library/Panel/” nil nil)
This will remove all other paths and update them with the paths you provided. Note the use of forward slashes, not backslashes! Using a backslash causes them to be removed, and only the text is placed in the path. The first path is for the schematic libraries, and the second path will update the panel footprint paths.
I also tried all four variables hoping for an extra path and updated years, but only the years were updated.
Be sure to test this on a small batch of test projects before moving into production data. And of course, ensure you have a good backup before you begin any mass data manipulation.
; Description: This function is used to replace a specified item in a list
; curlst - List to replace in
; nthitem - index to replace (0 based)
; newval - Value to set the list item to
(defun replace_in_list (curlst nthitem newval / idx item nextitem rtrn)
(setq rtrn nil)
(if (> (length curlst) nthitem)
(progn
(setq idx 0)
(foreach item curlst
(progn
(if (= idx nthitem)
(setq nextitem newval)
; else
(setq nextitem item)
)
(setq rtrn (cons nextitem rtrn))
)
(setq idx (+ idx 1))
)
(setq rtrn (reverse rtrn))
)
)
rtrn
)
; Description: This function is used to make the requested changes on the given WDP file
; newssympath - New schem symbol path
; newpsympath - New panel symbol path
; oldpathpart - When using routine in find/replace mode this is the part to find
; newpathpart - when using routine in find/replace mode this is the part that is the replacement
;
; To replace the whole path with something you provide, use the first two params otherwise they
; should be nil.
; To use the find/replace functionality use the last two params otherwise they should be nil.
(defun set_or_change_one_symbol_path (wdpfile newssympath newpsympath oldpathpart newpathpart
/ projdata t_lst a_lst p_lst d2_lst s_sym_paths p_sym_paths rtrn)
(setq rtrn nil)
; Make sure they passed in valid data
(if (or oldpathpart newssympath)
(progn
(setq projdata (c:wd_proj_wdp_data_fnam wdpfile))
(if projdata ; Were we able to read in the data?
(progn
; Yes so separate the data into lists, modify the path and write it back out
; First separate
(setq t_lst (nth 1 projdata))
(setq a_lst (nth 2 projdata))
(setq p_lst (nth 3 projdata))
(setq d2_lst (nth 5 projdata))
; Now modify it
(if (AND p_lst (/= (nth 1 p_lst) ""))
(progn
(if oldpathpart ; Use find/replace
(progn
; First the schem path
(setq s_sym_paths (nth 1 p_lst))
(setq s_sym_paths (strcase s_sym_paths T))
(setq oldpathpart (strcase oldpathpart T))
(while (vl-string-search oldpathpart s_sym_paths)
(setq s_sym_paths (vl-string-subst newpathpart oldpathpart s_sym_paths))
)
; Next the panel path
(setq p_sym_paths (nth 3 p_lst))
(setq p_sym_paths (strcase p_sym_paths T))
(setq oldpathpart (strcase oldpathpart T))
(while (vl-string-search oldpathpart p_sym_paths)
(setq p_sym_paths (vl-string-subst newpathpart oldpathpart p_sym_paths))
)
;(princ s_sym_paths)
)
;else direct replacement
(progn
; First schem path
(setq s_sym_paths newssympath)
; Next panel path
(if newpsympath
(progn
(setq p_sym_paths newpsympath)
)
;else
(progn
(setq p_sym_paths (nth 3 p_lst))
)
)
)
)
(setq p_lst (replace_in_list p_lst 1 s_sym_paths))
(setq p_lst (replace_in_list p_lst 3 p_sym_paths))
;(princ p_lst)
; Now write the data back out to the file
(c:wd_proj_wdp_write wdpfile t_lst a_lst p_lst d2_lst)
(setq rtrn T)
)
)
)
)
)
)
rtrn
)
; Description: This function is used to find all WDPs in a folder/subfolders and makes the requested changes
; newssympath - New schem symbol path
; newpsympath - New panel symbol path
; oldpathpart - When using routine in find/replace mode this is the part to find
; newpathpart - when using routine in find/replace mode this is the part that is the replacement
;
; To replace the whole path with something you provide, use the first two params otherwise they
; should be nil.
; To use the find/replace functionality use the last two params otherwise they should be nil.
(defun set_all_symbol_paths (fldr newssympath newpsympath oldpathpart newpathpart / filelst filename)
(setq filelst (c:wd_subfolder_wildcardsearch fldr "*.wdp"))
(if filelst ; found files?
(progn
(foreach filename filelst (set_or_change_one_symbol_path filename newssympath newpsympath oldpathpart newpathpart))
)
)
)
; Description: This is the main function call that starts off the process. It brings up the
; UI to browse for a folder and then passes that on to the routine that finds
; all of the WDPs.
; newssympath - New schem symbol path
; newpsympath - New panel symbol path
; oldpathpart - When using routine in find/replace mode this is the part to find
; newpathpart - when using routine in find/replace mode this is the part that is the replacement
;
; To replace the whole path with something you provide, use the first two params otherwise they
; should be nil.
; To use the find/replace functionality use the last two params otherwise they should be nil.
(defun change_projects (newssympath newpsympath oldpathpart newpathpart / fldr rtrn)
(setq rtrn nil)
(setq fldr (c:via_browseforfolder))
(if fldr ; Did they select a folder?
(progn
; Make sure the path ends in a slash
(if (not (c:ace_find_substr fldr "/" (strlen fldr))) (setq fldr (strcat fldr "/")))
(set_all_symbol_paths fldr newssympath newpsympath oldpathpart newpathpart)
(setq rtrn T)
)
)
rtrn
)
; end of LISP