pietrow Posted June 21, 2022 Posted June 21, 2022 Hi, I have a lot of text and mtexts in my dwg files. I need them to be changed in some way but a command "find and replace" seems to take so many time. So Im looking for a two lisp - first will be extracting text or mtext with base point, then i want change this text in eg. excel and second lisp should replace text and mtext in dwg with this new values. Hardest thing for me is to find out how to replace existing text and mtext with new values from txt file. Quote
Steven P Posted June 21, 2022 Posted June 21, 2022 Sounds like you just need a bit of a hint and that will get you going? Find and replace text is menu driven in AutoCAD.... and so tricky to automate with a LISP, You could try this which works through the command line, and also with a LISP passing find and replace text strings to it. https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/find-and-replace-text/td-p/5649883 I have used it with a couple of lists like this to replace many text strings at once: new_list is a list or text to add old_list is a list of text to replace. Noting of course that the nth items should correspond (setq lst_length (min (length new_lst) (length old_lst)) acount 0 );end_setq (while (< acount lst_length) (setq changes (+ (FindReplaceAll (nth acount old_lst) (nth acount new_lst)) changes)) (setq acount (+ 1 acount)) ); end while 1 Quote
tombu Posted June 21, 2022 Posted June 21, 2022 Take a look at Lee Mac's Batch Find & Replace Text lisp as a possible solution. I'm sure there's a lisp solution but attaching or adding a link to small before & after drawings so we'd know what you're trying to do. There's lots of lisp for adding prefixes and suffixes but right now we have no idea what you're looking for. 1 Quote
Steven P Posted June 21, 2022 Posted June 21, 2022 2 minutes ago, tombu said: Take a look at Lee Mac's Batch Find & Replace Text lisp as a possible solution. I'm sure there's a lisp solution but attaching or adding a link to small before & after drawings so we'd know what you're trying to do. There's lots of lisp for adding prefixes and suffixes but right now we have no idea what you're looking for. Which is a great LISP though I am not sure if it would save much here if you are changing a single drawing, still got to copy and paste the first text and its replacement from the text file / spreadsheet. Great though for changing a batch of drawings 1 Quote
BIGAL Posted June 22, 2022 Posted June 22, 2022 (edited) Like the others you really only need a csv file do you need Excel ? oldtext,newtext oldtext,newtext Get all the *text and just go through the list made from reading the csv, if match then change. The copy and paste part could be instead pick and write a csv file but with "oldtext," only then just open in notepad. Note "," 2nd lisp auto reads csv file. Edited June 22, 2022 by BIGAL 1 Quote
pietrow Posted June 23, 2022 Author Posted June 23, 2022 Thank you all for your help. Batch Find & Replace is great but not in my case. Let assume simple example: I have 3 text with coordinates like below: X Y TEXT 0 0 1-1-1 10 10 1-1-1 30 50 1-1-1 I want to export this values to csv or txt file, then change in specific way - not simple find & replace. So the new values will be like below 0 0 1-1-1A 10 10 1-1-1B 30 50 1-1-1C every text/mtext should be considered individually so lisp should work in such a way that at a given point (in that case 30,50) it starts search for "text / mtext" if it finds it puts the value assigned to that point (1-1-1C). I think its clear now. Quote
BIGAL Posted June 23, 2022 Posted June 23, 2022 That is what I said already 1st pass text file made from user picks. X,Y,TEXT 0,0,1-1-1,1-1-1 10,10,1-1-1,1-1-1 30,50,1-1-1,1-1-1 edited file X,Y,TEXT 0,0,1-1-1,1-1-1A 10,10,1-1-1,1-1-B 30,50,1-1-1,1-1-B Read file and update If you want to change X&Y then please say so now. 1 Quote
pietrow Posted June 23, 2022 Author Posted June 23, 2022 No, coordinates are the same, but I need help how transform it to code. - get point from file - start searching text/mtext in this point - replace searched text/mtext with value from file Quote
BIGAL Posted June 23, 2022 Posted June 23, 2022 Try this just change the file directory & name ; custom export mod and import text ; By AlanH Jun 2022 (defun c:ah:extxt ( / ) (setq ss (ssget '((0 . "*TEXT")))) (if (= ss nil) (alert "Something went wrong no text selected ") (progn (setq fo (open "D:\\acadtemp\\extxt.csv" "W")) (repeat (setq x (sslength ss)) (setq ent (entget (ssname ss (setq x (1- x))))) (setq txt (cdr (assoc 1 ent))) (setq hand (cdr (assoc 5 ent))) (write-line (strcat hand "," txt "," txt) fo) ) ) ) (close fo) (princ) ) (defun c:ah:intxt ( / ) ; thanks to Lee-mac for this defun ; www.lee-mac.com ; 44 is comma 32 is space . is 46 (defun _csv->lst ( strtxt / pos ) (if (setq pos (vl-string-position 44 strtxt)) (cons (substr strtxt 1 pos) (_csv->lst (substr strtxt (+ pos 2)))) (list strtxt) ) ) (setq fo (open "D:\\acadtemp\\extxt.csv" "R")) (while (setq nline (read-line fo)) (setq lst (_csv->lst nline)) (setq ent (entget (handent (nth 0 lst)))) (entmod (subst (cons 1 (nth 2 lst)) (assoc 1 ent) ent)) ) (close fo) (princ) ) 1 Quote
pietrow Posted June 23, 2022 Author Posted June 23, 2022 (edited) Man, this code is so simple and works great. Thank you very much Edited June 23, 2022 by pietrow Quote
pietrow Posted June 23, 2022 Author Posted June 23, 2022 2 hours ago, BIGAL said: Try this just change the file directory & name ; custom export mod and import text ; By AlanH Jun 2022 (defun c:ah:extxt ( / ) (setq ss (ssget '((0 . "*TEXT")))) (if (= ss nil) (alert "Something went wrong no text selected ") (progn (setq fo (open "D:\\acadtemp\\extxt.csv" "W")) (repeat (setq x (sslength ss)) (setq ent (entget (ssname ss (setq x (1- x))))) (setq txt (cdr (assoc 1 ent))) (setq hand (cdr (assoc 5 ent))) (write-line (strcat hand "," txt "," txt) fo) ) ) ) (close fo) (princ) ) (defun c:ah:intxt ( / ) ; thanks to Lee-mac for this defun ; www.lee-mac.com ; 44 is comma 32 is space . is 46 (defun _csv->lst ( strtxt / pos ) (if (setq pos (vl-string-position 44 strtxt)) (cons (substr strtxt 1 pos) (_csv->lst (substr strtxt (+ pos 2)))) (list strtxt) ) ) (setq fo (open "D:\\acadtemp\\extxt.csv" "R")) (while (setq nline (read-line fo)) (setq lst (_csv->lst nline)) (setq ent (entget (handent (nth 0 lst)))) (entmod (subst (cons 1 (nth 2 lst)) (assoc 1 ent) ent)) ) (close fo) (princ) ) One more question. Can I do it with txt instead of csv or at least use tab instead of ",". Is it possible with this lisp? Quote
pietrow Posted June 23, 2022 Author Posted June 23, 2022 (edited) 18 minutes ago, pietrow said: One more question. Can I do it with txt instead of csv or at least use tab instead of ",". Is it possible with this lisp? I figured it out, just change 44 to 9, and csv to txt Edited June 23, 2022 by pietrow Quote
BIGAL Posted June 23, 2022 Posted June 23, 2022 Good to hear another often used is ";" used in excel rather than "," yes as txt should auto open now. For future, to work out number type this on command line (ascii (getstring)) enter say "A" = 65 (defun c:ah:extxt ( / ) (setq ss (ssget '((0 . "*TEXT")))) (if (= ss nil) (alert "Something went wrong no text selected ") (progn (setq fo (open "D:\\acadtemp\\extxt.txt" "W")) (repeat (setq x (sslength ss)) (setq ent (entget (ssname ss (setq x (1- x))))) (setq txt (cdr (assoc 1 ent))) (setq hand (cdr (assoc 5 ent))) (write-line (strcat hand (chr 9) txt (chr 9) txt) fo) ) ) ) (close fo) (startapp "notepad.exe" "d:\\acadtemp\\extxt.txt") (princ) ) 1 Quote
pietrow Posted June 24, 2022 Author Posted June 24, 2022 Thank BIGAL for advice. Can you explain me what is this line for? (list strtxt) Quote
BIGAL Posted June 25, 2022 Posted June 25, 2022 (edited) The code was by lee-mac he may answer I think its a dummy line bit like doing a (princ) in a if so if true do (princ) else do something else. Edited June 25, 2022 by BIGAL Quote
exceed Posted June 25, 2022 Posted June 25, 2022 (edited) On 6/24/2022 at 4:48 PM, pietrow said: Thank BIGAL for advice. Can you explain me what is this line for? (list strtxt) On 6/25/2022 at 2:51 PM, BIGAL said: The code was by lee-mac he may answer I think its a dummy line bit like doing a (princ) in a if so if true do (princ) else do something else. Since it is a recursive function, if a specific character (ascii number 44) is found as vl-string-position in the if, option 1 = (cons (substr strtxt 1 pos) (_csv->lst (substr strtxt (+ pos 2)))) is executed. otherwise, option 2 = (list strtxt) is executed, the result value of strtxt is put in the list and finished. For example, if the delimiter of that function is a comma, and you put a csv of "1,2,3,4,5" in that function, "1" is stored in the list as cons, and throw out "," then "2,3,4,5" is put back into that function. (this is the if option 1) (substr strtxt 1 pos) means get text string 'strtxt' from 1 to pos position (=where comma is) = so this is "1" then, (substr strtxt (+ pos 2)) = this is "2,3,4,5" because comma is also 1 character, so +2 is for throw out comma, and there is no second argument, it means from (+ pos 2) to end of this string. so, first loop's result is (cons 1 (_csv->lst "2,3,4,5")) next step, we have (_csv->lst "2,3,4,5") so, we pull out "2" to list and throw out "," and put "3,4,5" back into that function. for "3,4," is same case with "1,2," and the last loop we get (_csv->lst "5") but "5" does not have a comma so we do if options 2 = (list strtxt) this will make (list 5) = (5) as an expression is (_csv->lst "1,2,3,4,5") = (cons 1 (cons 2 (cons 3 (cons 4 (list 5)))))) it makes list = (1 2 3 4 5) it's complete. what if (list strtxt) hadn't been result It would be like (cons 1 (cons 2 (cons 3 (cons 4 (cons 5)))))) (cons 5) does not work because there are not enough arguments. cons need a list as second argument, for put in there. like (cons 5 somelist) so (list strtxt) is like a button on the end of this clothes. Edited June 26, 2022 by exceed Quote
Recommended Posts
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.