Jump to content

Replace text from list


B2P

Recommended Posts

Hi everyone,

 

Is there a routine to find and replace one text with another in an autocad file, that allows me to do this operation with several files at the same time? For example, having a list in excel in which the names of the files, the original text and the text to be replaced are registered.

 

NRO.     DRAWING          FIND          REPLACE

1               D01                   T01             R01

2               D02                   T02             R02

3               D03                   T03             R03

.                   .                         .                   .

.                   .                         .                   .

n               D0N                  T0N             R0N

 

In the file "D01" find the word "T01" and replace it with "R01", and so on with all the files in the list automatically without having to do the operation one by one.

 

Thanks in advance for the help.

 

 

Link to comment
Share on other sites

Thank you very much mdbdesign.


The routine is very good and works well. However, it does not allow me to do what I need to, because on many occasions several of the files contain the same text but the word to be replaced in each file is different. For example, there is a case where files D01, D02, and D03 contain the text T01, but the word you want to replace with is different, R01 for file D01, R02 for D02, and R03 for D03.

Link to comment
Share on other sites

You could try Lee Macs Script programme (or others) to process updating each file (I think this does it: http://www.lee-mac.com/scriptwriter.html ).

 

I have copied a text find and replace LISP (C:txtreplace) which has limitations but you might be able to use this - call this LISP from the scriptwriter above and it -should- work

 

In the LISP below you'll need to modify C:txtreplace so that old_text and new_text are read from your spreadsheet rather than as an input - I don't have anything to hand that does that but others might be able to change this around, and you could have old_text and new_text as lists, just repeat the FindReplaceAll command until you have gone through the full list.

 

 

Limitations.... this best works on Dtext, when an Mtext string gets too long it stops processing it after so many characters.. but if you only have short Dtexts to update it should work

 

 

(note that this is about the only command line find and replace lisp I could find, everything else is with a pop up box)

 

;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/find-and-replace-text/td-p/5649883
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:txtreplace( / old_text new_text)
  (setq old_text (getstring T "OLD Text to replace (replace in this model/paper space and text case as entered): "))
  (setq new_text (getstring T "NEW text to use: "))
  (FindReplaceAll old_text new_text)
  (princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FindReplaceAll - Changes Text, Mtext, Dimensions and Attribute Block entities
; that have a Find$ string with a Replace$ string.
; Arguments: 2
;   Find$ = Phrase string to find
;   Replace$ = Phrase to replace it with
; Syntax: (FindReplaceAll "old string" "new string")
; Returns: Updates Text, Mtext, Dimension and Attribute Block entities
; It is Case sensitive
;-------------------------------------------------------------------------------
(defun FindReplaceAll (Find$ Replace$ / BlkEntList@ BlkEntName^ BlkEntType$ Cnt#
  DimEntList@ DimEntName^ DimEntType$ EntList@ EntName^ EntType$ FindReplace:
  Mid$ Mid2$ NewText$ Num# Replace$ SS& Text$)
  ;-----------------------------------------------------------------------------
  ; FindReplace: - Returns Str$ with Find$ changed to Replace$
  ; Arguments: 3
  ;   Str$ = Text string
  ;   Find$ = Phrase string to find
  ;   Replace$ = Phrase to replace Find$ with
  ; Returns: Returns Str$ with Find$ changed to Replace$
  ;-----------------------------------------------------------------------------
  (defun FindReplace: (Str$ Find$ Replace$ / Cnt# FindLen# Loop Mid$ NewStr$ ReplaceLen#)
    (setq Loop t Cnt# 1 NewStr$ Str$ FindLen# (strlen Find$) ReplaceLen# (strlen Replace$))
    (while Loop
      (setq Mid$ (substr NewStr$ Cnt# FindLen#))
      (if (= Mid$ Find$)
        (setq NewStr$ (strcat (substr NewStr$ 1 (1- Cnt#)) Replace$ (substr NewStr$ (+ Cnt# FindLen#)))
              Cnt# (+ Cnt# ReplaceLen#)
        );setq
        (setq Cnt# (1+ Cnt#))
      );if
      (if (= Mid$ "") (setq Loop nil))
    );while
    NewStr$
  );defun FindReplace:
  ;-----------------------------------------------------------------------------
  ; Start of Main function
  ;-----------------------------------------------------------------------------

  (if (and (= (type Find$) 'STR)(= (type Replace$) 'STR)(/= Find$ ""))
    (progn
      (if (setq SS& (ssget "x" (list '(-4 . "<AND")'(-4 . "<OR")'(0 . "TEXT")'(0 . "MTEXT")'(0 . "DIMENSION")'(0 . "INSERT")'(-4 . "OR>")(cons 410 (getvar "CTAB"))'(-4 . "AND>"))))
        (progn
          (command "UNDO" "BEGIN")
          (setq Cnt# 0)
          (repeat (sslength SS&)
            (setq EntName^ (ssname SS& Cnt#)
                  EntList@ (entget EntName^)
                  EntType$ (cdr (assoc 0 EntList@))
                  Text$ (cdr (assoc 1 EntList@))
            );setq
            (if (= EntType$ "INSERT")
              (if (assoc 66 EntList@)
                (progn
                  (while (/= (cdr (assoc 0 EntList@)) "SEQEND")
                    (setq EntList@ (entget EntName^))
                    (if (= (cdr (assoc 0 EntList@)) "ATTRIB")
                      (progn
                        (setq Text$ (cdr (assoc 1 EntList@)))
                        (if (wcmatch Text$ (strcat "*" Find$ "*"))
                          (progn
                            (setq ReplaceWith$ (FindReplace: Text$ Find$ Replace$))
                            (entmod (subst (cons 1 ReplaceWith$) (assoc 1 EntList@) EntList@))
                            (entupd EntName^)
                          );progn
                        );if
                      );progn
                    );if
                    (setq EntName^ (entnext EntName^))
                  );while
                );progn
              );if
              (if (wcmatch Text$ (strcat "*" Find$ "*"))
                (progn
                  (setq ReplaceWith$ (FindReplace: Text$ Find$ Replace$))
                  (entmod (subst (cons 1 ReplaceWith$) (assoc 1 EntList@) EntList@))
                  (entupd EntName^)
                );progn
              );if
            );if
            (setq Cnt# (1+ Cnt#))
          );repeat
          (command "UNDO" "END")
        );progn
      );if
    );progn
  );if
  (princ)
);defun FindReplaceAll
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

Link to comment
Share on other sites

You could use your excel to write the script look at the sequence of a manual version, then just copy a column to notepad and save as a script. Get 1 line to work 1st ! Note the text must be in quotes. Look at concatenate function.

 

open d01 (FindReplaceAll "T01" "R01") close Y

open d02 (FindReplaceAll "t02" "R02") close Y

 

Note you must have your lisp autoloaded if you don't know how to do that post.

 

 

  • Like 1
Link to comment
Share on other sites

7 hours ago, BIGAL said:

You could use your excel to write the script look at the sequence of a manual version, then just copy a column to notepad and save as a script. Get 1 line to work 1st ! Note the text must be in quotes. Look at concatenate function.

 

open d01 (FindReplaceAll "T01" "R01") close Y

open d02 (FindReplaceAll "t02" "R02") close Y

 

Note you must have your lisp autoloaded if you don't know how to do that post.

 

 

That's easier than trying to get the info from excel.

 

You could add something like

(load "C:\\Users\\…lisp file location..\\AutoCAD LISPS\\mylisp.lsp") if your lisp isn't autoloaded?

open d01 ((load "c:\\ ………..lsp") FindReplaceAll "T01...… ) close Y

Link to comment
Share on other sites

First of all Thank you all so much for your valuable time.

 

Steven P, the routine works fine when I load it inside each file, although in some cases I had problems with some texts, due to the limitations you mention. I have tried to do it through a script as BIGAL recommends and with the code that you indicate in your second message but I cannot make it work.

 

rlx, the attached routine allows me to read the excel sheet directly, and when testing the files I have, it has successfully made the changes in each case. However it only makes the change to the file of the first row of the excel table. I have tested multiple files and modifying the paths, but in all cases it only executes the change for the first file in the table.

I would appreciate it very much if you could help me modifying the file so that it performs the operation with all the files in the list.
 
Thank you in advance.

Link to comment
Share on other sites

darn , I knew I should have written virtually untested...

just copied , pasted and modified some stuff from a couple of other routines together. Anyways , cleaned code up just a tiny bit and tried it on my work computer and it seems to be working on this side so hope attached one does what you want else have to look at it later because after , I dunno , 10 weeks 'working' from home my boss said not to just book my hours but I actually have to do something too... now he tells me! I'm in sooo much trouble now haha

B2P.lsp

Link to comment
Share on other sites

8 minutes ago, rlx said:

 10 weeks 'working' from home my boss said not to just book my hours but I actually have to do something too... now he tells me! I'm in sooo much trouble now haha


 

 

 

Your boss is weird

  • Funny 1
Link to comment
Share on other sites

RLX (setenv "excelline" "1") as 1st step once lisp updates do (setenv "exceline" "2") this way know to read the next row down etc. Really have no idea if its going to work.

 

Thinking more don't run a script run a macro in Excel that opens, load lisp etc closes and so on for a row range. Would be in VBA calling a lisp is supported. Again where would I start.

control Autocad from excel.lsp

Edited by BIGAL
Link to comment
Share on other sites

RLX, thank you very much for taking the time to modify the lisp, I have tried the new routine and it executes the action for all the files in the list, but on several occasions a window appears with the instruction in neerlandés (Kies uit lijst) asking me to select the file from the list, I click OK, and the program keeps loading and does not respond.
Another error that happens is that when I want to replace numbers, for example when trying to replace 20 for 10, 100 or 1000, the program replaces it with 1, and sometimes when I try to replace 3 with 500 it made the change but resulted in 50.


For now I have been using the routine with the files that have given me results and with those that give me problems I am changing them manually. I will try to run the lisp using excel with VBA as BIGAL recommends.

Link to comment
Share on other sites

It's probably a small fix, would have to do more testing. vba extension is not installed om my work computer so I stopped using it but if its working for you ... whatever works is best. And most of the time a simple script may not be the fasted but often it is the most stable. Good luck with the dwg's :beer:

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...