shakuhachi Posted May 15, 2011 Posted May 15, 2011 Hi guys, I'm stuck again and need your help. I want to multiply 2 numbers. How can I put the value on the drawing as dtext. When I use (defun Make_Text (pt str hgt) (entmakex (list (cons 0 "TEXT") (cons 10 pt) (cons 40 hgt) (cons 1 str)))) I get "bad DXF group: (1 . 348.0)" I also tried using vla-addText but still getting error message. Lee Mac's "Text Calculator" is great but I'm looking for a simple one which doesn't require me to add, subtract, multiple or divide the number. I just want to click 2 text and multiply them and prompt for the insertion point of the result. Thanks. Quote
Tharwat Posted May 15, 2011 Posted May 15, 2011 Hope this help . (defun c:sub (/ ss1 ss2 str) (if (and (setq ss1 (car (nentsel "\n First Text :"))) (setq ss2 (car (nentsel "\n Second text:"))) ) (progn (setq str (* (atof (cdr (assoc 1 (entget ss1)))) (atoi (cdr (assoc 1 (entget ss2)))) ) ) (entmakex (list (cons 0 "TEXT") (cons 40 (cdr (assoc 40 (entget ss1)))) (cons 1 (rtos str 2)) (cons 7 (cdr (assoc 7 (entget ss1)))) (cons 10 (trans (getpoint "\n Text Location :")1 0)) ) ) ) (princ "\n Missed Texts or no numbers found ") ) (princ) ) Tharwat Quote
Lee Mac Posted May 15, 2011 Posted May 15, 2011 Tharwat, This: (cons 40 (cdr (assoc 40 (entget ss1)))) Could be replaced with: (assoc 40 (entget ss1)) Same for Group 7. Quote
Tharwat Posted May 15, 2011 Posted May 15, 2011 Oops, my bad habit . Thank you Lee. Appreciated a lot. Quote
shakuhachi Posted May 15, 2011 Author Posted May 15, 2011 Thanks Tharwat and Lee. Works like a charm. Missed the rtos on str that's why I get an error. Quote
Tharwat Posted May 15, 2011 Posted May 15, 2011 You're welcome. Here is another in Visual Lisp . (defun c:Test (/ ss1 ss2 p str) ; Tharwat 15. 05. 2011 (vl-load-com) (or (setq acdoc (vla-get-modelspace (vla-get-ActiveDocument (vlax-get-acad-object)) ) ) ) (if (and (setq ss1 (car (entsel "\n First Text :"))) (setq ss2 (car (entsel "\n Second text:"))) (setq p (getpoint "\n Text Location :")) ) (progn (setq str (* (atoi (cdr (assoc 1 (entget ss1)))) (atoi (cdr (assoc 1 (entget ss2)))) ) ) (vla-addText acdoc (rtos str 2) (vlax-3d-point (trans p 1 0)) (cdr (assoc 40 (entget ss1))) ) ) (princ "\n Missed Texts or no numbers found ") ) (princ) ) Enjoy my friend . Tharwat Quote
Lee Mac Posted May 15, 2011 Posted May 15, 2011 I would be inclined to approach it this way, with a little more error trapping: ([color=BLUE]defun[/color] c:test ( [color=BLUE]/[/color] _select pr e1 e2 p1 no ) ([color=BLUE]defun[/color] _select ( msg pred func [color=BLUE]/[/color] e ) ([color=BLUE]setq[/color] pred ([color=BLUE]eval[/color] pred)) ([color=BLUE]while[/color] ([color=BLUE]progn[/color] ([color=BLUE]setvar[/color] 'ERRNO 0) ([color=BLUE]setq[/color] e ([color=BLUE]car[/color] (func msg))) ([color=BLUE]cond[/color] ( ([color=BLUE]=[/color] 7 ([color=BLUE]getvar[/color] 'ERRNO)) ([color=BLUE]princ[/color] [color=MAROON]"\n** Missed, Try again **"[/color]) ) ( ([color=BLUE]eq[/color] 'ENAME ([color=BLUE]type[/color] e)) ([color=BLUE]if[/color] ([color=BLUE]and[/color] pred ([color=BLUE]not[/color] (pred e))) ([color=BLUE]princ[/color] [color=MAROON]"\n** Invalid Object Selected **"[/color]) ) ) ) ) ) e ) ([color=BLUE]setq[/color] pr ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( x [color=BLUE]/[/color] e ) ([color=BLUE]and[/color] ([color=BLUE]wcmatch[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 0 ([color=BLUE]setq[/color] e ([color=BLUE]entget[/color] x)))) [color=MAROON]"TEXT,MTEXT,ATTRIB"[/color]) ([color=BLUE]distof[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 1 e))) ) ) ) no ([color=BLUE]trans[/color] '(0. 0. 1.) 1 0 [color=BLUE]t[/color]) ) ([color=BLUE]if[/color] ([color=BLUE]and[/color] ([color=BLUE]setq[/color] e1 (_select [color=MAROON]"\nSelect First Object: "[/color] pr [color=BLUE]nentsel[/color])) ([color=BLUE]setq[/color] e2 (_select [color=MAROON]"\nSelect Second Object: "[/color] pr [color=BLUE]nentsel[/color])) ([color=BLUE]setq[/color] p1 ([color=BLUE]getpoint[/color] [color=MAROON]"\nSelect Point for Result: "[/color])) ([color=BLUE]setq[/color] e1 ([color=BLUE]entget[/color] e1) e2 ([color=BLUE]entget[/color] e2) ) ) ([color=BLUE]entmakex[/color] ([color=BLUE]list[/color] ([color=BLUE]cons[/color] 0 [color=MAROON]"TEXT"[/color]) ([color=BLUE]assoc[/color] 40 e1) ([color=BLUE]cons[/color] 1 ([color=BLUE]rtos[/color] ([color=BLUE]*[/color] ([color=BLUE]distof[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 1 e1))) ([color=BLUE]distof[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 1 e2))) ) ) ) ([color=BLUE]assoc[/color] 7 e1) ([color=BLUE]cons[/color] 10 ([color=BLUE]trans[/color] p1 1 no)) ([color=BLUE]cons[/color] 50 ([color=BLUE]angle[/color] '(0. 0. 0.) ([color=BLUE]trans[/color] ([color=BLUE]getvar[/color] 'UCSXDIR) 0 no [color=BLUE]t[/color]) ) ) ([color=BLUE]cons[/color] 210 no) ) ) ) ([color=BLUE]princ[/color]) ) Since Tharwat's code will error if either the user selects an object that isn't text or fails to select a point, and will furthermore return zero if the text doesn't contain purely numerical content. My code will work in all UCS/Views but will still return an incorrect result for formatted MText - this issue is overcome in my Text Calculator program. Tharwat, I would ask the intention behind this code: (or (setq acdoc (vla-get-modelspace (vla-get-ActiveDocument (vlax-get-acad-object)) ) ) ) Why the 'OR'? and why name the variable 'acdoc' when the variable doesn't point to the Document? Quote
Tharwat Posted May 15, 2011 Posted May 15, 2011 Tharwat, I would ask the intention behind this code: (or (setq acdoc (vla-get-modelspace (vla-get-ActiveDocument (vlax-get-acad-object)) ) ) ) Why the 'OR'? and why name the variable 'acdoc' when the variable doesn't point to the Document? Actually you know much more better than me why it is a good idea to use *or* in this case to become like global variable name and if it is already invoked, the function *or* would consider it without repeating it each time a user invoke the routine . And for the name of the variable , for me it is not that important since it has the correct value that I use at the right place . and sometimes I used to name them as ( a , b , c .... and d) and so on , but because of a note that was given by Alan once before I have been trying to give the right name for the variable which describes its contents clearly . What you think ?. Tharwat Quote
Lee Mac Posted May 15, 2011 Posted May 15, 2011 Actually you know much more better than me why it is a good idea to use *or* in this case to become like global variable name and if it is already invoked, the function *or* would consider it without repeating it each time a user invoke the routine . Your use of OR is redundant in your code since the assigment of the variable 'acdoc' will occur every time. but because of a note that was given by Alan once before I have been trying to give the right name for the variable which describes its contents clearly . Exactly, it is good practice to use a variable name that describes the value it points to, hence why I questioned your use of 'acdoc'. Quote
Tharwat Posted May 15, 2011 Posted May 15, 2011 Your use of OR is redundant in your code since the assigment of the variable 'acdoc' will occur every time. Do you mean that *or* won't take an action since the name of the variable 'acdoc' is not localized which would cause the variable to be repeated to get the value and not to depend on function *or* ? Thanks. Quote
Lee Mac Posted May 15, 2011 Posted May 15, 2011 Do you mean that *or* won't take an action since the name of the variable 'acdoc' is not localized which would cause the variable to be repeatedto get the value and not to depend on function *or* ? No, the OR function continues to evaluate supplied arguments until an expression returns a non-nil value. In your case, there is only one expression to evaluate and hence it will always be evaluated. Quote
Tharwat Posted May 15, 2011 Posted May 15, 2011 Yeah .. that's it . Thank you for your time Lee . Appreciated Quote
shakuhachi Posted May 16, 2011 Author Posted May 16, 2011 Thanks for the both of you, especially to you Lee. You always save me when I'm in deep trouble. My goal for this simple routine is to multiply 2 values with the sample units. Given "12 METERS" multiply by "34 METERS" will give me the result "408 sq METERS". If I pick the first value with a METER unit, I will also need to pick the second item with a METER unit. If nil it will ask again to pick a text with a METER unit. I don't need to convert to CM to M since I use meters in different objects and probably use inch and feet as a unit. Thanks again. Quote
Tharwat Posted May 16, 2011 Posted May 16, 2011 Since Tharwat's code will error if either the user selects an object that isn't text or fails to select a point, and will furthermore return zero if the text doesn't contain purely numerical content. No more error or Zero or even Nil would return . (defun c:Test (/ ss1 ss2 e str1 str2) (while (if (not (and (setq ss1 (car (entsel "\n First Text please :"))) (setq str1 (distof (cdr (assoc 1 (setq e (entget ss1) ) ) ) ) ) ) ) (princ "\n Select Text with Numbers only ***** ") ) ) (while (if (not (and (setq ss2 (car (entsel "\n Second Text please :"))) (setq str2 (distof (cdr (assoc 1 (entget ss2) ) ) ) ) ) ) (princ "\n Select Text with Numbers only ***** ") ) ) (entmakex (list (cons 0 "TEXT") (assoc 40 e) (cons 1 (rtos (* str1 str2) 2)) (assoc 7 e) (cons 10 (trans (getpoint "\n Text Location :") 1 0)) ) ) (princ) ) Regards. TharwaT Quote
Lee Mac Posted May 16, 2011 Posted May 16, 2011 Will still error if the user fails to pick a point... Quote
Tharwat Posted May 16, 2011 Posted May 16, 2011 Will still error if the user fails to pick a point... Which point of them , ( the insertion point of the text) ? I have tried it many times without a piece of error . Quote
Lee Mac Posted May 16, 2011 Posted May 16, 2011 Command: test First Text please : Second Text please : Text Location : ; error: bad argument type: 2D/3D point: nil Quote
Tharwat Posted May 16, 2011 Posted May 16, 2011 I have not faced that in tow Cad versions at home 2009 and at the office 2010 as well . So if we bring the insertion point of Text Location to be included within the *IF* function , that would guarantee the insertion value of the text without any error . Agree ? Thanks Quote
Lee Mac Posted May 16, 2011 Posted May 16, 2011 I have not faced that in tow Cad versions at home 2009 and at the office 2010 as well . trans will error if the point supplied is nil: Command: (trans nil 1 0) ; error: bad argument type: 2D/3D point: nil 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.