PDA

View Full Version : Find and Replace text in multiple drawings



hbisco
2004-07-07, 06:47 PM
We have a folder with about 30 drawings that we need to go in and find and replace several different lines of text. I am a neophyte with creating lisp routines, but is there a way to create a routine which could go in and find and replace text in multiple drawings within a folder?

thanks,

Hugh

whdjr
2004-07-07, 09:23 PM
YES IT CAN BE DONE, BUT SOME SPECIFICS ARE NEEDED. IS THE TEXT DTEXT OR MTEXT?
WHAT VERSION OF AUTOCAD ARE YOU USING?

hbisco
2004-07-07, 10:38 PM
The text is dtext and we are using 2004, although i believe the drawings were originally created in R12 (maybe even R11).

tuomo.jarvinen
2004-07-11, 11:12 PM
I was asked a while ago to write a lisp to do something almost similar: to change attribute values in titleblocks in a bunch of drawings (same value to all). I figured out that the lisp must write a script to do the job. I quess this has been done many times but following is what I have came up with:

(WARNING: NOVICE PROGRAMMING)

;THIS LISP WRITES A SCRIPT TO CHANGE ATTRIBUTE VALUES IN A BUNCH OF DRAWINGS
;bgae = "Batch Global Attribute Edit"
;2:02 12.7.2004 TJ

;Assumption 1: Doslib available
;Assumption 2: Expresstools gatte available

;Usage:
;Move all the drawings in one folder
;Open one of them
;Load and run bgae.lsp (this lisp)
;Run the script (batch.scr, created in the same folder)


(defun c:bgae (/ dwgnames titleblock blockname attrib-name new-attrib-val scriptname dwg-in-turn)

;creating a list of drawings:

(setq dwgnames (dos_dir (strcat (getvar "dwgprefix") "*.dwg")))

;getting the information: blockname, attribute name and the new value:

(setq titleblock (entsel "Please choose a block: "))
(setq blockname (cdr (assoc 2 (entget (car titleblock)))))
(command "undo" "m")
(command "explode" titleblock)
(setq attrib-name (cdr (assoc 2 (entget (car (entsel "Please choose an attribute: "))))))
(command "undo" "b")
(setq new-attrib-val (getstring "New value for attribute? "))


;writing the script:

(setq scriptname (open (strcat (getvar "dwgprefix") "batch.scr") "w"))
(write-line "isavebak 0" scriptname)
(write-line "close n" scriptname)

(progn
(repeat (length dwgnames)
(setq dwg-in-turn (car dwgnames))
(setq dwgnames (cdr dwgnames))

(write-line (strcat "open " (getvar "dwgprefix") dwg-in-turn) scriptname)
(write-line (strcat "gatte b " blockname " " attrib-name " " new-attrib-val) scriptname)
(write-line (strcat "Y qsave close") scriptname)

) T)

(close scriptname)
)

ScriptPro from Migration Assistant could also be helpful in this kind of tasks.

Hopely somebody more skillfull comments this subject...

whdjr
2004-07-12, 02:26 PM
Hugh,

I think I've failed you. I'm so close but just can't close it. The code I have below gives you a dialog box to select a file (single selection only). Once you select the file and click open it reloads the dialog box to select another file and continues this process until you click cancel. Then it continues with the rest of the routine. This process can be changed to select all the dwg's in a folder if you need that instead.

I tried to emulate the ACAD find & replace, but did a bad job. I put in 3 options to search by:
1. Matching the whole word only.
2. Matching case only.
3. Matching both whole word and case.

To say the least this was not easy. I quickly determined that I didn't have the time nor the skills to effectively construct this for you. So I am putting my work here in hopes that some other brave souls will take pity on me and help you out and instruct me on how to do this (if even possible). My code currently only works for option #2 (case). I am too busy right now to work on option #1. The only way I could think of to implement option #1 was to look at the ascii character values of the text string and compare those to the space value, I just don't have that much time right now. Sorry.

The other problem that I had wasn't so big, kind of little. I can't get the program to save the changes back to the file. I'm doing something wrong ang\d its not updating the textstring properly. Once again I'm am truely sorry for getting your hopes up and then failing you miserably.

Hope this helps in some small way,


(vl-load-com)
(defun *error* (msg)
(princ "\nError: ")
(princ msg)
(princ)
(if (and dbxdoc (not (vlax-object-released-p dbxdoc)))
(vlax-release-object dbxdoc)
)
(gc)
(princ)
)


(defun fandr (txtobj)
(vl-string-subst news olds (vla-get-textstring txtobj))
)


(defun findandreplacetext (document)
(vlax-for item (vla-get-modelspace document)
(cond ((not (= (vla-get-ObjectName item) "AcDbText")))
;((and whole case)()) This matches whole word and case
;(whole ()) This matches whole word only
(case (fandr item)); This matches case only
(T (fandr item)); This matches neither whole word nor case
)
)
)


