Add Text

Discussion in 'AutoCAD' started by om_gc, Dec 11, 2004.

  1. om_gc

    om_gc Guest

    Hi.
    The lisp routine below adds the number by the increment the user specify as long as the number is separated by a single space with the word. I wish the routine add the number even after two words. For example. TC 245.20 and if the user specify an increment by 1.5, then the result will be TC 246.70. However it doesn't work if one have more than a word like PVI Elev 100.5, the result will be an error (does nothing). and even it won't take a "=" between the number and the text.
    Can anyone help with is routine.
    Thanks in advance
     
    om_gc, Dec 11, 2004
    #1
  2. om_gc

    Don I Guest

    The following should work--although I've not tested it as I don't have acad
    here at home.

    ;Parse a string
    ;Author: Don Ireland
    ;Date: 12/11/04
    ;Arguments: string - the string to parse
    ; parseChar - the seperator character
    ; caseSensitive - if present and not nil then this is case sensitive
    (defun strParse (string parseChar caseSensitive / rtn cnt )
    (if (wcmatch string (strcat "*", parseChar, "*"))
    (progn(setq charCnt -1 cWord "")
    (repeat
    (setq charCnt (1+ charCnt))
    (if (= (substr (if caseSensitive string (strcase string)) charCnt 1)
    (if caseSensitive parseChar (strcase parseChar)))
    (progn(if wordList
    (setq wordList(append wordList (list cWord)))
    (setq wordList (list cWord))
    );endif
    (setq cWord ""));endProgn
    (setq cWord (strcat cWord (substr string charCnt 1))
    );endif
    );endProgn
    );endif
    )

    ;the following will return the LAST item in the list created
    ;by the above routine.
    (reverse(cdr(strParse "PVI Elev 10.20" " " nil)))
     
    Don I, Dec 11, 2004
    #2
  3. ; caseSensitive - if present and not nil then this is case sensitive

    should be:

    ....and there are some lost parenteses


    --

    Marc'Antonio Alessi
    http://xoomer.virgilio.it/alessi
    (strcat "NOT a " (substr (ver) 8 4) " guru.")

    --
     
    Marc'Antonio Alessi, Dec 12, 2004
    #3
  4. om_gc

    Don I Guest

    Marc,

    caseSensitive - if present and not nil then this is case sensitive
    &
    caseSensitive - if not nil then this is case sensitive

    mean the same thing--I worded it as I did because that's the why all the
    acad AutoLisp documentation I've seen worded it like that and to avoid
    confusion, I followed suit.

    Regarding the lost parenthesis, I thought there might be--although I
    HONESTLY THOUGHT I had found them all.

    Anyway, I went back through and looked for lost parentheses. I found a
    couple--I also found a couple things that I needed to revise slightly.

    Like I said, I don't have acad here at home and can't really test.

    ;Parse a string
    ;Author: Don Ireland
    ;Date: 12/11/04
    ;Version: 1.01
    ;Arguments: string - the string to parse
    ; parseChar - the seperator character
    ; caseSensitive - if present and not nil then this is case sensitive
    (defun strParse (string parseChar caseSensitive / rtn cnt wordList cWord
    charCnt)
    (if (wcmatch string (strcat "*" parseChar "*"))
    (progn(setq charCnt -1 cWord "")
    (repeat
    (setq charCnt (1+ charCnt))
    (if (= (substr (if caseSensitive (strcase string) string) charCnt 1)
    (if caseSensitive (strcase parseChar) parseChar))
    (progn(if wordList
    (setq wordList(append wordList (list cWord)))
    (setq wordList (list cWord))
    );endif
    (setq cWord ""));endProgn
    (setq cWord (strcat cWord (substr string charCnt 1)))
    );endif
    ));endRepeat & endProgn
    );endif
    (setq rtn wordList)
    )
     
    Don I, Dec 13, 2004
    #4
  5. om_gc

    Don I Guest

    After posting that, I thought about how to speed it up. I realized that
    SUBSTR will find the FIRST occurance of the parse character and then return
    the remainder of the string. THAT's the key.

    The following doesn't need to look at EVERY character and should be much
    faster. Again still not tested--I plan to test it tomorrow if I get a
    chance.

    ;Parse a string
    ;Author: Don Ireland
    ;Date: 12/11/04
    ;Version: 1.10
    ;Arguments: string - the string to parse
    ; parseChar - the seperator character
    ; caseSensitive - if present and not nil then this is case sensitive
    (defun strParse (string parseChar caseSensitive / rem wordList cWord rtn)
    (setq rem string)
    (if (wcmatch string (strcat "*", parseChar, "*"))
    (while (< 0 (strlen rem))
    (setq rem(substr (if caseSensitive (strcase parseChar) parseChar))
    rem)
    (setq cWord(substr 1 (strlen rem)))
    (if wordList (setq wordList(append wordList (list cWord)))(setq
    wordList (list cWord)))
    )
    );endif
    (setq rtn wordList)
    )
     
    Don I, Dec 13, 2004
    #5
  6. caseSensitive - if present and not nil then this is case sensitive

    Try:

    (strParse "PVI Elev 10.20" " ")

    ;caseSensitive not present


    --

    Marc'Antonio Alessi
    http://xoomer.virgilio.it/alessi
    (strcat "NOT a " (substr (ver) 8 4) " guru.")

    --
     
    Marc'Antonio Alessi, Dec 13, 2004
    #6
  7. om_gc

    Joe Burke Guest

    Just fooling around...

    ;; return first number in string
    (defun c:FirstNum (/ str lst newlst res)
    (and
    (setq str (getstring T "\nEnter string containing numbers: "))
    (setq lst (vl-string->list str))
    (foreach x lst
    (if
    (or (= x 32) (< 44 x 58))
    (setq newlst (append newlst (list x)))
    )
    )
    (setq res (atof (vl-list->string newlst)))
    )
    res
    ) ;end

    Command: firstnum
    Enter string containing numbers: abc-123.4 d 24
    -123.4

    One problem I see with this is atof doesn't like commas in strings: (atof "1,000")
    returns 1.0. So commas are filtered out.

    Another hiccup, it returns a real when the first number in string is an integer. I
    guess that could be avoided with a little more code.

    Oh well... the point being the OP's method for determining where a number starts in a
    string, based on a space preceding the number, is not a good idea. Rather, extract
    the numbers from the string and process as needed.

    Joe Burke
     
    Joe Burke, Dec 13, 2004
    #7
  8. om_gc

    T.Willey Guest

    Here is how I did it.

    Tim

    Ps. change the file extension from ".txt" to ".lsp" to use. at command type "addtext".
     
    T.Willey, Dec 13, 2004
    #8
  9. om_gc

    om_gc Guest

    HI
    Tim, the code works for the words and an equal sign but doesn't work properly for the numbers. (Results two dots like 14.0.00)
    Thanks
     
    om_gc, Dec 13, 2004
    #9
  10. om_gc

    T.Willey Guest

    If you have the situation a lot, then you could modify the code any way you want to fit your needs.

    Have fun with it.

    Tim
     
    T.Willey, Dec 13, 2004
    #10
  11. om_gc

    om_gc Guest

    Tim
    I have the problem all the time. The problem is if i input 1 for the decimal place it adds one zero and the decimal, likewise if i specify 2, it adds 2 zeros and a decimal. The result will be perfect, if you eliminate the necessary addition of zero. Works perfect if i don't have any decimal place.
    Hope u'll help me out.
    Thanks
     
    om_gc, Dec 13, 2004
    #11
  12. om_gc

    T.Willey Guest

    What do you have existing in the drawing that you want to modify? What do you want to end up with? Will you only use it to modify this type of number system?

    Would need a little more info. Can you write lisp routines? We usually like to help people write routines, not write the routine for them. This is one I have existing, so it is no problem sharing it.

    Tim
     
    T.Willey, Dec 13, 2004
    #12
  13. om_gc

    om_gc Guest

    I'm a beginner in lisp programming. still not capable of automizing complicated task. My problem is: I have words followed by a number. I want to add/subtract only the numeral part without making any changes to the words. This is my goal.
    For example, PVI STA = 100.00, i want to add certain value only to this number let say 0.50 and want to end up with PVI STA = 100.50.
    Thanks
     
    om_gc, Dec 14, 2004
    #13
  14. om_gc

    Adesu Guest

    Hi om_gc,you can try my code,more simple and easy,look in below

    ; rt is stand for revised text
    ; Design by Ade Suharna <>
    ; 1 December 2004
    ; Program no. 145/12/2004
    ; Edit by
    (defun c:rt (/ ent info1 opt remtex revtex ed)
    (while
    (setq ent (entget (car (entsel "\nCLICK TEXT FOR EDIT:"))))
    (setq info1 (cdr (assoc 1 ent)))
    (setq opt (getstring T "\nENTER NEW TEXT TO INSERT IT: "))
    (setq remtex (getstring T "\nENTER OLD TEXT TO REMOVE: "))
    (setq revtex (vl-string-subst opt remtex info1))
    (setq ed (subst (cons 1 revtex)(assoc 1 ent) ent))
    (entmod ed)
    )
    (princ)
    )



    complicated task. My problem is: I have words followed by a number. I want
    to add/subtract only the numeral part without making any changes to the
    words. This is my goal.
    number let say 0.50 and want to end up with PVI STA = 100.50.
     
    Adesu, Dec 14, 2004
    #14
  15. om_gc

    MP Guest

    imho it's easiest to break a problem into component parts, solving each part
    in turn
    creating functions to do intermediate steps helps in modularizing code and
    eliminating repetitive coding in the future

    in your example the first step is dividing the original string into alpha
    and numeric parts
    there would be many ways to do this
    one way would be to break it and return the two parts as a list of two
    elements
    the alpha part and the numeric part
    this assumes the string is in the format you show(alpha part first, numeric
    part last)
    you could adjust the function if you had other needs but for this problem
    this is one way
    probably not the best or shortest - i'm sure others will come along with
    better solutions
    (defun GetAlphaNumeric (string / strlist num numPart alphaPart char i)
    ;convert string into list of ascii codes
    (setq strlist(vl-string->list string))
    (setq i (length strlist))
    ;go through list from end(since your number was last)
    (while (> i 0)
    (setq char (nth (setq i(1- i)) strlist))
    ;if it's a number or decimal point, put in numeric part
    (if (or(= char 46) (and (> char 47)(< char 57)))
    (setq numPart(cons char numPart))
    ;otherwise put in alpha part
    (setq alphaPart(cons char alphaPart))
    )
    )
    ;convert ascii codes back to strings and return to calling function
    ; as a list of two strings
    (list (vl-list->string alphaPart) (vl-list->string numPart))
    )




    (defun test( / teststring anlist alpha numer addthis newnum newstring)
    (setq teststring "PVA STA = 100.00")
    (setq anList (GetAlphaNumeric teststring))
    ;now you have it divided into alpha and numeric, just add your value to the
    numeric part
    (setq alpha(car anList)
    ;since the numeric part is still a string you have to convert to number to
    do addition
    numer(atof(cadr anList)))
    ;in actual work this would get passed into the function as an argument
    ;just for example we'll hard code the value you presented
    (setq addThis 0.50)
    ;addem up
    (setq newNum(+ numer addThis))
    ;convert back to string
    (setq newString(strcat alpha (rtos newNum 2 2)))
    ;show the result
    (princ(strcat"\nResult: " newstring))
    (princ)
    )

    hope that helps
    Mark

    complicated task. My problem is: I have words followed by a number. I want
    to add/subtract only the numeral part without making any changes to the
    words. This is my goal.
    number let say 0.50 and want to end up with PVI STA = 100.50.
     
    MP, Dec 14, 2004
    #15
  16. om_gc

    Joe Burke Guest

    OK, here's an interface shell for the function I posted before. It's modified to
    operate as a sub-function and includes additional comments. Error checking is
    incomplete in the primary function.

    Notice a few things. The number may reside anywhere within the string, regardless of
    leading characters. Trailing numbers within the string are ignored. And the string
    may only represent a number, such as "123.4".

    I think this is what you are looking for given your original question, as I
    understand it. And yes, there will likely be some additional hiccups with integers
    vs. reals. Nothing that can't be dealt with, though outside the scope of what's
    presented here.

    Hi Tim,

    I haven't had time to look at what you posted. It might be similar?

    Joe Burke

    (defun c:TextIncrement (/ inc ent vobj oldstr oldnum oldsubstr
    newnum newsubstr newstr)
    (initget 1)
    (setq inc (getreal "\nEnter numeric value negative or positive: "))
    (while (setq ent (car (entsel "\nSelect text or mtext, or enter to end: ")))
    (setq vobj (vlax-ename->vla-object ent))
    (setq oldstr (vlax-get vobj 'TextString))
    (setq oldnum (FirstNum oldstr))
    (setq oldsubstr (vl-princ-to-string oldnum))
    (setq newnum (+ inc oldnum))
    (setq newsubstr (vl-princ-to-string newnum))
    (setq newstr (vl-string-subst newsubstr oldsubstr oldstr))
    (vlax-put vobj 'TextString newstr)
    )
    (princ)
    ) ;end

    ;; return first number in string argument
    ;; 32 represents the space character
    ;; note: atof strips leading spaces and ignores trailing characters
    ;; (atof " 123.4 5.6") returns 123.4
    (defun FirstNum (str / lst)
    (foreach x (vl-string->list str)
    (if (or (= x 32) (< 44 x 58))
    (setq lst (append lst (list x)))
    )
    )
    (atof (vl-list->string lst))
    ) ;end
     
    Joe Burke, Dec 14, 2004
    #16
  17. om_gc

    T.Willey Guest

    Hi Joe,

    It seems to do about the same thing. I just get my selections with a ssget. When I tried your's, the first text I picked did nothing, but the second did it, then the thrid did nothing, but the fourth worked again.

    Just thought I would let you know.
    Tim
     
    T.Willey, Dec 14, 2004
    #17
  18. om_gc

    T.Willey Guest

    Thanks for pointing that out. I thought it worked correctly.

    Tim

    Paste this new part over the old one you have already.

    (defun AddStrNReal (StrValue RealNum StrType DecPlace / cnt1 cnt2 txt4 txt5 txt6 txt7 op1 dec1)

    (setq cnt1 0
    cnt2 0
    )
    (while (not (<= 46 (ascii (substr StrValue 1 1)) 58))
    (if txt4
    (setq txt4 (strcat txt4 (substr StrValue 1 1)))
    (setq txt4 (substr StrValue 1 1))
    )
    (setq StrValue (substr StrValue 2 (strlen StrValue)))
    )

    (while (= (substr StrValue 1 1) " ")
    (if txt4
    (setq txt4 (strcat txt4 (substr StrValue 1 1)))
    (setq txt4 (substr StrValue 1 1))
    )
    (setq StrValue (substr StrValue 2 (strlen StrValue)))
    )

    (while (or (<= 46 (ascii (substr StrValue 1 1)) 58) (= (ascii (substr StrValue 1 1)) 44))
    (if (= (substr StrValue 1 1) ",")
    (setq StrValue (substr StrValue 2 (strlen StrValue)))
    )
    (if txt5
    (setq txt5 (strcat txt5 (substr StrValue 1 1)))
    (setq txt5 (substr StrValue 1 1))
    )
    (setq StrValue (substr StrValue 2 (strlen StrValue)))
    )

    (setq txt5 (atof txt5))
    (setq txt6 (rtos (+ txt5 RealNum) StrType DecPlace))
    (if (> (atoi txt6) 999)
    (progn
    (initget "Y N")
    (setq op1 (getkword "\nWould you like to add comma(s) [Y,<N>]? "))
    (if (= op1 "Y")
    (progn
    (setq txt7 txt6)
    (while (and (/= dec1 ".") (<= (strlen txt6) 0))
    (setq dec1 (substr txt6 1 1))
    (setq cnt1 (1+ cnt1))
    (setq txt6 (substr txt6 2 (strlen txt6)))
    )
    (if (= dec1 ".")
    (progn
    (setq txt6 (substr txt6 1 (- (strlen txt6) 1)))
    (setq txt7 (substr txt7 (strlen txt6) (strlen txt7)))
    )
    )
    (while (>= (strlen txt6) (+ cnt2 4))
    (setq txt6 (strcat (substr txt6 1 (- (strlen txt6) (+ 3 cnt2))) "," (substr txt6 (- (strlen txt6) (+ 2 cnt2)) (strlen txt6))))
    (setq cnt2 (+ cnt2 4))
    )
    (if (= dec1 ".")
    (setq txt6 (strcat txt6 txt7))
    )
    )
    )
    )
    )
    (setq txt7
    (if txt4
    (strcat txt4 txt6 StrValue)
    (strcat txt6 StrValue)
    )
    )

    )
     
    T.Willey, Dec 14, 2004
    #18
  19. om_gc

    Joe Burke Guest

    Tim,

    It seems OK here. I suspect missed picks. As is it does nothing and ends in that
    case.

    Thanks for checking.

    Joe Burke
     
    Joe Burke, Dec 15, 2004
    #19
  20. om_gc

    T.Willey Guest

    Joe,

    It seems that your code doesn't like it if there is no decimal point in the number. When I tested it, it worked only on ones with decimal points. No missed picks because it didn't exit the program, it just let me select another text object.

    Tim
     
    T.Willey, Dec 15, 2004
    #20
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.