OMEGA-ThundeR Posted January 22, 2019 Posted January 22, 2019 Hi, I could find some find and replace-ish lisp routines, but not something i am looking for. I type a lot of objectdescription, and for 8/10 drawings the description is mostly the same, but the way it is presented is usually different. I could copy/past from some textfile or previous text withing the drawing, but i think that can be done faster. I'm looking for a function that would replace a selected text (mtext or regular text) with something predefined in a lisp. Lets say: (defun c:replace1 (/ text selecttext) (setq text "this is a description text") (setq selecttext (ssget "_:L" '((0 . "MTEXT,TEXT")))) *Part of the code that changes out the predifined text with the selected text/mtext* Shouldn't be so hard right? Quote
Tharwat Posted January 22, 2019 Posted January 22, 2019 2 hours ago, OMEGA-ThundeR said: Hi, Shouldn't be so hard right? No its not. (defun c:replace1 (/ text sel int) (setq text "this is a description text") (if (setq sel (ssget "_:L" '((0 . "MTEXT,TEXT")))) (repeat (setq int (sslength sel)) (entmod (append (entget (ssname sel (setq int (1- int)))) (list (cons 1 text)) ) ) ) ) (princ) ) 1 Quote
OMEGA-ThundeR Posted January 22, 2019 Author Posted January 22, 2019 Works like a charm! Thanks! Quote
ronjonp Posted January 22, 2019 Posted January 22, 2019 @Tharwat FWIW, I'd use vla-put-textstring. Large mtext strings are broken up into multiple 3 codes so entmodding 1 is unreliable. Quote _$ ((-1 . <Entity name: 21985c54a50>) (0 . "MTEXT") (330 . <Entity name: 2199b10f2d0>) (5 . "102509D") (100 . "AcDbEntity") (67 . 1) (410 . "004") (8 . "0") (100 . "AcDbMText") (10 434.871 344.729 0.0) (40 . 2.5) (41 . 80.01) (46 . 0.0) (71 . 1) (72 . 1) (3 . "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown f" ) (3 . "ox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over t" ) (3 . "he lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\P" ) (3 . "The quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown" ) (1 . " fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. " ) (7 . "Standard") (210 0.0 0.0 1.0) (11 1.0 0.0 0.0) (42 . 77.8) (43 . 99.0833) (50 . 0.0) (73 . 1) (44 . 1.0) ) _$ 2 Quote
Tharwat Posted January 22, 2019 Posted January 22, 2019 1 hour ago, OMEGA-ThundeR said: Works like a charm! Thanks! You're welcome. @ronjonp Yeah, you are right and I am honestly aware of that but the OP asks for something very simple faraway enough from the DXF group 3. Brave fox by the way. 1 Quote
OMEGA-ThundeR Posted January 22, 2019 Author Posted January 22, 2019 15 minutes ago, Tharwat said: You're welcome. Minor setback, it changes it normal TEXT objects, but it ads the text with mtext objects. The original content isn't removed from mtext. Is that what that 'DXF group 3' is about? My mtext lines are not long, and even single words mtext objects don't get replaced. Quote
Tharwat Posted January 22, 2019 Posted January 22, 2019 6 minutes ago, OMEGA-ThundeR said: Minor setback, it changes it normal TEXT objects, but it ads the text with mtext objects. The original content isn't removed from mtext. Is that what that 'DXF group 3' is about? My mtext lines are not long, and even single words mtext objects don't get replaced. You can try instead. (defun c:replace1 (/ text sel int) (setq text "this is a description text") (if (setq sel (ssget "_:L" '((0 . "MTEXT,TEXT")))) (repeat (setq int (sslength sel)) (setq e (entget (ssname sel (setq int (1- int))))) (entmod (subst (cons 1 text) (assoc 1 e) e)) ) ) (princ) ) DXF Group Code 3 is about Text string that exceed more than 250 chars if I am not mistaken so read THIS for more info. 1 Quote
barristann Posted April 16, 2023 Posted April 16, 2023 (edited) Hi Tharwat, great lisp! I use this everyday! Is it possible to modify this to replace only the LAST 4 chars? Or, is it possible to have the option to change only the FIRST 3 chars? Thank you. Edited April 16, 2023 by barristann Quote
Tharwat Posted April 16, 2023 Posted April 16, 2023 Give an example of what you are after to allow me to modify the routine. Quote
barristann Posted April 16, 2023 Posted April 16, 2023 (edited) If I have a TEXT or MTEXT: ABC-1234 a. I would like to replace the LAST 4 chars with for example 6789 ABC-6789 b. or I would like to replace the FIRST 3 chars with for example XYZ XYZ-1234 Edited April 16, 2023 by barristann Quote
Tharwat Posted April 16, 2023 Posted April 16, 2023 This is to replace the end chars of selected texts. NOTE: Be sure to have your selected Mtexts objects unformatted. (defun c:Test ( / str len int sel ent get txt lng ) ;;----------------------------------------------------;; ;; Author : Tharwat Al Choufi ;; ;; website: https://autolispprograms.wordpress.com ;; ;;----------------------------------------------------;; (setq str "6789" len (strlen str) ) (and (princ (strcat "\nSelect text to replace the end chars with < " str " > : ")) (setq int -1 sel (ssget "_:L" '((0 . "TEXT,MTEXT")))) (while (setq int (1+ int) ent (ssname sel int)) (setq get (entget ent) txt (assoc 1 get) ) (and (<= len (setq lng (strlen (cdr txt)))) (entmod (subst (cons 1 (strcat (substr (cdr txt) 1 (- lng len)) str)) txt get)) ) ) ) (princ) ) 1 Quote
Tharwat Posted April 16, 2023 Posted April 16, 2023 Here is another routine for the second one although the mods are a little, so hopefully you can learn something from these posted two routines. (defun c:Test ( / str len int sel ent get txt lng ) ;;----------------------------------------------------;; ;; Author : Tharwat Al Choufi ;; ;; website: https://autolispprograms.wordpress.com ;; ;;----------------------------------------------------;; (setq str "XYZ" len (strlen str) ) (and (princ (strcat "\nSelect text to replace the end chars with < " str " > : ")) (setq int -1 sel (ssget "_:L" '((0 . "TEXT,MTEXT")))) (while (setq int (1+ int) ent (ssname sel int)) (setq get (entget ent) txt (assoc 1 get) ) (and (<= len (setq lng (strlen (cdr txt)))) (entmod (subst (cons 1 (strcat str (substr (cdr txt) 1 len))) txt get)) ) ) ) (princ) ) 1 Quote
barristann Posted April 17, 2023 Posted April 17, 2023 (edited) Great Tharwat. They both work! I'm very curious, it is possible to use the "-" character to indicate where to stop replacing? If I have many TEXT or MTEXT: AB-12 ABC-123 ABCDE-123456 a. I would like to replace All the chars on the RIGHT of "-" with 678 AB-678 ABC-678 ABCDE-678 b. or I would like to replace All the Chars on the Left of "-" with XYZ XYZ-12 XYZ-123 XYZ-123456 Thank you Tharwat Edited April 17, 2023 by barristann Quote
barristann Posted April 17, 2023 Posted April 17, 2023 (edited) I'm curious because of a similar thread Thank you Tharwat Edited April 17, 2023 by barristann Quote
Tharwat Posted April 17, 2023 Posted April 17, 2023 I did volunteer my time and efforts more than enough freely for you, so if you want me to help you more but with fees then let me know. Quote
Steven P Posted April 17, 2023 Posted April 17, 2023 (edited) So you could look into this page here: https://help.autodesk.com/view/OARX/2023/ENU/?guid=GUID-8543549B-F0D7-43CD-87A3-F6B827FF0B88 which gives the string functions. Perhaps use: (strlen [string ...]) to find the length of the text string (vl-string-search pattern string [ start-pos]) to find the position of the first '-' and from calculate the variable 'len' in the code above and go from there. As an alternative I use Lee Macs String to List (http://lee-mac.com/stringtolist.html#:~:text=%3B%3B String to List - Lee Mac %3B%3B,str (%2B pos len)))) (reverse (cons str lst)))) to split the text strings into parts, then remake the string using the parts and changing them as required. I quite like this way since you can change any part of the text between any deliminators - even multiple changes easily. Something like this: Should be quite versatile to do all the above, variable lengths, suffix and prefix, (defun c:Testthis ( / Prefix Suffix presuf ss acount MyNewString MyEnt MyString MyList MyCount MyNewString) (setq Prefix "Prefix TExt") ; change these texts as required or ;;(setq Prefix (getstring T "\nEnter Prefix Text:")) (setq Suffix "Suffix Text") ;;(setq Suffix (getstring T "\nEnter Suffix Text:")) ;;Sub Functions (defun LM:str->lst ( str del / pos ) (if (setq pos (vl-string-search del str)) (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del)) (list str) ) ) (initget "pre suf both") (setq presuf (strcase (getkword "\nEnter an option (Pre/Suf/both): ") )) ; Select change to make (setq ss (ssget '((0 . "*TEXT"))) ) ; Select text, mtext, rtext (setq acount 0) (while (< acount (sslength ss)) ; loop through selection (setq MyNewString "") ; empty text string (setq MyEnt (entget (ssname ss acount)) ) (setq MyString (cdr (assoc 1 MyEnt))) ; Gets text strinbg (up to 1st ~500 characters) (setq MyList (LM:str->lst MyString "-")) ; text to list ;;Modify list items, could use cond here (if (= presuf "PRE") (setq MyList (subst Prefix (nth 0 MyList) MyList ) ) ) (if (= presuf "SUF") (setq MyList (subst Suffix (nth 0 (reverse MyList)) MyList ) ) ) (if (= presuf "BOTH") (progn (setq MyList (subst Prefix (nth 0 MyList) MyList ) ) ; Change Prefix text as you want (setq MyList (subst Suffix (nth 0 (reverse MyList)) MyList ) ) ; change Suffix text as you want ) ) ;;Remake text from list (setq MyNewString (nth 0 MyList)) (setq MyCount 1) (while (< MyCount (length MyList)) (setq MyNewString (strcat MyNewString "-" (nth MyCount MyList))) (setq MyCount (+ MyCount 1)) ) ; end while (entmod (subst (cons 1 MyNewString) (assoc 1 MyEnt) MyEnt )) ; update text (setq acount (+ acount 1)) ) ; end while (princ) ) Edited April 19, 2023 by Steven P EDIT: Added 'getstring' for the suffix and prefix 1 Quote
Steven P Posted April 17, 2023 Posted April 17, 2023 (sorry Tharwat - 20 minutes copy, paste and check isn't going to pay enough to cover your time to even make an invoice in this case) 1 Quote
barristann Posted April 19, 2023 Posted April 19, 2023 That's 100% incredible, Steven! I used your codes so many times at work today. I was speechless when I first tested them this morning. I'm still amazed something like this can be coded. Thank you Steven P for being so awesome! 1 Quote
Steven P Posted April 19, 2023 Posted April 19, 2023 That's no problem, it was all copy and pasted from other things. I have updated the code slightly so that the prefix and suffix text is at the start (easier to find and change when it is there), but also commented out 2 lines containing 'getstring' - remove the ; and the LISP will ask the for user input for the text to add 1 Quote
barristann Posted April 22, 2023 Posted April 22, 2023 (edited) Wow it was already great, but you've made it even better, Steven. I'll study your codes for sure. Thank you for going above and beyond, Steven! Edited April 22, 2023 by barristann 1 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.