Multiply function

Multiply function

Anonymous
Not applicable
1,403 Views
12 Replies
Message 1 of 13

Multiply function

Anonymous
Not applicable

Hi.

Can anyone help me with this problem:

(defun c:txt2tab1 ( )
    (txt2tab:main '("^\\d+" "\\d+" "%%C\\d+" "C=" "\\d+\\.?\\d*") "MYDWGLAYER")
)

;;----------------------------------------------------------------------;;


(defun txt2tab:main ( pat lay / *error* idx ins itm lst mlt obj rgx sel str tmp )

    (setq mlt
       '(
            ("5"   . 0.154)
            ("6.3" . 0.245)
            ("8"   . 0.395)
            ("10"  . 0.617)
            ("12.5". 0.963)
            ("16"  . 1.578)
            ("20"  . 2.466)
            ("25"  . 3.853)
            ("32"  . 6.313)
        )
    )

    (defun *error* ( msg )
        (if
            (and
                (= 'vla-object (type rgx))
                (not (vlax-object-released-p rgx))
            )
            (vlax-release-object rgx)
        )
        (if
            (and
                (= 'vla-object (type obj))
                (vlax-read-enabled-p obj)
                (= "AcDbTable" (vla-get-objectname obj))
                (vlax-write-enabled-p obj)
            )
            (vla-put-regeneratetablesuppressed obj :vlax-false)
        )
        (txt2tab:endundo (txt2tab:acdoc))
        (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )

I cant multiply values like 6.3 and 12.5. The other ones works well.

0 Likes
Accepted solutions (1)
1,404 Views
12 Replies
Replies (12)
Message 2 of 13

dlanorh
Advisor
Advisor

At a guess, the regex pattern, i think it's a regex pattern since the error sub contains

(vlax-release-object rgx)

Pattern string

 

'("^\\d+" "\\d+" "%%C\\d+" "C=" "\\d+\\.?\\d*")

 is satisfying the integer number pattern before the real numbers pattern. Difficult to tell as the regex part is missing from your posted code and without it i don't know how its being implemented.

I am not one of the robots you're looking for

0 Likes
Message 3 of 13

Anonymous
Not applicable

dlanorh,

Thank you.

Here is the regex part:

    (txt2tab:startundo (txt2tab:acdoc))
    (cond
        (   (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (getvar 'clayer))))))
            (princ "\nO layer está locked.")
        )
        (   (not
                (setq sel
                    (txt2tab:ssget (strcat "\nSeleciona o texto no \"" lay "\" layer: ")
                        (list
                            (list
                               '(000 . "TEXT")
                                (cons 8 lay)
                                (if (= 1 (getvar 'cvport))
                                    (cons 410 (getvar 'ctab))
                                   '(410 . "Model")
                                )
                            )
                       	)
                    )
                )
            )
            (princ "\n*Cancel*")
        )
        (   (not (setq ins (getpoint "\nDiz-me onde queres a tabela: ")))
            (princ "\n*Cancel*")
        )
        (   (not (setq rgx (vlax-get-or-create-object "vbscript.regexp")))
            (princ "\nImpossivel estabelecer uma ligação com o objecto RegEx.")
        )
        (   (progn
                (vlax-put-property rgx 'global     acfalse)
                (vlax-put-property rgx 'ignorecase actrue)
                (vlax-put-property rgx 'multiline  acfalse)

                (repeat (setq idx (sslength sel))
                    (setq str (cdr (assoc 1 (entget (ssname sel (setq idx (1- idx)))))))
                    (cond
                        (   (/= 5 (length (setq tmp (txt2tab:parsestring rgx str pat))))
                            (princ (strcat "\nA string \"" str "\" não pode ser partida em 5 elementos."))
                        )
                        (   (< (atoi (nth 0 tmp)) 1)
                            (princ (strcat "\nO primeiro elemento (\"" (nth 0 tmp) "\") da string \"" str "\" não é um integral."))
                        )
                        (   (null  (distof (nth 4 tmp) 2))
                            (princ (strcat "\nO quinto elemento (\"" (nth 4 tmp) "\") da string \"" str "\" não é um valor numérico."))
                        )
                        (   (null  (assoc (substr (nth 2 tmp) 4) mlt))
                            (princ (strcat "\nO diametro \"" (substr (nth 2 tmp) 4) "\" não foi encontrado na lista de pesos."))
                        )
                        (   (vl-some '(lambda ( x ) (if (vl-every '= (cdr tmp) (cdr x)) (setq itm x))) lst)
                            (setq lst (subst (cons (+ (atoi (nth 0 tmp)) (car itm)) (cdr itm)) itm lst))
                        )
                        (   (setq lst (cons (cons (atoi (nth 0 tmp)) (cdr tmp)) lst)))
                    )
                )
                (setq lst
                    (mapcar
                        (function
                            (lambda ( x )
                                (list
                                    (nth 1 x)
                                    (nth 2 x)
                                    (itoa (nth 0 x))
                                    (nth 4 x)
                                    (rtos (* (nth 0 x) (distof (nth 4 x) 2)) 2 1)
                                    (rtos (* (nth 0 x) (distof (nth 4 x) 2) (cdr (assoc (substr (nth 2 x) 4) mlt))) 2 1)
                                )
                            )
                        )
                        lst
                    )
                )
                (null lst)
            )
            (princ "\nNão foram encontrado dados válidos.")
        )

 

0 Likes
Message 4 of 13

DannyNL
Advisor
Advisor

Well, since you specifically mention 6.3 and 12.5....

 

6.3 and 12.5 are defined as strings, so these cannot be multiplied directly and somewhere in the code you didn't post there needs to be a conversion. Converting strings to numbers is usually done with ATOF (to convert to floating) and ATOI (to convert to integer.

As 6.3 and 12.5 are the only floating numbers defined as a string and these do not multiple correctly, my first idea would be that ATOI is used in the code while you actually need ATOF.

0 Likes
Message 5 of 13

DannyNL
Advisor
Advisor

You posted while I was writing my response Smiley Happy

 

Well, there you go: ATOI is used and 6.3 will become 6 and 12.5 will become 12.

So you'll need to change ATOI to ATOF in your code to make it work with floating numbers.

 

...
...
                    (cond
                        (   (/= 5 (length (setq tmp (txt2tab:parsestring rgx str pat))))
                            (princ (strcat "\nA string \"" str "\" não pode ser partida em 5 elementos."))
                        )
                        (   (< (atof (nth 0 tmp)) 1)
                            (princ (strcat "\nO primeiro elemento (\"" (nth 0 tmp) "\") da string \"" str "\" não é um integral."))
                        )
                        (   (null  (distof (nth 4 tmp) 2))
                            (princ (strcat "\nO quinto elemento (\"" (nth 4 tmp) "\") da string \"" str "\" não é um valor numérico."))
                        )
                        (   (null  (assoc (substr (nth 2 tmp) 4) mlt))
                            (princ (strcat "\nO diametro \"" (substr (nth 2 tmp) 4) "\" não foi encontrado na lista de pesos."))
                        )
                        (   (vl-some '(lambda ( x ) (if (vl-every '= (cdr tmp) (cdr x)) (setq itm x))) lst)
                            (setq lst (subst (cons (+ (atof (nth 0 tmp)) (car itm)) (cdr itm)) itm lst))
                        )
                        (   (setq lst (cons (cons (atof (nth 0 tmp)) (cdr tmp)) lst)))
                    )
                )
...
...
0 Likes
Message 6 of 13

Anonymous
Not applicable

DannyNL,

Thank you.

No...not working…

0 Likes
Message 7 of 13

john.uhden
Mentor
Mentor

Since they are strings, you know you have to convert them to reals using the ATOF or DISTOF or READ functions before multiplying.

John F. Uhden

0 Likes
Message 8 of 13

Anonymous
Not applicable
(defun c:txt2tab1 ( )
    (txt2tab:main '("^\\d+" "\\d+" "%%C\\d+" "C=" "\\d+\\.?\\d*") "E-B-TEXTOS")
)
;;----------------------------------------------------------------------;;
(defun txt2tab:main ( pat lay / *error* idx ins itm lst mlt obj rgx sel str tmp )

    (setq mlt
       '(
            ( "5"  . 0.154)
            ( "6.3". 0.245)
            ( "8"  . 0.395)
            ("10"  . 0.617)
            ("12.5". 0.963)
            ("16"  . 1.578)
            ("20"  . 2.466)
            ("25"  . 3.853)
            ("32"  . 6.313)
        )
    )

    (defun *error* ( msg )
        (if
            (and
                (= 'vla-object (type rgx))
                (not (vlax-object-released-p rgx))
            )
            (vlax-release-object rgx)
        )
        (if
            (and
                (= 'vla-object (type obj))
                (vlax-read-enabled-p obj)
                (= "AcDbTable" (vla-get-objectname obj))
                (vlax-write-enabled-p obj)
            )
            (vla-put-regeneratetablesuppressed obj :vlax-false)
        )
        (txt2tab:endundo (txt2tab:acdoc))
        (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )

    (txt2tab:startundo (txt2tab:acdoc))
    (cond
        (   (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (getvar 'clayer))))))
            (princ "\nO layer está locked.")
        )
        (   (not
                (setq sel
                    (txt2tab:ssget (strcat "\nSeleciona o texto no \"" lay "\" layer: ")
                        (list
                            (list
                               '(000 . "TEXT")
                                (cons 8 lay)
                                (if (= 1 (getvar 'cvport))
                                    (cons 410 (getvar 'ctab))
                                   '(410 . "Model")
                                )
                            )
                       	)
                    )
                )
            )
            (princ "\n*Cancel*")
        )
        (   (not (setq ins (getpoint "\nDiz-me onde queres a tabela: ")))
            (princ "\n*Cancel*")
        )
        (   (not (setq rgx (vlax-get-or-create-object "vbscript.regexp")))
            (princ "\nImpossivel estabelecer uma ligação com o objecto RegEx.")
        )
        (   (progn
                (vlax-put-property rgx 'global     acfalse)
                (vlax-put-property rgx 'ignorecase actrue)
                (vlax-put-property rgx 'multiline  acfalse)

                (repeat (setq idx (sslength sel))
                    (setq str (cdr (assoc 1 (entget (ssname sel (setq idx (1- idx)))))))
                    (cond
                        (   (/= 5 (length (setq tmp (txt2tab:parsestring rgx str pat))))
                            (princ (strcat "\nA string \"" str "\" não pode ser partida em 5 elementos."))
                        )
                        (   (< (atoi (nth 0 tmp)) 1)
                            (princ (strcat "\nO primeiro elemento (\"" (nth 0 tmp) "\") da string \"" str "\" não é um integral."))
                        )
                        (   (null  (distof (nth 4 tmp) 2))
                            (princ (strcat "\nO quinto elemento (\"" (nth 4 tmp) "\") da string \"" str "\" não é um valor numérico."))
                        )
                        (   (null  (assoc (substr (nth 2 tmp) 4) mlt))
                            (princ (strcat "\nO diametro \"" (substr (nth 2 tmp) 4) "\" não foi encontrado na lista de pesos."))
                        )
                        (   (vl-some '(lambda ( x ) (if (vl-every '= (cdr tmp) (cdr x)) (setq itm x))) lst)
                            (setq lst (subst (cons (+ (atoi (nth 0 tmp)) (car itm)) (cdr itm)) itm lst))
                        )
                        (   (setq lst (cons (cons (atoi (nth 0 tmp)) (cdr tmp)) lst)))
                    )
                )
                (setq lst
                    (mapcar
                        (function
                            (lambda ( x )
                                (list
                                    (nth 1 x)
                                    (nth 2 x)
                                    (itoa (nth 0 x))
                                    (nth 4 x)
                                    (rtos (* (nth 0 x) (distof (nth 4 x) 2)) 2 1)
                                    (rtos (* (nth 0 x) (distof (nth 4 x) 2) (cdr (assoc (substr (nth 2 x) 4) mlt))) 2 1)
                                )
                            )
                        )
                        lst
                    )
                )
                (null lst)
            )
            (princ "\nNão foram encontrados dados válidos.")
        )

I think everything is fine in the code, however it gives an error when it finds a decimal value such as 6.3 and 12.5. I dont know how to solve this. Thank you.

0 Likes
Message 9 of 13

dlanorh
Advisor
Advisor

Substitute the line in c:txt2tab1 to below and test.

(txt2tab:main '("^[0-9\.]+" "\\d+" "%%C\\d+" "C=" "\\d+\\.?\\d*") "E-B-TEXTOS")

and in txt2tab:main

( (< (atof (nth 0 tmp)) 1) (princ (strcat "\nO primeiro elemento (\"" (nth 0 tmp) "\") da string \"" str "\" não é um integral.")) )

 

I am not one of the robots you're looking for

0 Likes
Message 10 of 13

Anonymous
Not applicable

No. Dont work. Thank you.

0 Likes
Message 11 of 13

dlanorh
Advisor
Advisor
Accepted solution

Try this string

 

("^\\d+" "\\d+" "%%C\\d+\\.*\\d*" "C=" "\\d+\\.?\\d*")

Without a drawing or part drawing to test on, and without the (txt2tab:parsestring) function i'm only guessing, but this has something to do with finding a diameter and matching it against the weight list (var mlt). Since the third pattern of the 5 has "%%C" at the front, which is the diameter symbol i'm pretty sure we're in the right area, but i'm uncertain how greedy to make the pattern and whether this will break it for integers.

I am not one of the robots you're looking for

Message 12 of 13

DannyNL
Advisor
Advisor

Well, let me see:

- You get an error but do not share with us what the error is.

- You only provide part of your LISP code.

- You don't give any example drawing to test your code and debug the error.

 

There is only so much we can do with the information you provide and it's obvious the limit has been reached.

So if you want us to help you any further please provide your whole LISP code and an example drawing to debug your code. Everything else at this point with only the information provided in your earlier posts, is just shooting in the dark.

0 Likes
Message 13 of 13

Anonymous
Not applicable

dlanorh,

Thank you. Your last post solve the problem.

New version:

("^\\d+" "\\d+" "%%C\\d+\\.*\\d*" "C=" "\\d+\\.?\\d*")

Old version:

("^\\d+" "\\d+" "%%C\\d+" "C=" "\\d+\\.?\\d*")

 Here is the parsestring:

(defun txt2tab:parsestring ( rgx str lst / rtn tmp )
    (foreach pat lst
        (if (setq tmp (txt2tab:rgx:execute rgx str pat))
            (setq rtn (cons (substr str (1+ (caar tmp)) (strlen (cdar tmp))) rtn)
                  str (substr str (+ (caar tmp) (strlen (cdar tmp)) 1))
            )
            (setq rtn (cons "" rtn))
        )
    )
    (reverse rtn)
)
0 Likes