TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: SPDCad on March 30, 2005, 12:35:34 PM

Title: Command line Find
Post by: SPDCad on March 30, 2005, 12:35:34 PM
Does the 'Find' command have a command line prompt or is it dialog box controlled only?
I am writting a lisp and I would like to use find and replace in the lisp, but I can't call it up without bringing up the dialog box.
If it is not possible to control the find and replace command at the command prompt, does any one have code that will find and replace a string item in mtext, text and attribute format?  I know I have a few long retired programme that do, but I am at work and I don't have access to the code.
:O(

Any help would be greatly appreciated.

Damn! I need to carry my all my lisp programmes (rerired or not) around with me on a DVD!  :?
Title: Command line Find
Post by: CADaver on March 30, 2005, 12:49:50 PM
Older than dirt, but still works on TEXT MTEXT and DIMS

Code: [Select]
;;; a rudimentary text editor Frank Emerick, RBCulp
(defun c:cx () (c:chgtext))
(defun C:CHGTEXT () (cht_Edit nil))
(defun cht_Edit (objs / last_o tot_o ent o_str n_str st s_temp
                       n_slen o_slen si chf chm cont ans class)
(command "undo" "BEGIN")
  (if (null objs)
    (setq objs (ssget))
  )
  (setq chm 0)
  (if objs
    (progn                   ;; If any objects selected
      (if (= (type objs) 'ENAME)
        (progn
          (setq ent (entget objs))
          (princ (strcat "\nExisting string: " (cdr (assoc 1 ent))))
        )
        (if (= (sslength objs) 1)
          (progn
            (setq ent (entget (ssname objs 0)))
            (princ (strcat "\nExisting string: " (cdr (assoc 1 ent))))
          )
        )
      )
      (setq o_str (getstring "\nMatch string   : " t))
      (setq o_slen (strlen o_str))
      (if (/= o_slen 0)
        (progn
          (setq n_str (getstring "\nNew string     : " t))
          (setq n_slen (strlen n_str))
          (setq last_o 0
                tot_o  (if (= (type objs) 'ENAME)
                         1
                         (sslength objs)
                       )
          )
          ;; For each selected object...
          (while (< last_o tot_o)
            (setq class (cdr (assoc 0 (setq ent (entget (ssname objs last_o))))))
            (if (cond (= "TEXT" class)
                      (= "mtext" class)
                      (= "DIMENSION" class) )
              (progn
                (setq chf nil si 1)
                (setq s_temp (cdr (assoc 1 ent)))
                (while (= o_slen (strlen (setq st (substr s_temp si o_slen))))
                  (if (= st o_str)
                    (progn
                      (setq s_temp (strcat
                                     (if (> si 1)
                                       (substr s_temp 1 (1- si))
                                       ""
                                     )
                                     n_str
                                     (substr s_temp (+ si o_slen))
                                   )
                      )
                      (setq chf t)    ;; Found old string
                      (setq si (+ si n_slen))
                    )
                    (setq si (1+ si))
                  )
                )
                (if chf
                  (progn              ;; Substitute new string for old
                    ;; Modify the TEXT entity
                    (entmod (subst (cons 1 s_temp) (assoc 1 ent) ent))
                    (setq chm (1+ chm))
                  )
                )
              )
            )
            (setq last_o (1+ last_o))
          )
        )
        ;; else go on to the next line...
      )
    )
  )
  (if (/= (type objs) 'ENAME)
    ;; Print total lines changed
    (if (/= (sslength objs) 1)
      (princ (strcat (rtos chm 2 0) " text lines changed."))
  (terpri)
    )
  )
(command "undo" "END")
  (terpri)
)
Title: Command line Find
Post by: SPDCad on March 31, 2005, 10:12:44 AM
Thanks CADaver! :)
Title: Command line Find
Post by: CADaver on March 31, 2005, 11:11:46 AM
Quote from: SPDCad
Thanks CADaver! :)
You're welcome.  Bear in mind that it was originally written nearly 18 years ago and has been "tweaked" a bit since.  (I think there may be newer/netter versions floating around somewhere.)

I am quite sure the "real" gurus here can come up with something considerably more elegant.
Title: Command line Find
Post by: Sitra on April 04, 2005, 03:25:49 PM
What about something where you can open up a drawing and it will do a find and replace with preset words to look for and replace. Is this possible.
Title: Command line Find
Post by: Mark on April 04, 2005, 03:53:57 PM
Yep, with autolisp or vba it is.

You should be about ready to handle that one now, right? You are in Stig's class aren't you?
:)
Title: Command line Find
Post by: Sitra on April 04, 2005, 03:58:19 PM
Quote from: Mark Thomas

You should be about ready to handle that one now, right?


Unfortunately no...:cry:

Quote from: Mark Thomas
You are in Stig's class aren't you?


Yes, sir. But, I am so far behind it is not even funny...
 :roll:
Title: Command line Find
Post by: Jeff_M on April 04, 2005, 07:04:37 PM
Hi Conrad,
Here's a function I put together a while back that you could easily use in a new lisp to do what you want.
Code: [Select]

;| Routine to find specified text and replace with new text. Works on Text,
   Mtext, Attributes and Dimension text overrides.
   WARNING: it will change all occurances of a pattern with the new text.
   Such as: if "test" "contest" "testing" are all valid text entries in the
   drawing, running this: (txtfind "test" "newtest") will change
   the original text to "newtest" "connewtest" "newtesting", but for the
   original intent of this routine that was not a problem. Modifications
   may be made to force matching of whole word only.

   by: Jeff Mishler Sept. 2003

   |;


(defun txtfind (patt newpatt / count ss ent str txthgt match?)
  (vl-load-com)
  (vla-startundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
  (setq ss (ssget "X" '((0 . "TEXT,MTEXT,DIMENSION,INSERT"))))
  (if (not ss)
    (princ "\nNo Text entities found!")
    (progn
      (setq count -1)
      (while (< (setq count (1+ count))(sslength ss))
(setq ent (entget (ssname ss count))
     obj (vlax-ename->vla-object (cdr (car ent))))
(cond
 ((= (cdr (assoc 0 ent)) "TEXT")
  (progn
    (setq str (cdr (assoc 1 ent)))
    (while (setq match? (vl-string-search patt str))
      (setq str (vl-string-subst newpatt patt str))
      (vla-put-textstring obj str)
      );while
    );progn
  );first condition
 ((= (cdr (assoc 0 ent)) "DIMENSION")
  (progn
    (setq str (cdr (assoc 1 ent)))
    (while (setq match? (vl-string-search patt str))
      (setq str (vl-string-subst newpatt patt str))
      (vla-put-textoverride obj str)
      );while
    );progn
  );second condition
 ((= (cdr (assoc 0 ent)) "MTEXT")
  (progn
    (setq str (vla-get-textstring obj))
    (while (setq match? (vl-string-search patt str))
      (setq str (vl-string-subst newpatt patt str))
      (vla-put-textstring obj str)
      );while
    );progn
  );third condition
 (t
  (progn
    (if (= (vla-get-hasattributes obj) :vlax-true)
      (progn
(setq atts (vla-getattributes obj))
(foreach x (vlax-safearray->list (vlax-variant-value atts))
  (setq str (vla-get-textstring x))
  (while (setq match? (vl-string-search patt str))
    (setq str (vl-string-subst newpatt patt str))
    (vla-put-textstring x str)
    );while
  );for
);progn
      );if
    );progn
  );last condition
 );cond
);while
      );progn
    );if
  (vla-endundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
  (princ)
  );defun

Make sure this loads first in acaddoc.lsp, then add your lisp after it. Something like this:
Code: [Select]

(txtfind "badtext" "goodtext")
Title: Command line Find
Post by: Sitra on April 05, 2005, 09:24:28 AM
Thanks Jeff, I will give it a try... :D
Title: Re: Command line Find
Post by: M-dub on December 13, 2007, 01:17:30 PM
Here's a function I put together a while back...

Love this one.  Comes in handy, it does!  :-D
Title: Re: Command line Find
Post by: M-dub on April 18, 2008, 08:27:11 AM
8< Snip >8

Any idea as to why I would get this message on some drawings, but not all?

Quote
Command: (txtfind "ABE-4172-AA" "ABE-4172")
; error: ActiveX Server returned an error: Invalid index
Title: Re: Command line Find
Post by: One Shot on April 18, 2008, 09:25:24 AM
Is there a way to us this command to highlight where text was changed?  Like make it change colors when it was changed. 
Title: Re: Command line Find
Post by: ronjonp on April 18, 2008, 10:05:36 AM
You could add (vla-put-color x 1) to this portion of Jeff's code:

Code: [Select]
   (while (setq match? (vl-string-search patt str))
     (setq str (vl-string-subst newpatt patt str))
     (vla-put-textstring x str)
     );while
   );for
Title: Re: Command line Find
Post by: T.Willey on April 18, 2008, 11:02:48 AM
8< Snip >8

Any idea as to why I would get this message on some drawings, but not all?

Quote
Command: (txtfind "ABE-4172-AA" "ABE-4172")
; error: ActiveX Server returned an error: Invalid index
Does it happen in the same drawing always?  If so maybe you can post a small portion of the drawing.  The only reason I can think of (it's early and I'm tried) is that it's trying to replace the items in a spot that is outside the range of letters.
Title: Re: Command line Find
Post by: M-dub on April 18, 2008, 11:22:56 AM
8< Snip >8

Any idea as to why I would get this message on some drawings, but not all?

Quote
Command: (txtfind "ABE-4172-AA" "ABE-4172")
; error: ActiveX Server returned an error: Invalid index
Does it happen in the same drawing always?  If so maybe you can post a small portion of the drawing.  The only reason I can think of (it's early and I'm tried) is that it's trying to replace the items in a spot that is outside the range of letters.
Can't really post the drawing, but I could email it to you...


I just figured out that even if I get the error message, it will sometimes change the text anyway.
It should also be noted that this text is in an attribute.
Title: Re: Command line Find
Post by: T.Willey on April 18, 2008, 11:33:00 AM
8< Snip >8

Any idea as to why I would get this message on some drawings, but not all?

Quote
Command: (txtfind "ABE-4172-AA" "ABE-4172")
; error: ActiveX Server returned an error: Invalid index
Does it happen in the same drawing always?  If so maybe you can post a small portion of the drawing.  The only reason I can think of (it's early and I'm tried) is that it's trying to replace the items in a spot that is outside the range of letters.
Can't really post the drawing, but I could email it to you...


I just figured out that even if I get the error message, it will sometimes change the text anyway.
It should also be noted that this text is in an attribute.

If it is happening in the same drawing, then go ahead and email me the drawing.  My email is in my profile.  I just did a little test here and it worked for plain text and attributes.
Title: Re: Command line Find
Post by: T.Willey on April 18, 2008, 12:05:59 PM
The problem seemed to be that the block had attributes, but it didn't have editable attributes, only constant, so the program was choking on that.  I changed one section (shown in red), and it doesn't error anymore.  Hope you don't mind Jeff.   :-)

Code: [Select]
(defun txtfind (patt newpatt / count ss ent str txthgt match?)
    ;| Routine to find specified text and replace with new text. Works on Text,
    Mtext, Attributes and Dimension text overrides.
    WARNING: it will change all occurances of a pattern with the new text.
    Such as: if "test" "contest" "testing" are all valid text entries in the
    drawing, running this: (txtfind "test" "newtest") will change
    the original text to "newtest" "connewtest" "newtesting", but for the
    original intent of this routine that was not a problem. Modifications
    may be made to force matching of whole word only.
   
    by: Jeff Mishler Sept. 2003
   
    |;
   
    (vl-load-com)
    (vla-startundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
    (setq ss (ssget "X" '((0 . "TEXT,MTEXT,DIMENSION,INSERT"))))
    (if (not ss)
        (princ "\nNo Text entities found!")
        (progn
            (setq count -1)
            (while (< (setq count (1+ count))(sslength ss))
                (setq ent (entget (ssname ss count))
                obj (vlax-ename->vla-object (cdr (car ent))))
                (cond
                    ((= (cdr (assoc 0 ent)) "TEXT")
                        (progn
                            (setq str (cdr (assoc 1 ent)))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textstring obj str)
                            );while
                        );progn
                    );first condition
                    ((= (cdr (assoc 0 ent)) "DIMENSION")
                        (progn
                            (setq str (cdr (assoc 1 ent)))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textoverride obj str)
                            );while
                        );progn
                    );second condition
                    ((= (cdr (assoc 0 ent)) "MTEXT")
                        (progn
                            (setq str (vla-get-textstring obj))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textstring obj str)
                            );while
                        );progn
                    );third condition
                    (t
[color=red]                        (foreach x (vlax-invoke obj 'GetAttributes)
                            (setq str (vla-get-textstring x))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textstring x str)
                            );while
                        );for[/color]
                    );last condition
                );cond
            );while
        );progn
    );if
    (vla-endundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
    (princ)
);defun

Edit:  If you want to change constant attributes, then change this line (in red above)
Code: [Select]
(foreach x (vlax-invoke obj 'GetAttributes)
To
Code: [Select]
(foreach x (append (vlax-invoke obj 'GetAttributes) (vlax-invoke obj 'GetConstantAttributes))
Title: Re: Command line Find
Post by: M-dub on April 18, 2008, 12:10:33 PM
First of all, Thank-you!



Constant?  :?


(Checking... )
Title: Re: Command line Find
Post by: T.Willey on April 18, 2008, 12:15:29 PM
First of all, Thank-you!
You're welcome.

Constant?  :?


(Checking... )
I don't use them, but I know they exist.  It is a mode that is set like invisible.  Here is something from the help, if it helps.
Quote
Mode
Sets options for attribute values associated with a block when you insert the block in a drawing.

The default values are stored in the AFLAGS system variable. Changing the AFLAGS setting affects the default mode for new attribute definitions and does not affect existing attribute definitions.

Invisible

Specifies that attribute values are not displayed or printed when you insert the block. ATTDISP overrides Invisible mode.

Constant

Gives attributes a fixed value for block insertions.

Verify

Prompts you to verify that the attribute value is correct when you insert the block.

Preset

Sets the attribute to its default value when you insert a block containing a preset attribute.
Title: Re: Command line Find
Post by: M-dub on April 18, 2008, 12:45:52 PM
I know what constants are, but I didn't think they were being used in that drawing.  Must have been one of the garbage blocks from the vendor that were on a layer that was turned off... ?
Title: Re: Command line Find
Post by: M-dub on April 18, 2008, 12:46:49 PM
Must have been one of the garbage blocks from the vendor that were on a layer that was turned off... ?

Yep...
Title: Re: Command line Find
Post by: M-dub on October 15, 2012, 02:23:43 PM
So, is the statute of limitations up on this one yet?  ;)

As we've done in the past, we're using Jeff's TXTFIND routine to do some find & replacements in a script for many drawings.  I'm not sure if it has something to do with the text we're trying to find & replace or what, but we keep getting fatal errors.

When we enter (TXTFIND "DO1" "FDO1"), AutoCAD crashes with a fatal error and says something like "FATAL ERROR.:  Cannot write to undo file (probably disk full)".  It seems to have something to do with DO or DI.  I even tried "D" and it crashed.  Every other word that I tested worked, though.

I kept a copy of Jeff's original and I THOUGHT that I had tried it successfully but just tried it again and it crashed.  Does anyone know what could be going on here?

T.Willey Modified Version
Code: [Select]
(defun txtfind (patt newpatt / count ss ent str txthgt match?)
    ;| Routine to find specified text and replace with new text. Works on Text,
    Mtext, Attributes and Dimension text overrides.
    WARNING: it will change all occurances of a pattern with the new text.
    Such as: if "test" "contest" "testing" are all valid text entries in the
    drawing, running this: (txtfind "test" "newtest") will change
    the original text to "newtest" "connewtest" "newtesting", but for the
    original intent of this routine that was not a problem. Modifications
    may be made to force matching of whole word only.
   
    by: Jeff Mishler Sept. 2003
   
    |;
   
    (vl-load-com)
    (vla-startundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
    (setq ss (ssget "X" '((0 . "TEXT,MTEXT,DIMENSION,INSERT"))))
    (if (not ss)
        (princ "\nNo Text entities found!")
        (progn
            (setq count -1)
            (while (< (setq count (1+ count))(sslength ss))
                (setq ent (entget (ssname ss count))
                obj (vlax-ename->vla-object (cdr (car ent))))
                (cond
                    ((= (cdr (assoc 0 ent)) "TEXT")
                        (progn
                            (setq str (cdr (assoc 1 ent)))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textstring obj str)
                            );while
                        );progn
                    );first condition
                    ((= (cdr (assoc 0 ent)) "DIMENSION")
                        (progn
                            (setq str (cdr (assoc 1 ent)))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textoverride obj str)
                            );while
                        );progn
                    );second condition
                    ((= (cdr (assoc 0 ent)) "MTEXT")
                        (progn
                            (setq str (vla-get-textstring obj))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textstring obj str)
                            );while
                        );progn
                    );third condition
                    (t
                        (foreach x (vlax-invoke obj 'GetAttributes)
                            (setq str (vla-get-textstring x))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textstring x str)
                            );while
                        );for
                    );last condition
                );cond
            );while
        );progn
    );if
    (vla-endundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
    (princ)
);defun

