Any idea why this doesnt work.. I swear this syntax was fine pre 2010.
Renaming
PREFIX-VDS-stuff
SOMEOTHER-VDS-stuffso
to
PREFIX-WST-stuff
SOMEOTHER-WST-stuffso
i.e
*VDS*
*WST*
Solved! Go to Solution.
Solved by vladimir_michl. Go to Solution.
I've jsut tested in 2010, but it didn't work.
Hmm....are you sure did you use in 2010??
Could it perhaps be the length of the string?
AutoCAD sometimes balks at long strings - I have used the wildcard in rename as well, in ACAD 2011
@bkanthergolder wrote:
Any idea why this doesnt work.. I swear this syntax was fine pre 2010.
....
I replied on the thread on whatever other Forum this question is on that it doesn't work in my ol' 2004. However, I find in further trial that it does work with a * wildcard at the end, and it works with a limited wildcard situation [? wildcard(s), etc.] at the beginning. It just doesn't work with the anything-goes-no-matter-how-many-characters * wildcard at the beginning [and therefore also not with that at both the beginning and the end].
Its stange because as you can see it selects the correct layers when typing a dual wildcard..
It just doesnt rename them...!! 😞
I might have been using a custom tool now that i think about it.. shouldn't this be core functionality though i mean ****! it would take forever to have to rename layers on large proejcts!
Regards
@bkanthergolder wrote:
.... shouldn't this be core functionality though i mean ****! it would take forever to have to rename layers on large proejcts!
....
But it would be easy to build into an AutoLISP routine, which could work through the Layer table, and for each name, check whether it contains the "old" substring [for that, the double-wildcard-ended check would work], and if so, replace that with the "new" substring using (vl-string-translate). It could also be built to check whether the intended changed Layer name is one that already exists, keeping track of those it therefore couldn't change and notifying the User, and/or could either have the substrings built in or ask the User for them in a couple of different ways, and/or could handle more than one such operation in one shot using lists of old and new substrings, etc., etc. Is that something worth pursuing?
@Kent1Cooper wrote:
....But it would be easy to build into an AutoLISP routine, which could work through the Layer table, and for each name, check whether it contains the "old" substring [for that, the double-wildcard-ended check would work], and if so, replace that with the "new" substring using (vl-string-translate). It could also be built to check whether the intended changed Layer name is one that already exists, keeping track of those it therefore couldn't change and notifying the User, and/or could either have the substrings built in or ask the User for them in a couple of different ways, and/or could handle more than one such operation in one shot using lists of old and new substrings, etc., etc. Is that something worth pursuing?
[Actually, using (vl-string-subst).]
The following is built as a function with arguments [see the Usage note], but could easily be altered to be a command, prompting the User to supply the old and new substring content. It does not [yet] handle substitutions of more than one 'old'/'new pairing at a time. Limited testing, and it could probably use an error handler, Undo begin/end wrapping, etc.
;; LNSS function [= Layer Name Substring Substitution]
;; To replace a specified substring with another in the names of
;; all Layers whose names contain the 'old' substring.
;; Usage: (LNSS "THIS" "THAT") will replace "THIS" with "THAT" in
;; all Layer names containing "THIS" anywhere in them, provided
;; there is not already a Layer with the altered name.
;; Reports a list of all Layer name(s) not changed because they
;; are already in use.
;; Not case-sensitive -- 'new' will be used in uppercase, regardless
;; of how entered, and will replace 'old' in any case combination.
;; Kent Cooper, 30 May 2014
(defun LNSS (old new / layinfo oldname newname laydata notchanged)
(while
(setq layinfo (tblnext "layer" (not layinfo))); step through Layers from beginning
(if (wcmatch (setq oldname (strcase (cdr (assoc 2 layinfo)))) (strcat "*" (strcase old) "*")); name contains old substring
(progn ; then
(setq newname (vl-string-subst (strcase new) (strcase old) oldname)); edit Layer name
(if (tblsearch "layer" newname); Layer already exists
(setq notchanged (cons oldname notchanged)); then
(progn ; else -- change it
(setq laydata (entget (tblobjname "layer" oldname)))
(entmod (subst (cons 2 newname) (assoc 2 laydata) laydata))
); progn
); if ['newname' Layer already exists or not]
); progn
); if [name contains 'old' or not]
); while
(if notchanged
(progn
(prompt "\nLayer name(s) NOT changed: ")
notchanged
); progn
); if
); defun
Usage for the OP's example: (LNSS "VDS" "WST")
EDIT: Oh, and by the way, if any Layer names contain the 'old' substring more than once, it will replace only the first occurrence [that's how (vl-string-subst) works]. If you want to get them all, run the function more than once.
You can also use the RRENAME utility (regular-expression rename of any symbol table) from www.cadstudio.cz/freeware
Its find/replace parameters for the above mentioned layout example will be:
Find: (.+)-VDS-(.+)
Replace: $1-WST-$2
Vladimir Michl, www.cadstudio.cz www.cadforum.cz
Vladmir..
Thanks that does work.. strange syntax (the whole wildcard * is a (.+) S$
and i had to use $1-WST-$2. I know you typed dollars below.. The default font family on this forum makes them look like s'sss though.
Ohh.. and the routine will not change the active layer as well.. but easy fixed manually obviouslly.
Thanks again..
Brad
P.$
S$
If you have to do the renaming task in multiple files without opening the drawings then you can try the free tool BatchInDatabase which is compatible with AutoCAD 2012 to 2015
Kent1Cooper,
I found this routine you posted here: https://forums.autodesk.com/t5/autocad-2010-2011-2012/rename-command-and-dual-sided-wildcards-lt-wor... last year regarding the renaming of multiple layers within a dwg file.
(defun LNSS (old new / layinfo oldname newname laydata notchanged)
(while
(setq layinfo (tblnext "layer" (not layinfo))); step through Layers from beginning
(if (wcmatch (setq oldname (strcase (cdr (assoc 2 layinfo)))) (strcat "*" (strcase old) "*")); name contains old substring
(progn ; then
(setq newname (vl-string-subst (strcase new) (strcase old) oldname)); edit Layer name
(if (tblsearch "layer" newname); Layer already exists
(setq notchanged (cons oldname notchanged)); then
(progn ; else -- change it
(setq laydata (entget (tblobjname "layer" oldname)))
(entmod (subst (cons 2 newname) (assoc 2 laydata) laydata))
); progn
); if ['newname' Layer already exists or not]
); progn
); if [name contains 'old' or not]
); while
(if notchanged
(progn
(prompt "\nLayer name(s) NOT changed: ")
notchanged
); progn
); if
); defun
I could use greatly such a routine myself if I can please have you advise me on exactly where in the routine I need to put my old/new layer names.
My use would be to search for all layers beginning with a certain prefix (note that the latter parts of the layer name always varies):
Examples-
LAY-RiskAssessmentMap_Grid_67071
LAY-RiskAssessmentMap_Label_67071
LAY-RiskAssessmentMap_Tag_67071
And rename those old layers to this:
Example-
100-LAY-RiskAssessmentMap_Grid_67071
100-LAY-RiskAssessmentMap_Label_67071
100-LAY-RiskAssessmentMap_Tag_67071
I need to make this part of a larger lisp routine so manually using the rename command within Autocad is not an option.
I have tried various things but cannot get your routine to work and it is my ignorance of the lisp code that is to blame.
The first obstacle is my getting it to run... I can do a manual load application and the routine does successfully load; however, when I initiate it with LNSS command it tells me "Unknown command".
I appreciate any help you can provide.
Navarreb - notice that there is no c: in front of LNSS which means it cannot be run as an ordinary command.
Once you have loaded it, type (LNSS "oldname" "newname") where you substitute your old and new layer names for oldname newname. If it runs correctly it will return "nil" on the command line. Don't forget the parnethesis and quotes, won't work without them!
HTH!
Jeff.Whitney,
Of course! I totally missed the C: when thats the first thing I should have seen.
Thanks for that and the explanation about typing the (LNSS "oldname" "newname").
The typing did work fine; however, I needed it to run inside a larger routine (that does many other things) on multiple preconfigured layers that are "grouped" with the same prefixes. For example, the layer prefixes "LAY-" and "CART-" and "PROJ-" and "TOPO-" need to have a number added to their names like "199-LAY-" and "100-CART-" and "102-PROJ-" and "301-TOPO-" yet retain the last part of the layer name.
Looking below you can see how I revised the code for my use; but, when I incorporate this into my larger routine it, of course, runs automatically upon loading that larger routine... instead of waiting until I initiate the command to run the larger routine. Now I get the result of half the routine being completed and half not before I even initiate the command of the larger routine.
If you could, please explain how I can have this smaller routine NOT run upon loading the larger routine that it is in, but rather wait until I actually enter the command to initiate the larger routine.
I'm sure you know this, but for those who may benefit from this post, the following revised code runs the routine as a stand alone unit whereby just loading the file, the routine initiates and makes the changes (if this may be of interest to you):
(defun C:LNSS (old new / layinfo oldname newname laydata notchanged)
(while
(setq layinfo (tblnext "layer" (not layinfo))); step through Layers from beginning
(if (wcmatch (setq oldname (strcase (cdr (assoc 2 layinfo)))) (strcat "*" (strcase old) "*")); name contains old substring
(progn ; then
(setq newname (vl-string-subst (strcase new) (strcase old) oldname)); edit Layer name
(if (tblsearch "layer" newname); Layer already exists
(setq notchanged (cons oldname notchanged)); then
(progn ; else -- change it
(setq laydata (entget (tblobjname "layer" oldname)))
(entmod (subst (cons 2 newname) (assoc 2 laydata) laydata))
); progn
); if ['newname' Layer already exists or not]
); progn
); if [name contains 'old' or not]
); while
(if notchanged
(progn
(prompt "\nLayer name(s) NOT changed: ")
notchanged
); progn
); if
); defun
(c:LNSS "LAY-" "199-LAY-")
(c:LNSS "CART-" "100-CART-")
(c:LNSS "PROJ-" "102-PROJ-")
(c:LNSS "TOPO-" "301-TOPO-")
I am afraid that is beyond my limited skills with AutoLISP. I could probably figure it out but it would take a lot of time!
Hopefully Kent will see these exchanges and come up with a solution.
Well I'm certainly not complaining. Thank you for the help so far.
But yes, hopefully Kent will see this thread.
Seeing as this is his code, I was going to post my original question to him directly, but could not figure out how to do so through the forums; thus, I just did a reply to this year-old topic.
Thanks again
@Anonymous wrote:
... I revised the code for my use; but, when I incorporate this into my larger routine it, of course, runs automatically upon loading that larger routine... instead of waiting until I initiate the command to run the larger routine. ....
Command names (defun)'d with the C: aren't supposed to have arguments [things before the slash in the parentheses after the command name], at least Help says they shouldn't, though I have seen instances where it "works" anyway [such as, apparently, this one, if it's doing that stuff when you load the file]. I would suggest leaving the C: out of both the (defun) line at the top and the usage lines at the bottom.
But in either case, to get it to run only when you initiate the larger command, rather than when you load the file, put the usage lines inside the definition of the larger command. The definition of LNSS can be inside it or outside it:
(defun LNSS (old new / layinfo oldname newname laydata notchanged)
(while
.... the rest of it ....
); if
); defun
But then:
(defun C:YourLargerCommandName (/ what ever local variables)
.... whatever it does, including inside it the running of that routine on those Layers:
(LNSS "LAY-" "199-LAY-")
(LNSS "CART-" "100-CART-")
(LNSS "PROJ-" "102-PROJ-")
(LNSS "TOPO-" "301-TOPO-")
.... whatever else it does ....
); defun
I know this is old, but is there an updated version of this that will work in AutoCAD LT 2024, now that they've enabled the lisp functionality? I have tried running it as-is, but I get this:
Command: RRENAME
RegExp Renamimg of AutoCAD symbols/tables/styles (no Undo!); error: bad argument type: numberp: nil
Please note that AutoCAD LT 2024 offers a limited support of LISP. And unfortunately, RRENAME uses a couple of functions which are not available in LT. So it won't work in LT.
Vladimir Michl, www.arkance-systems.cz - www.cadforum.cz
Can't find what you're looking for? Ask the community or share your knowledge.