Hi,
I have many DWG files and I have some text to replace in these DWG files.
And I have a CSV file containing the name of these files and the values will be assigned to each file as follows:
The text to be replaced in DWG files is fixed. So this part is easy.
COLUMN 3 --> QDT
COLUMN 4 --> QSC
COLUMN 5 --> QFM
COLUMN 9 --> QAE
COLUMN 10 -> QSAE
COLUMN 11 -> QSY
COLUMN 12 -> QSSY
COLUMN 13 -> QLN
COLUMN 14 -> QDCT
COLUMN 15 -> QDCN
The thing that I want to do is:
1 - Get the values from the CSV table by looking at the name from the first column.
2 - Replace the values in the DWG file with the values from the table.
3 - Do these for all the files in the directory.
Well actually I created a AutoLisp Program that does all of this except the last part. I can't run it for multiple files.
1 - I used LM:ReadCSV to read the table.
(setq csv_file "C:/VARIABLES.csv")
(setq csv_data (LM:readcsv csv_file)) ;WHOLE TABLE
2 - I used this code to Find&Replace method:
(defun change_it (old new)
(setq OldTxt old
NewTxt new)
(setq ss (ssget "x" '((0 . "TEXT,MTEXT"))))
(setq i (sslength ss))
(while (not (minusp (setq i (1- i))))
(setq oText (vlax-ename->vla-object (ssname ss i)))
(setq Txt (vlax-get-property oText 'TextString))
(if (vl-string-search OldTxt txt)
(progn
(setq newChg (vl-string-subst NewTxt OldTxt txt))
(vlax-put-property oText 'TextString newchg)
(vlax-invoke-method oText 'Update)
)
)
)
(princ)
)
3 - I used this function to make all the changes for a single file:
(defun _replace_all_text ()
(foreach line csv_data
(setq pafta_no (nth 0 line)) ;Gets the first column to get the file name
(if (= (car line) file_name) ;Gets the line where the filename matches.
(progn
(change_it "QDT" (nth 2 line)) ;DATE QDT
(change_it "QSC" (nth 3 line)) ;SCALE QSC
(change_it "QFM" (nth 4 line)) ;FORMAT QFM
(change_it "QAE" (nth 8 line)) ;AREA QAE
(change_it "QSAE" (nth 9 line)) ;SUBAREA QSAE
(change_it "QSY" (nth 10 line)) ;SYSTEM QSY
(change_it "QSSY" (nth 11 line));SUBSYSTEM QSSY
(change_it "QLN" (nth 12 line)) ;LANGUAGE QLN
(change_it "QDCT" (nth 13 line));DOCTYPE QDCT
(change_it "QDCN" (nth 14 line));DOCNO QDCN
)
)
)
)
I tried to use BFIND program from "lee-mac" but I couldn't manage to use it with an external CSV file.
I also tried to use objectdbx wrapper from "lee-mac" but it doesn't work since "change_it" function has some commands such as "ssget".
I don't want to use an external software due to privacy reasons. What is your suggestions?
Solved! Go to Solution.
Solved by bahayalnizhotmail_com. Go to Solution.
like this:
(load "lispfilename") ; a line command in script file
but you can also load the necessary lisp files from appload startup suite
What do you mean i am using script pro and open each file manually?
Did you install script pro?
This is special program from autodesk to run script program on a list of drawings.
Look into OBDX this allows the changing of a dwg without opening it.
The other is using Accoreconsole, its possible to do a full directory via a bat file auto selecting dwg files, but some VL code will not work but there is possibly a work around for this problem. A possible problem (vlax-put-property oText 'TextString newchg) change to a entmod method.
Ok open a dwg, change text, then save, its called go to lunch and run. With no user interaction it can be a reasonable speed.
Thank you for the answer. Currently I'm trying to figuring out how to use ODBX. It would be really nice for me if you have any suggestions for the training. Secondly, the main problem here I think find the text to be changed. Right now, in my method, I'm using SSGET to select all the text and then VL methods to filter them (as shown in the code block 2). But using SSGET method to select all the text makes it impossible to use ODBX as it also stated on its website:
Back to the script method it would look like this a .scr file. SCRIPT will run it. You need to make sure your lisp runs ok on a sample dwg.
Open dwg1
(load "my lisp file")
(change_it "old1" "new1")
close y
open dwg2
(load "my lisp file")
(change_it "old2" "new2")
close y
open dwg3
(load "my lisp file")
(change_it "old3" "new3")
close y
....................
So you need to read the csv file and then write the script file. Putting correct values for old & new.
Hi,
Thank you for the answer. I fixed this problem:
1 - I inserted my LSP file into the autoload section in AutoCAD.
2 - I placed a function call in the last line of the code to make it execute automatically.
3 - I utilized a .BAT file to open each file in a directory with a 5-second delay.
@Anonymous off
setlocal
set "directory=%~dp0"
for %%F in ("%directory%\*.*") do (
if /I not "%%~nxF"=="%~nx0" (
start "" "%%F"
ping -n 5 127.0.0.1 >nul
)
)
endlocal
But I'm still searching for an alternative solution to enhance the efficiency of this process. I am aware that it's achievable by using ActiveX (VLA) functions in AutoLISP.
My objective is to locate all text elements within a VL AutoCAD document object, filter them based on their string content, and modify them. If I can accomplish this solely using VLA functions, I will be able to utilize Lee-Mac's ObjectDBX.
Here is the solution for the "change_it" function! Now I'm using only ActiveX functions to find and replace text contents. In this way, I am now able to use Lee-Mac's ObjectDBX. Basically, the program checks every object in every layout in the document, and if the string contains the text, it replaces it with the new text.
(defun change_it (OldTxt NewTxt doc / txt)
(vlax-for layout (vla-get-layouts doc) ;GET ALL THE LAYOUTS AND ITERATE TROUGH THEM
(vlax-for entry (vla-get-block layout); ITERATE TROUGH ALL THE OBJECTS
(if
(or (eq (vla-get-objectname entry) "AcDbMText") ;CHECK IF THE OBJECT IS "MTEXT"
(eq (vla-get-objectname entry) "AcDbText") ;CHECK IF THE OBJECT IS "TEXT"
)
(progn
(setq txt (vlax-get-property entry 'TextString)) ;GET THE STRING CONTENT
(if (vl-string-search OldTxt txt) ;CHECK THE STRING CONTENT IF IT CONTAINS THE OLD TEXT
(progn
(setq newChg (vl-string-subst NewTxt OldTxt txt))
(vlax-put-property entry 'TextString newchg) ;REPLACE THE OLD TEXT WITH THE NEW ONE
(vlax-invoke-method entry 'Update)
)
)
)
)
)
)
(princ)
)
As you can see in the code, I also added "doc" variable into the function to be able to use Lee-Mac's ObjectDBX.
Can't find what you're looking for? Ask the community or share your knowledge.