Organic Posted June 28, 2011 Share Posted June 28, 2011 Does anyone have a better way of doing the following or know of a lisp that accomplishes this? I need to remove the numeric prefixes from the following example strings (mtext): 12ABCD 1DEF 11ABCD 08GHF 1326KJD so they would go to ABCD, DEF, ABCD, GHF and KJD. It would be good if it could only be applied to a selection set of objects. I can do it using the Find & Replace search tool, however when there are 100 different numeric prefixes etc it is still a time consuming task (thankfully not one that occurs very often however). So does anyone have a more efficient way? Quote Link to comment Share on other sites More sharing options...
designerstuart Posted June 28, 2011 Share Posted June 28, 2011 dink i'm sure i've seen a list somewhere of a load of special characters that you can use in searches which are more sophistocated than the * wildcard. so like there is one for any numerical, one for any alphabetical character and so on. any use to you? (a limited amount of info here) Quote Link to comment Share on other sites More sharing options...
Organic Posted June 28, 2011 Author Share Posted June 28, 2011 Thanks, that is a good start. I totally forgot about wildcards! Quote Link to comment Share on other sites More sharing options...
SLW210 Posted June 28, 2011 Share Posted June 28, 2011 I think I saw something similar in the LISP forum not too long ago. Quote Link to comment Share on other sites More sharing options...
irneb Posted June 29, 2011 Share Posted June 29, 2011 If you want to attempt the lisp yourself - look for the vl-string-left-trim function, IMO it's the simplest & fastest. Then look for some code to select text and step through the ActiveX selection set ... there should be many of those. Then all that's needed is to combine! Quote Link to comment Share on other sites More sharing options...
ketxu Posted June 29, 2011 Share Posted June 29, 2011 Maybe like this (defun c:1() (foreach ent (mapcar 'vlax-ename->vla-object (acet-ss-to-list (ssget '((0 . "*TEXT")(1 . "#*"))))) (vla-put-textstring ent (vl-string-left-trim (rtos (atoi (setq str (vla-get-textstring ent))) 2 0) str)))) Quote Link to comment Share on other sites More sharing options...
irneb Posted June 29, 2011 Share Posted June 29, 2011 A few small notes on your routine: I generally try not to use the acet functions as the user may not have Express tools installed. The *TEXT wildcard could also select RTEXT - (if they're working on an old drawing which has these it could make for crashes). For efficiency yours isn't as good as it can be. You're converting to vla objects multiple times. You don't need to worry about how long the number portion is. Simply send vl-string-left-trim the 10 digits which should be removed. My example: (vl-load-com) ;;; Remove number prefixes (defun c:RemNumPrefix (/ ss eo) (if (and (ssget '((0 . "TEXT,MTEXT") (1 . "#*"))) (setq ss (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))) ) (progn (vlax-for eo ss (vla-put-TextString (vl-string-left-trim "0123456789" (vla-get-TextString eo))) ) (vla-Delete ss) ) ) (princ) ) If you want to remove suffixes, then use vl-string-right-trim. Or to remove both use vl-string-trim. Quote Link to comment Share on other sites More sharing options...
ketxu Posted June 29, 2011 Share Posted June 29, 2011 Thank you for your comments ^^ I agree with two fisrt points, just a quick code (and if tested, yours is faster) . But i don't understand three point.Does It mean convert one time with one object, many times is any objects ? Quote Link to comment Share on other sites More sharing options...
BlackBox Posted June 29, 2011 Share Posted June 29, 2011 (edited) @Irneb - There is no change in effectiveness during execution, but I would typically drop the second part of your and statement into the main code, as if there is a valid selection set (via ssget) there is an ActiveSelectionSet: (vl-load-com) ;;; Remove number prefixes (defun c:RemNumPrefix (/ ss eo) (if [color=blue](ssget '((0 . "TEXT,MTEXT") (1 . "#*"))) [/color] (progn (vlax-for eo [color=blue](setq ss (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))) [/color] (vla-put-TextString (vl-string-left-trim "0123456789" (vla-get-TextString eo))) ) (vla-Delete ss) ) ) (princ) ) Less code - My $0.02 Edited July 12, 2011 by BlackBox Stupid typos Quote Link to comment Share on other sites More sharing options...
Tyke Posted June 29, 2011 Share Posted June 29, 2011 @Irneb - Lee code - My $0.02 Why do we always think Lee is going to jump in and show us a better way :wink: But its true he does. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted June 29, 2011 Share Posted June 29, 2011 @Irneb - Lee code - My $0.02 Why do we always think Lee is going to jump in and show us a better way :wink: But its true he does. User error. This is a typo on my part (fat-finger typing)... that was supposed to be "Less code..." Quote Link to comment Share on other sites More sharing options...
irneb Posted June 29, 2011 Share Posted June 29, 2011 Thank you for your comments ^^ I agree with two fisrt points, just a quick code (and if tested, yours is faster) . But i don't understand three point.Does It mean convert one time with one object, many times is any objects ? Basically what I meant by point 3 is you get a list of enames ... each of which you convert to a vla-object through vlax-ename->vla-object. This happens for each and every single entity in the selection set. It's not much, but with a great many entities this could eat up some time in the code's running. What I've done is rather than convert each entity, I've "converted" the selection set to the vla-object. I.e. no matter how many entities are selected there's only one conversion happening. Then using the vlax-for each entity is already in its vla-object form. If you wanted to use entmod instead, then I'd stick with using the normal ssget and not going for the ActiveSelectionSet. Otherwise you have to reconvert back to enames through vlax-vla-object->ename. So it depends on which you're going to use. Just remember that is you go with the vla section set you have to clear it through the vla-Delete method. It doesn't "auto"-clear itself like a normal selection set does. And with selection sets you only have a small number available, so you could quickly run into problems if they're not cleared. @RenderMan: True it makes more logical sense and there's a few less keys to type (something like 10 of them, depending on how many Enters you press), but they don't actually do anything different at all. Anyhow, yours is probably neater. Oh hang on, I see ... you need to reduce the required keystrokes to rest those fat fingers of yours. Even a small change is preferable right! Quote Link to comment Share on other sites More sharing options...
BlackBox Posted June 29, 2011 Share Posted June 29, 2011 @RenderMan: True it makes more logical sense and there's a few less keys to type (something like 10 of them, depending on how many Enters you press), but they don't actually do anything different at all. Anyhow, yours is probably neater. Absolutely no change in performance, my friend. Oh hang on, I see ... you need to reduce the required keystrokes to rest those fat fingers of yours. Even a small change is preferable right! Just yesterday, I got this warning... You have no idea how hard it was to find a keyboard that I could use... Quote Link to comment Share on other sites More sharing options...
ketxu Posted June 29, 2011 Share Posted June 29, 2011 Basically what I meant by point 3 is you get a list of enames ... each of which you convert to a vla-object through vlax-ename->vla-object. This happens for each and every single entity in the selection set. It's not much, but with a great many entities this could eat up some time in the code's running. What I've done is rather than convert each entity, I've "converted" the selection set to the vla-object. I.e. no matter how many entities are selected there's only one conversion happening. Then using the vlax-for each entity is already in its vla-object form. If you wanted to use entmod instead, then I'd stick with using the normal ssget and not going for the ActiveSelectionSet. Otherwise you have to reconvert back to enames through vlax-vla-object->ename. So it depends on which you're going to use. Just remember that is you go with the vla section set you have to clear it through the vla-Delete method. It doesn't "auto"-clear itself like a normal selection set does. And with selection sets you only have a small number available, so you could quickly run into problems if they're not cleared. Thanks you so much ^^ i ever think about SelectionSet Vla-Object. Where i can see more information about it ? So, with a rountine only working with one ssget, we should use foreach with entities (not vla object), and do sth by Autolisp, or vlax-for with Selectionset and do sth by VLisp. is it right ? Quote Link to comment Share on other sites More sharing options...
irneb Posted June 29, 2011 Share Posted June 29, 2011 If you want to know a bit more about the difference between a lisp ss and a vla ss, I've explained it in some details here: http://forums.augi.com/showthread.php?t=123526 Quote Link to comment Share on other sites More sharing options...
Organic Posted July 12, 2011 Author Share Posted July 12, 2011 @Irneb - There is no change in effectiveness during execution, but I would typically drop the second part of your and statement into the main code, as if there is a valid selection set (via ssget) there is an ActiveSelectionSet: (vl-load-com) ;;; Remove number prefixes (defun c:RemNumPrefix (/ ss eo) (if [color=blue](ssget '((0 . "TEXT,MTEXT") (1 . "#*"))) [/color] (progn (vlax-for eo [color=blue](setq ss (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))) [/color] (vla-put-TextString (vl-string-left-trim "0123456789" (vla-get-TextString eo))) ) (vla-Delete ss) ) ) (princ) ) Lee code - My $0.02 I can't get this to work and get the following error (when selecting mtext, objects were 3 text strings with contents 62LVL, 59LVL, 103LVL): Select objects: Specify opposite corner: 3 found Select objects: ; error: bad argument type: VLA-OBJECT "LVL" Any idea why? With the wild cards I tried it, although I couldn't get it to work/do what I need. It would select 123ABC, 456ABC when searching for *ABC, however when I then tried to replace that with just "ABC" using the find and replace tool, it didn't replace it at all (I'm thinking it replaced ABC with ABC again - althoguh the numeric prefixes of each was still retained). Any other ideas? Quote Link to comment Share on other sites More sharing options...
Organic Posted July 12, 2011 Author Share Posted July 12, 2011 This article (http://www.eatyourcad.com/article.php?incat_id=2329 - had to register to view it) helped me do what I needed. Searching for ###LVL will replace it. I thought the wildcard * would have been enough. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 12, 2011 Share Posted July 12, 2011 I can't get this to work and get the following error (when selecting mtext, objects were 3 text strings with contents 62LVL, 59LVL, 103LVL): Select objects: Specify opposite corner: 3 found Select objects: ; error: bad argument type: VLA-OBJECT "LVL" Any idea why? With the wild cards I tried it, although I couldn't get it to work/do what I need. It would select 123ABC, 456ABC when searching for *ABC, however when I then tried to replace that with just "ABC" using the find and replace tool, it didn't replace it at all (I'm thinking it replaced ABC with ABC again - althoguh the numeric prefixes of each was still retained). Any other ideas? Give this a try instead: (vl-load-com) ;;; Remove number prefixes (defun c:RemNumPrefix (/ ss eo) (if (ssget '((0 . "TEXT,MTEXT") (1 . "#*"))) (progn (vlax-for eo (setq ss (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))) (vla-put-TextString [color="red"]eo[/color] [color="blue"](vl-string-left-trim "0123456789" (vla-get-TextString eo))[/color]) ) (vla-Delete ss) ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
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.