Original Jeff M Version
Code: [Select]
;| Routine to find specified text and replace with new text. Works on Text,
   Mtext, Attributes and Dimension text overrides.
   WARNING: it will change all occurances of a pattern with the new text.
   Such as: if "test" "contest" "testing" are all valid text entries in the
   drawing, running this: (txtfind "test" "newtest") will change
   the original text to "newtest" "connewtest" "newtesting", but for the
   original intent of this routine that was not a problem. Modifications
   may be made to force matching of whole word only.

   by: Jeff Mishler Sept. 2003

   |;


(defun txtfind (patt newpatt / count ss ent str txthgt match?)
  (vl-load-com)
  (vla-startundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
  (setq ss (ssget "X" '((0 . "TEXT,MTEXT,DIMENSION,INSERT"))))
  (if (not ss)
    (princ "\nNo Text entities found!")
    (progn
      (setq count -1)
      (while (< (setq count (1+ count))(sslength ss))
(setq ent (entget (ssname ss count))
      obj (vlax-ename->vla-object (cdr (car ent))))
(cond
  ((= (cdr (assoc 0 ent)) "TEXT")
   (progn
     (setq str (cdr (assoc 1 ent)))
     (while (setq match? (vl-string-search patt str))
       (setq str (vl-string-subst newpatt patt str))
       (vla-put-textstring obj str)
       );while
     );progn
   );first condition
  ((= (cdr (assoc 0 ent)) "DIMENSION")
   (progn
     (setq str (cdr (assoc 1 ent)))
     (while (setq match? (vl-string-search patt str))
       (setq str (vl-string-subst newpatt patt str))
       (vla-put-textoverride obj str)
       );while
     );progn
   );second condition
  ((= (cdr (assoc 0 ent)) "MTEXT")
   (progn
     (setq str (vla-get-textstring obj))
     (while (setq match? (vl-string-search patt str))
       (setq str (vl-string-subst newpatt patt str))
       (vla-put-textstring obj str)
       );while
     );progn
   );third condition
  (t
   (progn
     (if (= (vla-get-hasattributes obj) :vlax-true)
       (progn
(setq atts (vla-getattributes obj))
(foreach x (vlax-safearray->list (vlax-variant-value atts))
   (setq str (vla-get-textstring x))
   (while (setq match? (vl-string-search patt str))
     (setq str (vl-string-subst newpatt patt str))
     (vla-put-textstring x str)
     );while
   );for
);progn
       );if
     );progn
   );last condition
  );cond
);while
      );progn
    );if
  (vla-endundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
  (princ)
  );defun
Title: Re: Command line Find
Post by: ronjonp on October 15, 2012, 03:05:33 PM
If you're running it in a script, you could probably just take out the vla-startundomark and vla-endundomark.

You read this about the temp folder?
http://forums.autodesk.com/t5/AutoCAD-2012/Autocad-crash-FATAL-ERROR-cannot-write-to-UNDO-file-disk/td-p/3320167
Title: Re: Command line Find
Post by: M-dub on October 15, 2012, 03:21:46 PM
Thanks Ron,

Gave that a try and no workie.

Like I said, most of the strings have no issue, but the strings that start with DO and DI throw it for a harf.  It's like AutoCAD thinks we're trying to divide by zero or something.

These guys have other things they have to do in each drawing, so they'll have to just change these strings manually or with the AutoCAD Find & Replace... I just wish they'd come out with a command line version already!

Thanks again!
Mike
Title: Re: Command line Find
Post by: ronjonp on October 15, 2012, 03:31:02 PM
Maybe try changing the autocad temp directory to another location and see if the problem persists?
Title: Re: Command line Find
Post by: M-dub on October 15, 2012, 03:39:40 PM
Hmmm...
Nope.  I changed the order of the string changes in the script to keep all of the DI's and DO's at the bottom and it goes through and changes all of the other ones just fine.  If it doesn't have something to do with DO or DI, this is one crazy coincidence.

Edit: Forgot to add AO and AI.  Those ones harf it, too.
Title: Re: Command line Find
Post by: ronjonp on October 15, 2012, 03:44:54 PM
That is weird  :?. Can you post a sample drawing that this crashes on?
Title: Re: Command line Find
Post by: M-dub on October 15, 2012, 03:47:14 PM
I could, but it doesn't even matter if I start a brand new drawing and just throw a few random strings of text on it.  It doesn't like DO, DI, AO, or AI... at least.  It doesn't matter WHICH drawing it is.
Title: Re: Command line Find
Post by: T.Willey on October 15, 2012, 06:27:34 PM
The issue is the way the code is done, and your example leaves in an infinite loop.  Here is an example:
start D01
replace FD01
(then it will search the whole string again)
start FD01
replace FFD01
(as you can see it will always find the string D01 to replace, and so on and on)

Will see what I can do.
Title: Re: Command line Find
Post by: T.Willey on October 15, 2012, 06:35:11 PM
Here is a quick fix that seems to work on the issue with dtext.  Added the same fix to all items that the program works on.

Code: [Select]
(defun txtfind (patt newpatt / count ss ent str txthgt match? cnt slen)
    ;| Routine to find specified text and replace with new text. Works on Text,
    Mtext, Attributes and Dimension text overrides.
    WARNING: it will change all occurances of a pattern with the new text.
    Such as: if "test" "contest" "testing" are all valid text entries in the
    drawing, running this: (txtfind "test" "newtest") will change
    the original text to "newtest" "connewtest" "newtesting", but for the
    original intent of this routine that was not a problem. Modifications
    may be made to force matching of whole word only.
   
    by: Jeff Mishler Sept. 2003
   
    |;
   
    (vl-load-com)
    (vla-startundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
    (setq slen (strlen newpatt))
    (setq ss (ssget "X" '((0 . "TEXT,MTEXT,DIMENSION,INSERT"))))
    (if (not ss)
        (princ "\nNo Text entities found!")
        (progn
            (setq count -1)
            (while (< (setq count (1+ count))(sslength ss))
                (setq ent (entget (ssname ss count))
                obj (vlax-ename->vla-object (cdr (car ent))))
                (cond
                    ((= (cdr (assoc 0 ent)) "TEXT")
                        (progn
                            (setq cnt 0)
                            (setq str (cdr (assoc 1 ent)))
                            (while (setq match? (vl-string-search patt str cnt))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textstring obj str)
                                (setq cnt (+ slen match?))
                            );while
                        );progn
                    );first condition
                    ((= (cdr (assoc 0 ent)) "DIMENSION")
                        (progn
                            (setq cnt 0)
                            (setq str (cdr (assoc 1 ent)))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textoverride obj str)
                                (setq cnt (+ slen match?))
                            );while
                        );progn
                    );second condition
                    ((= (cdr (assoc 0 ent)) "MTEXT")
                        (progn
                            (setq cnt 0)
                            (setq str (vla-get-textstring obj))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textstring obj str)
                                (setq cnt (+ slen match?))
                            );while
                        );progn
                    );third condition
                    (t
                        (foreach x (vlax-invoke obj 'GetAttributes)
                            (setq cnt 0)
                            (setq str (vla-get-textstring x))
                            (while (setq match? (vl-string-search patt str))
                                (setq str (vl-string-subst newpatt patt str))
                                (vla-put-textstring x str)
                                (setq cnt (+ slen match?))
                            );while
                        );for
                    );last condition
                );cond
            );while
        );progn
    );if
    (vla-endundomark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
    (princ)
)
Title: Re: Command line Find
Post by: Lee Mac on October 15, 2012, 07:24:09 PM
Would this help at all Mike?

http://lee-mac.com/bfind.html (http://lee-mac.com/bfind.html)
Title: Re: Command line Find
Post by: M-dub on October 17, 2012, 12:28:21 PM
Big thanks to Tim and Ron for helping me out with this.

Ron got me squared away with this update and all is well again.  :)

So, what we used to do with this lisp was to write a script that just ran this routine over and over again for each string we wanted to change.  With Ron's update, we just throw what used to be in the script down at the bottom of the code and run the lisp.

Again, many thanks to you both!  :)

Code: [Select]
(defun txtfind (patt newpatt / _replacetext e el n obj ss str)
        ;| Routine to find specified text and replace with new text. Works on Text,
    Mtext, Attributes and Dimension text overrides.
    WARNING: it will change all occurances of a pattern with the new text.
    Such as: if "test" "contest" "testing" are all valid text entries in the
    drawing, running this: (txtfind "test" "newtest") will change
    the original text to "newtest" "connewtest" "newtesting", but for the
    original intent of this routine that was not a problem. Modifications
    may be made to force matching of whole word only.
   
    by: Jeff Mishler Sept. 2003
    10.16.2012 Modified by RJP to prevent infinite loop when source search includes all or part of replace pattern
    Created more refined filter
    ie.
    (txtfind "AI1" "FAI1")
    (txtfind "AI2" "FAI2")
    |;
  (defun _replacetext (new old textstring / i out tmp)
    (cond ((vl-string-search old textstring)
    (setq tmp textstring)
    (setq out "")
    (while (setq i (vl-string-search old tmp))
      (setq out (strcat out (vl-string-subst new old (substr tmp 1 (+ i (strlen old))))))
      (setq tmp (substr tmp (1+ (+ i (strlen old)))))
    )
    (if (zerop (strlen tmp))
      out
      (strcat out tmp)
    )
   )
   (textstring)
    )
  )
  (vl-load-com)
  ;; More refined filter
  (if (setq ss (ssget "_X"
       (list '(-4 . "<OR")
     '(-4 . "<AND")
     ;; *text that only has part of the search string
     '
      (0 . "MTEXT,TEXT")
     (cons 1 (strcat "*" patt "*"))
     '(-4 . "AND>")
     '(-4 . "<AND")
     ;; Attributed blocks
     '
      (0 . "INSERT")
     '(66 . 1)
     '(-4 . "AND>")
     ;; Dimension DUH :)
     '
      (-4 . "<AND")
     '(0 . "DIMENSION")
     '(-4 . "AND>")
     '(-4 . "OR>")
       )
        )
      )
    (progn
      ;;(vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
      (setq n -1)
      (while (setq e (ssname ss (setq n (1+ n))))
(setq el (entget e))
(setq obj (vlax-ename->vla-object e))
(cond ((wcmatch (cdr (assoc 0 el)) "TEXT,MTEXT")
        (setq str (cdr (assoc 1 el)))
        (vla-put-textstring obj (_replacetext newpatt patt str))
       )
       ((= (cdr (assoc 0 el)) "DIMENSION")
        (and (wcmatch (strcase (setq str (cdr (assoc 1 el)))) (strcat "*" patt "*"))
     (vla-put-textoverride obj (_replacetext newpatt patt str))
        )
       )
       (t
        (foreach x (vlax-invoke obj 'getattributes)
(and (wcmatch (strcase (setq str (vla-get-textstring x))) (strcat "*" patt "*"))
       (vla-put-textstring x (_replacetext newpatt patt str))
)
        )
       )
)
      )
      ;;(vla-endundomark adoc)
    )
    (princ "\nNo Text entities found!")
  )
  (princ)
)

(txtfind "AI1" "FAI1")
(txtfind "AI2" "FAI2")
(txtfind "AI3" "FAI3")
(txtfind "AI4" "FAI4")
(txtfind "AO1" "FAO1")
(txtfind "AO2" "FAO2")
(txtfind "AO3" "FAO3")
(txtfind "AO4" "FAO4")
(txtfind "DI1" "FDI1")
(txtfind "DI2" "FDI2")
(txtfind "DI3" "FDI3")
(txtfind "DI4" "FDI4")
(txtfind "DO1" "FDO1")
(txtfind "DO2" "FDO2")
(txtfind "DO3" "FDO3")
(txtfind "DO4" "FDO4")
Title: Re: Command line Find
Post by: M-dub on October 17, 2012, 12:30:33 PM
Would this help at all Mike?

http://lee-mac.com/bfind.html (http://lee-mac.com/bfind.html)
Funny story...

The short version:  Yes, it helps!  :lol:
Title: Re: Command line Find
Post by: Lee Mac on October 17, 2012, 02:53:02 PM
Would this help at all Mike?

http://lee-mac.com/bfind.html (http://lee-mac.com/bfind.html)
Funny story...

The short version:  Yes, it helps!  :lol:

Excellent  :-)
Title: Re: Command line Find
Post by: JohnK on June 16, 2021, 04:05:10 PM
I needed a text "find and replace" routine I could use with accoreconsole and I found this thread which saved me a lot of time. I have modified the above routine (txtfind) to use regular AutoLisp (no VisualLisp).

Thank you to those of you that helped create/modify this routine. Here is my contribution.
Code - Auto/Visual Lisp: [Select]
  1. (defun txtfind (patt newpatt / _replacetext e el n obj ss str)
  2.     ;; Routine to find specified text and replace with new text. Works on Text,
  3.     ;; Mtext, Attributes and Dimension text overrides.
  4.     ;;
  5.     ;; WARNING : it will change all occurances of a pattern with the new text.
  6.     ;;           Such as: if "test" "contest" "testing" are all valid text
  7.     ;;           entries in the drawing, running this: (txtfind "test"
  8.     ;;           "newtest") will change the original text to "newtest"
  9.     ;;           "connewtest" "newtesting", but for the original intent of this
  10.     ;;           routine that was not a problem. Modifications may be made to
  11.     ;;           force matching of whole word only.
  12.     ;; by: Jeff Mishler Sept. 2003
  13.     ;;
  14.     ;; 10.16.2012 - Modified by RJP to prevent infinite loop when source search includes
  15.     ;;              all or part of replace pattern.
  16.     ;;            - Created more refined filter
  17.     ;;                  ie.
  18.     ;;                  (txtfind "AI1" "FAI1")
  19.     ;;                  (txtfind "AI2" "FAI2")
  20.     ;; 06.16.2021 - Modified by John Kaul to use only AutoLisp functions (no visual lisp),
  21.     ;;              so this can be used with accoreconsole.
  22.  
  23.    (defun str_subst ( new old txtstr / i char)                  ; /*{{{*/
  24.        ;;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  25.        ;; STR_SUBST
  26.        ;;  replace text in a string with new text
  27.        ;;
  28.        ;;  by: Iqbal Lotey 09/10/1999
  29.        ;;
  30.        ;;  Takes  new    string to replace with
  31.        ;;         old    string to be replaced
  32.        ;;         txtstr string to search in
  33.        ;;
  34.        ;;  Returns modified string, or unmodified string if old not found
  35.        ;;  WARNING : no error checking! function WILL hang or crash if it doesn't
  36.        ;;            recieve sensible values (i.e. no emtpy strings!)
  37.      (setq i 1)
  38.      (while ( <= i (strlen txtstr))
  39.        (setq char (substr txtstr i (strlen old)))
  40.        (if (equal char old)
  41.          (setq txtstr (strcat (substr txtstr 1 (- i 1))
  42.                               new (substr txtstr
  43.                                           (+ i (strlen old))))
  44.                i (+ i (- (strlen new) 1))
  45.          )
  46.          (setq i (1+ i))
  47.        )
  48.      )
  49.      txtstr
  50.    )                    ; /*}}}*/
  51.   ;; More refined filter
  52.   (if (setq ss (ssget "_X"
  53.                        (list '(-4 . "<OR")
  54.                              '(-4 . "<AND")
  55.                              ;; *text that only has part of the search string
  56.                              '
  57.                               (0 . "MTEXT,TEXT")
  58.                              (cons 1 (strcat "*" patt "*"))
  59.                              '(-4 . "AND>")
  60.                              '(-4 . "<AND")
  61.                              ;; Attributed blocks
  62.                              '
  63.                               (0 . "INSERT")
  64.                              '(66 . 1)
  65.                              '(-4 . "AND>")
  66.                              ;; Dimension DUH
  67.                              '
  68.                               (-4 . "<AND")
  69.                              '(0 . "DIMENSION")
  70.                              '(-4 . "AND>")
  71.                              '(-4 . "OR>")
  72.                        )
  73.                 )
  74.       )
  75.     (progn
  76.       (setq n -1)
  77.       (while (setq e (ssname ss (setq n (1+ n))))
  78.          (setq el (entget e))
  79.          (cond ((wcmatch (cdr (assoc 0 el)) "TEXT,MTEXT")
  80.                 (setq str (cdr (assoc 1 el)))
  81.                 (entmod (subst (cons 1 (str_subst newpatt patt str)) (assoc 1 el) el)))
  82.                ((= (cdr (assoc 0 el)) "DIMENSION")
  83.                 (and (wcmatch (setq str (cdr (assoc 1 el))) (strcat "*" patt "*"))
  84.                      (entmod (subst (cons 1 (str_subst newpatt patt str)) (assoc 1 el) el))))
  85.                (t
  86.                  (setq el (entget (entnext (cdr (assoc -1 el)))))
  87.                  (while (and (= (cdr (assoc 0 el)) "ATTRIB") (not (= (cdr (assoc 0 el)) "SEQEND")))
  88.                    (if (wcmatch (setq str (cdr (assoc 1 el))) patt)
  89.                      (entmod (subst (cons 1 (str_subst newpatt patt str)) (assoc 1 el) el))
  90.                    )
  91.                    (setq el (entget (entnext (cdr (assoc -1 el)))))))
  92.          )
  93.       )
  94.     )
  95.     (princ "\nNo Text entities found!")
  96.   )
  97.   (princ)
  98. )


EDIT:
2021-06-16: Fixed minor code error.
2021-07-20: Adjusted attribute code section slightly.
Title: Re: Command line Find
Post by: JohnK on July 20, 2021, 11:55:09 AM
Update: Adjusted attribute code section slightly (slightly more efficient).