Nikon Posted Friday at 11:44 AM Posted Friday at 11:44 AM Help me fix the errors. The division operation is not highlighted When selecting MTEXT, the code returns an error: invalid argument type: stringp nil. ;************************ (defun getNumericValue (ent / edata val str1 str3) (setq edata (entget ent)) (cond ;; TEXT ((equal (cdr (assoc 0 edata)) "TEXT") (setq val (cdr (assoc 1 edata)))) ;; MTEXT ((equal (cdr (assoc 0 edata)) "MTEXT") (setq str1 (cdr (assoc 1 edata))) (setq str3 (cdr (assoc 3 edata))) (setq val (strcat str1 str3)) ) (T (setq val "0") ) ) (atof val) ) ;***************** (defun c:CalcTwoTxt ( / lastOp prompt op ent1 ent2 v1 v2 result inspt validOps) (setq validOps '("*" "+" "-" "/")) (setq lastOp (getenv "CALC_TXT_LAST_OP")) (setq prompt (strcat "\nSelect an operation [*/+/-//] <" (if lastOp lastOp "") ">: ")) (setq op (getstring "\nSelect an operation [*/+/-//]: ")) (if (= op "") (setq op lastOp)) (if (not (member op validOps)) (progn (alert "An invalid operation. The operation is used \"+\".") (setq op "+") ) ) (setenv "CALC_TXT_LAST_OP" op) (setq ent1 (car (entsel "\nSelect the first text or MTEXT: "))) (if (null ent1) (exit)) (setq ent2 (car (entsel "\nSelect the second text or MTEXT: "))) (if (null ent2) (exit)) (setq v1 (getNumericValue ent1)) (setq v2 (getNumericValue ent2)) (cond ((= op "*") (setq result (* v1 v2))) ((= op "+") (setq result (+ v1 v2))) ((= op "-") (setq result (- v1 v2))) ((= op "/") (if (zerop v2) (setq result 0.0) (setq result (/ v1 v2)) ) ) (T (setq result 0.0)) ) (setq inspt (getpoint "\nSpecify the insertion point of the result: ")) (if (null inspt) (exit)) (command "_.TEXT" inspt "2.5" "0" (rtos result 2 2) "") (princ) ) Quote
GLAVCVS Posted Friday at 12:16 PM Posted Friday at 12:16 PM Hi Nikon Probably: '(cdr (assoc 3 edata))' is nil Quote
GLAVCVS Posted Friday at 12:19 PM Posted Friday at 12:19 PM Since it's not a text string and you want to concatenate it with '(cdr (assoc 1 edata))', it gets 'indigestible' and 'erupts': stringp nil' 1 Quote
Nikon Posted Friday at 12:23 PM Author Posted Friday at 12:23 PM On 3/21/2025 at 12:19 PM, GLAVCVS said: Since it's not a text string and you want to concatenate it with '(cdr (assoc 1 edata))', it gets 'indigestible' and 'erupts': stringp nil' Expand And how to write it correctly in the code? Quote
marko_ribar Posted Friday at 12:23 PM Posted Friday at 12:23 PM Whereever in the code occurs v1 or v2, change them to (atof v1) and (atof v2)... 1 1 Quote
GLAVCVS Posted Friday at 12:30 PM Posted Friday at 12:30 PM I see Marko probably already knows the problem and the solution. But if not, what do you hope to achieve with '(cdr (assoc 3 edata))'? Quote
Nikon Posted Friday at 12:45 PM Author Posted Friday at 12:45 PM On 3/21/2025 at 12:30 PM, GLAVCVS said: But if not, what do you hope to achieve with '(cdr (assoc 3 edata))'? Expand Most of the texts are stored in code group 1, but if they are longer than 250 characters, the additional text goes to code group 3. (setq str1 (cdr (assoc 1 edata))) (setq str3 (cdr (assoc 3 edata))) ; it can be nil if there are no additional lines. But I'm not sure if this is correct. Quote
GLAVCVS Posted Friday at 12:46 PM Posted Friday at 12:46 PM I think the quickest way to clarify this is to attach a drawing. Quote
Nikon Posted Friday at 12:52 PM Author Posted Friday at 12:52 PM (edited) On 3/21/2025 at 12:23 PM, marko_ribar said: Whereever in the code occurs v1 or v2, change them to ( atof v1) and (atof v2)... Expand error: syntax error ;************************ (defun getNumericValue (ent / edata val str1 str3) (setq edata (entget ent)) (cond ;; TEXT ((equal (cdr (assoc 0 edata)) "TEXT") (setq val (cdr (assoc 1 edata)))) ;; MTEXT ((equal (cdr (assoc 0 edata)) "MTEXT") (setq str1 (cdr (assoc 1 edata))) (setq str3 (cdr (assoc 3 edata))) (setq val (strcat str1 str3)) ) (T (setq val "0") ) ) (atof val) ) ;***************** (defun c:CalcTwoTxt ( / lastOp prompt op ent1 ent2 atof v1 atof v2 result inspt validOps) (setq validOps '("*" "+" "-" "/")) (setq lastOp (getenv "CALC_TXT_LAST_OP")) (setq prompt (strcat "\nSelect an operation [*/+/-//] <" (if lastOp lastOp "") ">: ")) (setq op (getstring "\nSelect an operation [*/+/-//]: ")) (if (= op "") (setq op lastOp)) (if (not (member op validOps)) (progn (alert "An invalid operation. The operation is used \"+\".") (setq op "+") ) ) (setenv "CALC_TXT_LAST_OP" op) (setq ent1 (car (entsel "\nSelect the first text or MTEXT: "))) (if (null ent1) (exit)) (setq ent2 (car (entsel "\nSelect the second text or MTEXT: "))) (if (null ent2) (exit)) (setq (atof v1) (getNumericValue ent1)) (setq (atof v2) (getNumericValue ent2)) (cond ((= op "*") (setq result (* (atof v1) (atof v2)))) ((= op "+") (setq result (+ (atof v1) (atof v2)))) ((= op "-") (setq result (- (atof v1) (atof v2)))) ((= op "/") (if (zerop (atof v2)) (setq result 0.0) (setq result (/ (atof v1) (atof v2))) ) ) (T (setq result 0.0)) ) (setq inspt (getpoint "\nSpecify the insertion point of the result: ")) (if (null inspt) (exit)) (command "_.TEXT" inspt "2.5" "0" (rtos result 2 2) "") (princ) ) Edited Friday at 04:45 PM by Nikon (atof v1) (atof v2) Quote
Nikon Posted Friday at 12:54 PM Author Posted Friday at 12:54 PM On 3/21/2025 at 12:46 PM, GLAVCVS said: I think the quickest way to clarify this is to attach a drawing. Expand I have simple operations with numbers, the drawing will not clarify anything. Quote
GLAVCVS Posted Friday at 01:14 PM Posted Friday at 01:14 PM On 3/21/2025 at 12:54 PM, Nikon said: Tengo operaciones sencillas con números, el dibujo no me aclara nada. Expand Quote
marko_ribar Posted Friday at 03:59 PM Posted Friday at 03:59 PM Nikon, you forgot to add open and closing brackets for v1 and v2... Like I said it should be : (atof v1) and (atof v2)... 1 1 Quote
Nikon Posted Friday at 04:46 PM Author Posted Friday at 04:46 PM (edited) On 3/21/2025 at 3:59 PM, marko_ribar said: Nikon, you forgot to add open and closing brackets for v1 and v2... Like I said it should be : (atof v1) and (atof v2)... Expand Unfortunately, error: syntax error Edited Friday at 04:47 PM by Nikon Quote
Steven P Posted Friday at 05:26 PM Posted Friday at 05:26 PM In numerical functions, this: ;; TEXT ((equal (cdr (assoc 0 edata)) "TEXT") (setq val (cdr (assoc 1 edata)))) ;; MTEXT ((equal (cdr (assoc 0 edata)) "MTEXT") (setq str1 (cdr (assoc 1 edata))) (setq str3 (cdr (assoc 3 edata))) (setq val (strcat str1 str3)) ) could probably be just ;; TEXT ((equal (cdr (assoc 0 edata)) "*TEXT") (setq val (cdr (assoc 1 edata))) ) reason being in text. assoc 3 comes into things if the text string is over 256 characters long... which is a very very big number. 1 Quote
Steven P Posted Friday at 10:15 PM Posted Friday at 10:15 PM (edited) Cold try this as a modification, keeping your method: Putting getNumericValue as a subroutine (I find that better for these forum LISPs, copy and paste 1 routine rather than several), getNumericValue altered. I didn't test for mtexts numbers over 256 characters - it should work if you really really want to. Changed the order in the main routine a bit, calculates and reports the value of the 'v's just after selection - handy to have a confirmation of the selected value just after selection Works in my quick tests (defun c:CalcTwoTxt ( / lastOp prompt op ent1 ent2 v1 v2 result inspt validOps) (defun getNumericValue (ent / edata val str1 str3) (setq edata (entget ent)) (setq val 0) (if (or (equal (cdr (assoc 0 edata)) "TEXT")(equal (cdr (assoc 0 edata)) "MTEXT")) (progn (setq val (cdr (assoc 1 edata))) (if (assoc 3 edata) (setq val (strcat str1 str3))) ) ; end progn ) (princ val) (atof val) ) (setq validOps '("*" "+" "-" "/")) (setq lastOp (getenv "CALC_TXT_LAST_OP")) (setq prompt (strcat "\nSelect an operation [*/+/-/\/] <" (if lastOp lastOp "") ">: ")) (setq op (getstring "\nSelect an operation [*/+/-/]: ")) (if (= op "") (setq op lastOp)) (if (not (member op validOps)) (progn (alert "An invalid operation. The operation is used \"+\".") (setq op "+") ) ) (setenv "CALC_TXT_LAST_OP" op) (setq ent1 (car (entsel "\nSelect the first text or MTEXT: "))) (if (null ent1) (exit)) (setq v1 (getNumericValue ent1)) (setq ent2 (car (entsel "\nSelect the second text or MTEXT: "))) (if (null ent2) (exit)) (setq v2 (getNumericValue ent2)) (cond ((= op "*") (setq result (* v1 v2))) ((= op "+") (setq result (+ v1 v2))) ((= op "-") (setq result (- v1 v2))) ((= op "/") (if (zerop v2) (setq result 0.0) (setq result (/ v1 v2)) ) ) (T (setq result 0.0)) ) (setq inspt (getpoint "\nSpecify the insertion point of the result: ")) (if (null inspt) (exit)) (command "_.TEXT" inspt "2.5" "0" (rtos result 2 2) "") (princ) ) Edited Saturday at 09:39 PM by Steven P 1 Quote
Tsuky Posted Saturday at 12:20 AM Posted Saturday at 12:20 AM (edited) My way, if can be a pleasure... (defun ExtractNumber (str / l rslt) (setq l (mapcar '(lambda (x) (if (and (> x 44) (< x 58) (/= x 47)) x 32) ) (vl-string->list str) ) l (mapcar '(lambda (x y) (if (not (= x y 32)) x) ) l (append (cdr l) '(32)) ) l (vl-remove-if-not '(lambda (x) (eq (type x) 'INT) x) l) l (mapcar '(lambda (x) (if (not (eq x 32)) x (list nil))) l) ) (eval (read (strcat "(setq rslt (list " (apply 'strcat (mapcar '(lambda (x) (if (not (listp x)) (chr x) " ")) l)) "))"))) ) (defun c:CalcTwoTxt ( / ss1 ss2 val1 val2 op rslt inspt) (princ "\nSelect first text") (while (not (setq ss1 (ssget "_+.:E:S" '((0 . "*TEXT")))))) (princ "\nSelect second text") (while (not (setq ss2 (ssget "_+.:E:S" '((0 . "*TEXT")))))) (setq val1 (extractnumber (cdr (assoc 1 (entget (ssname ss1 0)))))) (setq val2 (extractnumber (cdr (assoc 1 (entget (ssname ss2 0)))))) (cond ((and val1 val2) (initget "* + - /") (setq op (getkword "\nSelect an operation [*/+/-/\/]? <+>: ")) (if (not op) (setq op "+")) (if (and (eq op "/") (member 0 val2)) (setq rslt 0.0) (setq rslt (apply (read op) (append val1 val2))) ) (initget 1) (setq inspt (getpoint "\nSpecify the insertion point of the result: ")) (command "_.TEXT" inspt "2.5" "0" (rtos rslt 2 2)) ) (T (princ "\No value found in text")) ) (prin1) ) NB:The extractnumber function recovers all the digital values contained in a text in the form of a list exemple: (extractnumber "area floor = 45.60m², length 12.56m heigth = 2.12m") -> (45.6 12.56 2.12) Edited Saturday at 12:33 AM by Tsuky 1 Quote
Nikon Posted Saturday at 06:47 AM Author Posted Saturday at 06:47 AM (edited) On 3/22/2025 at 12:20 AM, Tsuky said: My way, if can be a pleasure... Expand @Tsuky HUGE thank. The division operation is active, but there is one drawback. Dividing a smaller number by a larger one gives 0. For example, 5/10=0 or 5/550=0... decimal division works fine 05./50.5=0.9. ??? Is it possible to remember the last choice of operation? Edited Saturday at 07:08 AM by Nikon Quote
Nikon Posted Saturday at 03:57 PM Author Posted Saturday at 03:57 PM On 3/21/2025 at 10:15 PM, Steven P said: Cold try this as a modification, keeping your method: Putting getNumericValue as a subroutine (I find that better for these forum LISPs, copy and paste 1 routine rather than several), getNumericValue altered. I didn't test for mtexts numbers over 256 characters - it should work if you really really want to. Changed the order in the main routine a bit, calculates and reports the value of the 'v's just after selection - handy to have a confirmation of the selected value just after selection Works in my quick tests Expand For some reason, the code gives an error... ; error: incorrectly generated list at the entrance Quote
Steven P Posted Saturday at 09:39 PM Posted Saturday at 09:39 PM think I left in something I was trying - edited now 1 Quote
Nikon Posted Sunday at 05:53 AM Author Posted Sunday at 05:53 AM On 3/22/2025 at 9:39 PM, Steven P said: think I left in something I was trying - edited now Expand Unfortunately, I can't check the code, the same error. ; error: incorrectly generated list at the entrance Quote
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.