(defun c:tfar (/ file files dcl_id dbxdoc of olds news whole case)
(setq file "")
(while (setq file
(getfiled "Select a file to replace text in" file "dwg" 128)
)
(setq files (cons file files))
)
(cond ((not files) (princ "No files were selected."))
((not (setq dcl_id (load_dialog "textreplace.dcl")))
(princ "Unable to load dialog box.")
)
((not (new_dialog "textreplace" dcl_id))
(princ "Could not load (textreplace.dcl) dialog box.")
)
((not
(and (not (mode_tile "eb1" 2))
(action_tile "eb1" "(setq olds (get_tile \"eb1\"))")
(action_tile "eb2" "(setq news (get_tile \"eb2\"))")
(action_tile "tog1" "(setq whole $value)")
(action_tile "tog2" "(setq case $value)")
(action_tile "cancel" "(done_dialog)")
(action_tile "ok" "(done_dialog)")
(if (and (= (start_dialog) 1)
(> (strlen olds) 0)
(> (strlen news) 0)
)
(not (unload_dialog dcl_id))
(unload_dialog dcl_id)
)
)
)
(princ "Function Cancelled by User.")
)
((not (setq dbxdoc (vla-GetInterfaceObject
(vlax-get-acad-object)
"ObjectDBX.AxDbDocument.16"
)
)
)
(princ "Unable to load ObjectDBX.")
)
(T
(foreach f (reverse files)
(setq of (vl-catch-all-apply
'(lambda ()
(vlax-invoke-method dbxdoc 'open f)
)
)
)
(if (vl-catch-all-error-p of)
(*error* (vl-catch-all-error-message of))
(progn
(findandreplacetext dbxdoc)
(vla-saveas dbxdoc f)
)
)
)
)
)
(if (and dbxdoc (not (vlax-object-released-p dbxdoc)))
(vlax-release-object dbxdoc)
)
(gc)
(princ)
)





//dcl_settings : default_dcl_settings {audit_level = 3; }
textreplace : dialog {
label = "Replace Text" ;
: row {
: column {
: edit_box {
key = "eb1";
label = "Find text string:";
edit_width = 20;
is_default = true;
}
: edit_box {
key = "eb2";
label = "Replace with:";
edit_width = 20;
}
}
: boxed_column {
: toggle {
key = "tog1";
label = "Find whole words only";
}
: toggle {
key = "tog2";
label = "Match case";
}
}
}
ok_cancel ;
}

eugene_k
2010-04-06, 02:18 AM
I believe those people capable of doing this level of lisp programing could do much better job by creating a universal code for batch processing various lisp files on multiple drawings. Instead of solving just one problem of text replacement, we couls just start this batch engine program, select the files to be processed and then select a lisp to run! It could be lisp for text replacement or for anything else - you name it. This is where the real power is. Maybe Autodesk should provide this sort of engine instead of its ScriptPro...
There is no good tool availbale at the moment. If anybody ever find something good, please let me know!

jsowinski
2010-04-06, 06:55 PM
Here is a routine that came from Cadalyst Tips (author - Andrzej Gumula). This is a great tool that works fast. If you encounter an error while running you will want to check the part of the code that looks for (getvar "AcadVer"). "ObjectDBX.AxDbDocument.17" You may have to update the number in the lisp to the version of AutoCAD you're using.

alanjt
2010-04-06, 06:59 PM
http://www.cadtutor.net/forum/showthread.php?t=46135

raghu.sahaja
2010-07-20, 10:15 AM
Here is a routine that came from Cadalyst Tips (author - Andrzej Gumula). This is a great tool that works fast. If you encounter an error while running you will want to check the part of the code that looks for (getvar "AcadVer"). "ObjectDBX.AxDbDocument.17" You may have to update the number in the lisp to the version of AutoCAD you're using.

Hi, what command i have to type in command line

Dave Jones
2010-07-21, 03:19 PM
Hi, what command i have to type in command line

command: Reid

Dave Jones
2010-07-21, 03:22 PM
I believe those people capable of doing this level of lisp programing could do much better job by creating a universal code for batch processing various lisp files on multiple drawings. Instead of solving just one problem of text replacement, we couls just start this batch engine program, select the files to be processed and then select a lisp to run! It could be lisp for text replacement or for anything else - you name it. This is where the real power is. Maybe Autodesk should provide this sort of engine instead of its ScriptPro...
There is no good tool availbale at the moment. If anybody ever find something good, please let me know!

not available for free, but available none the less and has been for some years

