Jump to content

LISP to SUM attributes


Nickvnlr

Recommended Posts

I am looking for a LISP routine that will add the values of an attribute for the blocks selected.

I have a block called "PLANT" with an attribute "PLANTGPM".  I want to be able to select the blocks and total the values for this attribute to give me a "Total GPM".  

Thanks in advance!

Link to comment
Share on other sites

Try this:

(defun c:pp( / ss)
  (setq ss (ssget "_:L" '((0 . "INSERT")(2 . "PLANT")(66 . 1))) sum 0)
  (repeat (setq i (sslength ss))
    (setq b1 (ssname ss (setq i (1- i))))
    (while (and (/= (cdr (assoc 0 (setq b1l (entget b1)))) "SEQEND") (/= (cdr (assoc 2 b1l)) "PLANTGPM"))
      (setq b1 (entnext b1))
      )
    (setq n1 (read (cdr (assoc 1 b1l))) sum (+ sum n1))
    )
  )

Welcome in the Forum!

Link to comment
Share on other sites

Another but note check that attribute selected is a number/string a ABC will return 0.0.

 

Just pick the attribute in teh block that you want to sum then select all blocks etc.

 

(defun c:sumatt ( / att atts pt tagname bname obj sum)
(setq att (nentsel "\nPick the attrbute to sum "))
(setq pt (cadr att))
(setq tagname (cdr (assoc 2 (entget (car att)))))
(setq bname (cdr (assoc 2 (entget(ssname (ssget pt) 0)))))

(setq ss (ssget '((0 . "INSERT")(cons 2 bname)(cons 410 (getvar 'ctab))(66 . 1))))

(if (= ss nil)
(alert "no blocks match the criteria will skip ")
(progn
  (setq sum 0)
  (repeat (setq x (sslength ss))
  (setq obj (vlax-ename->vla-object (ssname ss (setq x (- x 1)))))
  (setq atts (vlax-invoke obj 'Getattributes))
  (foreach att atts
  	(if (= (vlax-get att 'tagstring) tagname)
  	(setq sum (+ (atof (vlax-get att 'Textstring)) sum))
  	)
  )
  )
  (alert (strcat "The total is " (rtos sum 2 2)))
)
)
(princ)
)
(c:sumatt)

 

Edited by BIGAL
Link to comment
Share on other sites

7 hours ago, BIGAL said:
(defum sumatt (...

 

Is this part right?  It wouldn't do anything until I changed it to:

(defun c:sumatt (...

Then I get an error : bad SSGET list

Link to comment
Share on other sites

8 hours ago, fuccaro said:

Try this:

(defun c:pp( / ss)
  (setq ss (ssget "_:L" '((0 . "INSERT")(2 . "PLANT")(66 . 1))) sum 0)
  (repeat (setq i (sslength ss))
    (setq b1 (ssname ss (setq i (1- i))))
    (while (and (/= (cdr (assoc 0 (setq b1l (entget b1)))) "SEQEND") (/= (cdr (assoc 2 b1l)) "PLANTGPM"))
      (setq b1 (entnext b1))
      )
    (setq n1 (read (cdr (assoc 1 b1l))) sum (+ sum n1))
    )
  )

Welcome in the Forum!

This doesn't seem to do anything.

 

Are there limitations on LISP in acadLT?  Maybe that is why I am having problems with this???

Thank you for the help!

Link to comment
Share on other sites

I never worked on LT, nor I have where to try it. In full AutoCAD I run the program and in the command line appeared the result.

Please give it one more try and after the lisp finishes, press F2 to switch to the text screen and post here what you see.

Link to comment
Share on other sites

Command: PP
Select objects: Specify opposite corner: 2 found
Select objects:  2

2 PLANT.jpg

Link to comment
Share on other sites

At the prompt "select objects" you selected those two blocks. After you pressed ENTER in the command line it says 2 - that's the sum.

Link to comment
Share on other sites

Ah.  I changed the values to get a better idea.  Thank you!  Of note:  It does not like decimal numbers without the leading zero, ie. ".41161".  It needs the leading zero "0.41161".

 

Thank you!

Link to comment
Share on other sites

Follow up; how would I get this to output a text field?

Thank you!

Link to comment
Share on other sites

I am at home now -here the local time is 9pm. Maybe tomorrow I will get some time... not sure

Link to comment
Share on other sites

Do you wish a text *field* or just a text? And where should this text (field?) appear on the drawing area?

Link to comment
Share on other sites

(defun c:pp( / ss)
  (setq ss (ssget "_:L" '((0 . "INSERT")(2 . "PLANT")(66 . 1))) sum 0)
  (repeat (setq i (sslength ss))
    (setq b1 (ssname ss (setq i (1- i))))
    (while (and (/= (cdr (assoc 0 (setq b1l (entget b1)))) "SEQEND") (/= (cdr (assoc 2 b1l)) "PLANTGPM"))
      (setq b1 (entnext b1))
      )
    (setq n1 (read (cdr (assoc 1 b1l))) sum (+ sum n1))
    )
(entmake (list '(0 . "TEXT") (cons 1 (strcat "Total GPM = " (rtos sum))) '(10 0.0 0.0 0.0)))
  )

This will place the text in the origin (I think...). Sorry, I can't test it right now.

Link to comment
Share on other sites

Just a text I suppose, using the current text style.  It should appear where placed (click).

Link to comment
Share on other sites

There was a typo in code did not spot it as tested code prior to adding defun note "n" not "m" as originally posted . Updated.

 

Add Text also included, uses style "Standard" with ht = 0.0

 

Note the (c:sumatt) as last line this will run the code when you load it, can then repeat by typing "sumatt"

Edited by BIGAL
Link to comment
Share on other sites

@Nickvnlr

Here I am with the Lisp. It also can handle that case you mentioned, when the real number starts with a dot.

Change the text height to suit your needs -see the 2nd program line.

(defun c:GPM( / ss textHeight i b1 b1l sum)
  (setq textHeight 1)
  (setq ss (ssget "_:L" '((0 . "INSERT")(2 . "PLANT")(66 . 1))) sum 0)
  (repeat (setq i (sslength ss))
    (setq b1 (ssname ss (setq i (1- i))))
    (while (and (/= (cdr (assoc 0 (setq b1l (entget b1)))) "SEQEND") (/= (cdr (assoc 2 b1l)) "PLANTGPM"))
      (setq b1 (entnext b1))
      )
    (setq sum (+ sum (atof (cdr (assoc 1 b1l)))))
    )
  (entmake (list '(0 . "TEXT") (cons 1 (strcat "Total GPM = " (rtos sum))) (cons 10 (getpoint "Pick text position")) (cons 40 textHeight)))
  )

 

  • Thanks 1
Link to comment
Share on other sites

This is very close.  It outputs the total as a measurement (ft-in).  I need just a plain decimal number.

 

Thank you!

total GPM.jpg

Link to comment
Share on other sites

Please find at the end of the program a call to RTOS function.

Replace (rtos sum) with (rtos sum 2)

  • Like 1
Link to comment
Share on other sites

(rtos sum 2 0) will return an integer answer

(rtos sum 2 2) will return a real answer with 2 decimal places

 

So second number controls decimal places.

  • Like 1
Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...