Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Find & Replace Text in Multiple DWG Files From a CSV Table

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
bahayalnizhotmail_com
2492 Views, 12 Replies

Find & Replace Text in Multiple DWG Files From a CSV Table

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:

bahayalniz_0-1685968098667.png

 

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?
 

12 REPLIES 12
Message 2 of 13

@bahayalnizhotmail_com  hi,

 

for item 3 check >> script pro << 

 

enjoy

moshe

 

Message 3 of 13

Thanks for the advice. Sorry for my silly questions, but I couldn't find how can I call LSP files that I've created from a SCR script file. Is there any guide for this?

Message 4 of 13

@bahayalnizhotmail_com ,

 

like this:

(load "lispfilename")  ; a line command in script file

 

but you can also load the necessary lisp files from appload startup suite

Message 5 of 13

I used the Appload starter pack and ScriptPro together. Still, I didn't find it useful as it opened each file individually. I have many DWG files and opening each one and closing doesn't seem like the right way to solve this particular issue.

Thank you for your valueble time.
Message 6 of 13

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.

 

 

Message 7 of 13

Sorry if my message wasn't clear enough.

I wrote a script to use in Script Pro and set my LSP files to be loaded automatically with Appload Startup Suite.

However, Script Pro opens all the DWG files I have selected one by one to run the LSP files and performs the process in this way. Considering that I have hundreds of DWG files, opening and closing all files one by one seems unreasonable.

For this reason, what I really want to do is to solve the whole problem with a single LISP file. In order to do this I probably need to use the VL-Activex libraries.

So instead of selecting the texts in the project with the "ssget" command, I need to select these texts with some functions from the activex library and change them using functions from the activex library. In this way, I can interfere with the drawings without opening any files.

But like I said, I'm not sure about that and that's why I'm here. Actually, I think the solution I'm looking for is a slightly revised version of the BFind command.
Message 8 of 13

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.

Message 9 of 13

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:

bahayalniz_0-1686026938534.png

 

Message 10 of 13

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.

 

Message 11 of 13

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.

Message 12 of 13

Re look at Accoreconsole.

Message 13 of 13

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.

Post to forums  

Forma Design Contest


Autodesk Design & Make Report