irneb
2010-07-22, 11:32 AM
I believe those people capable of doing this level of lisp programing could do much better job by creating a universal code for batch processing various lisp files on multiple drawings. Instead of solving just one problem of text replacement, we couls just start this batch engine program, select the files to be processed and then select a lisp to run! It could be lisp for text replacement or for anything else - you name it. This is where the real power is. Maybe Autodesk should provide this sort of engine instead of its ScriptPro...
There is no good tool availbale at the moment. If anybody ever find something good, please let me know!Well, having it run through a SCR file is really not dificult. E.g. make your SCR file as so:
(load "FileName.LSP")
(function_name arg1 arg2)
CommandName Input1 Input2So you can have this working through ScriptPro (http://usa.autodesk.com/adsk/servlet/item?linkID=9240618&id=4091678&siteID=123112), or if you're on 64bit use AutoScript (http://www.cadig.com/products/autocad-script-pro.php).

And BTW, there is already something which simply runs a LSP file on multiple DWG's. It basically just creates the SCR file and then runs it. It's called BatchLisp (http://www.jefferypsanders.com/autolisp_batchlisp.html).

david.hassan234486
2010-11-16, 04:32 PM
I get an error that says

VLA-OBJECT nil

carlosmanteigas
2011-09-24, 11:44 PM
hi!

I'm using AutoCAD 2009, and i've received de error message:"; error: no function definition: VLAX-GET-ACAD-OBJECT" :(
Can u please help?

Lee Mac
2011-09-25, 11:36 AM
I'm using AutoCAD 2009, and i've received de error message:"; error: no function definition: VLAX-GET-ACAD-OBJECT" :(
Can u please help?

Add:


(vl-load-com)

On a new line at the end of the file.

bjonzz
2012-01-19, 08:59 PM
when i add the (vl-load-com) i get a new error:

Loaded new command Reid.
[c]2004 Andrzej Gumula.
Command: reid
; error: Automation Error. Problem in loading application

Using Acad 2012
(this is version 18.2 so i am not sure about the version part of the LSP)

antistar
2012-01-20, 12:58 PM
Here is a routine that came from Cadalyst Tips (author - Andrzej Gumula). This is a great tool that works fast. If you encounter an error while running you will want to check the part of the code that looks for (getvar "AcadVer"). "ObjectDBX.AxDbDocument.17" You may have to update the number in the lisp to the version of AutoCAD you're using.

Hi to all,
I am running the routine and displays the following message:


Loaded new command Reid.
[c]2004 Andrzej Gumula.
Command: REID

Looking for text to replace. Please wait...

Cannot find in C:\_TEST\TEST-01.dwg. Probably drawing is open now.
Cannot find in C:\_TEST\TEST-02.dwg. Probably drawing is open now.
Cannot find in C:\_TEST\TEST-03.dwg. Probably drawing is open now.
ERROR: bad argument type: VLA-OBJECT nil
Command:

But these drawings are not open.
Could anyone help me with this?

Bruno.Valsecchi
2012-01-20, 02:19 PM
If you want try this...

You must save the lisp file "my_text_replace.lsp" in path (or create it) for AutoCad.
And after in new drawing load the code next



(defun c:make_script_for_text_replace ( / prefix file_scr old_str new_str)
(setq
prefix (strcat (vl-filename-directory (getfiled "Select a drawing file for folder target" "" "dwg" 16)) "\\")
file_scr (open (strcat prefix "job_on_folder.scr") "w")
)
(princ "\nBe careful with the case of character!")
(setq
old_str (getstring T "\nOld chain of character to replace: ")
new_str (getstring T "\nBy new chain of character: ")
)
(foreach dwg (vl-directory-files prefix "*.dwg" 1)
(write-line "_.open" file_scr)
(write-line (strcat "\"" prefix dwg "\"") file_scr)
(write-line "(load\"my_text_replace\")" file_scr)
(write-line (strcat "(my_text_replace \"" new_str "\" \"" old_str "\")") file_scr)
(write-line "_.qsave" file_scr)
(write-line "_.close" file_scr)
)
(close file_scr)
(princ (strcat "\nYou can run the SCRIPT :" prefix "job_on_folder.scr"))
(prin1)
)

antistar
2012-01-20, 05:01 PM
If you want try this...

You must save the lisp file "my_text_replace.lsp" in path (or create it) for AutoCad.
And after in new drawing load the code next



(defun c:make_script_for_text_replace ( / prefix file_scr old_str new_str)
(setq
prefix (strcat (vl-filename-directory (getfiled "Select a drawing file for folder target" "" "dwg" 16)) "\\")
file_scr (open (strcat prefix "job_on_folder.scr") "w")
)
(princ "\nBe careful with the case of character!")
(setq
old_str (getstring T "\nOld chain of character to replace: ")
new_str (getstring T "\nBy new chain of character: ")
)
(foreach dwg (vl-directory-files prefix "*.dwg" 1)
(write-line "_.open" file_scr)
(write-line (strcat "\"" prefix dwg "\"") file_scr)
(write-line "(load\"my_text_replace\")" file_scr)
(write-line (strcat "(my_text_replace \"" new_str "\" \"" old_str "\")") file_scr)
(write-line "_.qsave" file_scr)
(write-line "_.close" file_scr)
)
(close file_scr)
(princ (strcat "\nYou can run the SCRIPT :" prefix "job_on_folder.scr"))
(prin1)
)


Thanks Bruno.
This routine worked for me.