Author Topic: Command line Find  (Read 21922 times)

0 Members and 1 Guest are viewing this topic.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Command line Find
« Reply #15 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.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Command line Find
« Reply #16 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))
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

M-dub

  • Guest
Re: Command line Find
« Reply #17 on: April 18, 2008, 12:10:33 PM »
First of all, Thank-you!



Constant?  :?


(Checking... )

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Command line Find
« Reply #18 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.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

M-dub

  • Guest
Re: Command line Find
« Reply #19 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... ?

M-dub

  • Guest
Re: Command line Find
« Reply #20 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...

M-dub

  • Guest
Re: Command line Find
« Reply #21 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

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Command line Find
« Reply #22 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

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

M-dub

  • Guest
Re: Command line Find
« Reply #23 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

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Command line Find
« Reply #24 on: October 15, 2012, 03:31:02 PM »
Maybe try changing the autocad temp directory to another location and see if the problem persists?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

M-dub

  • Guest
Re: Command line Find
« Reply #25 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.
« Last Edit: October 15, 2012, 03:44:03 PM by M-dub »

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Command line Find
« Reply #26 on: October 15, 2012, 03:44:54 PM »
That is weird  :?. Can you post a sample drawing that this crashes on?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

M-dub

  • Guest
Re: Command line Find
« Reply #27 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.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Command line Find
« Reply #28 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.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Command line Find
« Reply #29 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)
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.