Count quantities and export to excel file

Count quantities and export to excel file

Egbay
Contributor Contributor
2,021 Views
13 Replies
Message 1 of 14

Count quantities and export to excel file

Egbay
Contributor
Contributor

Hello,

 

I would like to have a lisp that counts the "Items" that cross/is within the "Group" block. User should be able to decide if you want to select an area with the window selection or just the whole drawing. It should be able to read attributes to help with determining quantities. For example, Group.1.1 has the same 4 blocks named "Item 1", attribute tag is "Size" with a value of "3". So Group.1.1 has 4 blocks of size 3. Screenshot provided for visual. If there isn't a block with a certain attribute tag then it can be 0 or just be left blank.

 

Let me know if there is more clarification needed on my end.

0 Likes
2,022 Views
13 Replies
Replies (13)
Message 3 of 14

Egbay
Contributor
Contributor

Those two look like they are counting the total number of each block. I'm looking to see how much of each item is grouped together by this orange group block.

Egbay_1-1685733725803.png

I was also having a hard time trying to get the code in the second link to run. Not familiar with .net

 

 

 

 

0 Likes
Message 4 of 14

Sea-Haven
Mentor
Mentor

Can be done but need to think about it, you have count blocks so that part is done, to get each group count need to select the objects that are Group Dynamic blocks.

 

This is 1st go need to find out why the groupname is not coming out.

(defun c:wow ( / effn lst lst2 obj grpatts grpatt pointmin pointmax)
(setq effn "GROUP")
(setq ssd (ssget "X" (list (cons 0 "INSERT")(cons 2 "*U*"))))
(setq lst '() )
(repeat (setq x (sslength ssd))
  (setq obj (vlax-ename->vla-object (ssname ssd (setq x (1- x)))))
  (setq effn (vla-get-effectivename obj))
  (setq Grpatts (vlax-invoke obj 'Getattributes))
  (foreach grpatt grpatts
  (if (= (vla-get-tagstring grpatt) "GROUPNUM")
  (setq grp (vla-get-textstring grpatt))
  )
  )
  (setq lst2 '())
  (if (= effn "Group")
  (progn
    (vla-GetBoundingBox obj 'minpoint 'maxpoint)
    (setq pointmin (vlax-safearray->list minpoint))
    (setq pointmax (vlax-safearray->list maxpoint))

    (setq ss (ssget "F" (list pointmin pointmax) (list (cons 0 "INSERT")(cons 2 "ITEM*"))))
	(repeat (setq k (sslength ss))
	(setq atts (vlax-invoke (vlax-ename->vla-object (ssname ss (setq k (1- k)))) 'Getattributes))
	(setq lst2 (cons (list (vla-get-textstring (nth 0 atts)) grp) lst2))
    )
   )
   )
   (setq lst (cons lst2 lst))
)
(princ)
)

Count lst.

 

Message 5 of 14

hosneyalaa
Advisor
Advisor

My language is not good
Do you want After selecting all items

 to group all 4 items into a group

or
A group can contain more than 4 items


then
Extract some properties to Excel

 

 

q.JPG

0 Likes
Message 6 of 14

Egbay
Contributor
Contributor

A group can contain more that 4 items. My file should of had more variations sorry about that. @hosneyalaa @Sea-Haven I was able to find a lisp that one of my ex coworkers was working on that may be of some help. I believe he got help putting it together because I know he didnt have much experience with code. The problem that occurs with this is that when the group block is at the end of the items it is short one item. I attached the lisp, resulting output .csv and updated text.dwg that now has 5 items in group 1.3

0 Likes
Message 7 of 14

Sea-Haven
Mentor
Mentor

Did you try what I posted ? It is a start the 1st step.

 

It will find any amount that the Group block covers and do each insert separately. 

0 Likes
Message 8 of 14

hosneyalaa
Advisor
Advisor

@Egbay  hi

try

 

(vl-load-com) ; loads visual lisp

(defun c:GroupData ( / A B C ENTITY F G I J L M N OBJECT POINTMAX POINTMAXC POINTMIN SELSET X Y Z)   ;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/count-quantities-and-export-to-excel-file/td-p/12007741
  
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break,end"))
      (princ (strcat "\nError: " errmsg)))
    (if f (close f))
    (princ))
  
  (if (setq selset (ssget "_X" '((0 . "INSERT") (8 . "Grouping Block") ))) ; selects all and filters out things that are not blocks 
    (repeat (setq i (sslength selset)) ; get number of items in selection set
      (if (and (setq entity (ssname selset (setq i (1- i)))) ; iterates i and gets ith entity in selection set
	       (= "Group" (getpropertyvalue entity "BlockTableRecord/Name"))
	       (setq object (vlax-ename->vla-object entity)) ; converts entity into vla-object
	       (vlax-method-applicable-p object 'getboundingbox) ; determines if object supports a bounding box
	       (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list object 'a 'b))))
;;;	       (setq p (mapcar 'vlax-safearray->list (list a b)))
	       (setq pointmin (vlax-safearray->list a))
               (setq pointmax (vlax-safearray->list b))
	       (setq pointmaxc (list (car pointmax ) (cadr pointmin )))  
	       
	       
	       (setq z (ssget "_F" (list pointmin pointmaxc) '((0 . "INSERT") (8 . "Items"))))
	       (setq n (getpropertyvalue entity "GROUPNUM"))
	       )
	(repeat (setq j (sslength z))
	  (and (setq g (ssname z (setq j (1- j))))
	       (wcmatch (getpropertyvalue g "BlockTableRecord/Name") "~Item")
	       (not (vl-catch-all-error-p (setq c (vl-catch-all-apply 'getpropertyvalue (list g "Size")))))
	       (setq m (if (vl-position c m) m (cons c m)))
	       (setq l (if (setq a (assoc n l))
			 (subst (cons n (if (setq b (assoc c (cdr a)))
					  (subst (cons c (1+ (cdr b)))
						 b
						 (cdr a))
					  (cons (cons c 1) (cdr a))))
				a
				l)
			 (cons (list n (cons c 1)) l))))  ;;;  (and

	  );;;; (repeat


	))  ;;;; (repeat

    )

   (if l
     (progn

       (setq m (vl-sort m '<))
       (setq l (mapcar '(lambda (x) (cons (car x) (mapcar '(lambda (y / a) (if (setq a (assoc y (cdr x))) (itoa (cdr a)) "0")) m)))
		       (vl-sort l '(lambda (e1 e2) (< (car e1) (car e2))))))
       (setq n (strcat (getvar 'DWGPREFIX) (vl-string-right-trim ".dwg" (getvar 'dwgname)) ".csv"))
       (setq f (open n "a"))
       (write-line (write-line (strcat "GROUPNUM" (apply 'strcat (mapcar '(lambda (x) (strcat ",QTY OF BLOCKS WITH A SIZE " x)) m)))) f)
       (foreach entity l (write-line (write-line (substr (apply 'strcat (mapcar '(lambda (x) (strcat "," x)) entity)) 2)) f))
       (close f)
       
       (startapp "explorer" n)
       )
     )
  
  (princ)
  )

 

 

99.gif

0 Likes
Message 9 of 14

Egbay
Contributor
Contributor

I just tried it now and I got this error

Egbay_0-1685978911479.png

 

I also tried what @hosneyalaa added and it looks like it worked for me. I believe there were other instances where it was not counting the correct number of items. I need to think back and see what those may have been and try the code there. If it all works then Ill accept the answer.

 

I do appreciate all the help up to this point. Thank you

0 Likes
Message 10 of 14

Egbay
Contributor
Contributor

So after having myself and coworker try it out there are two things:

 

  1. If we are to run the program multiple times and the .dwg and .csv remain in the same location then the program just continues adding the .csv. Would need it to overwrite the .csv so there is only one instance showing.
  2. Coworker had multiple "Group" blocks ex "Group1" "Group2" because in some instances the block was not perfectly horizontal so he created a similar blocks but at an angle. Can it be made so "Group#" where # is any number be picked up and added to the .csv?
0 Likes
Message 11 of 14

hosneyalaa
Advisor
Advisor

@Egbay wrote:

So after having myself and coworker try it out there are two things:

 

  1. If we are to run the program multiple times and the .dwg and .csv remain in the same location then the program just continues adding the .csv. Would need it to overwrite the .csv so there is only one instance showing.
  2. Coworker had multiple "Group" blocks ex "Group1" "Group2" because in some instances the block was not perfectly horizontal so he created a similar blocks but at an angle. Can it be made so "Group#" where # is any number be picked up and added to the .csv?

CAN YOU ATTACHED  DRAWING ( some instances the block was not perfectly horizontal  )

0 Likes
Message 12 of 14

Egbay
Contributor
Contributor

I edited the previous Test.dwg to get something similar but I cant get you the file my coworker was using. Groups 1.1-1.3 the block is named Group and 1.4 block is named Group2. Not sure if it being at an angle mattered but from what he mentioned to me it can be that all the items within the Group blocks were picked up but no items within the Group2 would not be counted.

0 Likes
Message 13 of 14

hosneyalaa
Advisor
Advisor

 

test

 

(vl-load-com)                                     ; loads visual lisp

(defun c:GroupData (/      A      B      C      ENTITY F      G
                    I      J      L      M      N      OBJECT POINTMAX
                    POINTMAXC     POINTMIN      SELSET X      Y
                    Z
                   )
  (defun *error* (errmsg)
    (if
      (not
        (wcmatch errmsg
                 "Function cancelled,quit / exit abort,console break,end"
        ) ;_ end of wcmatch
      ) ;_ end of not
       (princ (strcat "\nError: " errmsg))
    ) ;_ end of if
    (if f
      (close f)
    ) ;_ end of if
    (princ)
  ) ;_ end of defun

  (if (setq selset (ssget "_X" '((0 . "INSERT"))))
    (repeat (setq i (sslength selset))            ; get number of items in selection set
      (if (and (setq entity (ssname selset (setq i (1- i))))
                                                  ; iterates i and gets ith entity in selection set
               (or (= "Group2"
                      (getpropertyvalue entity "BlockTableRecord/Name")
                   ) ;_ end of =
                   (= "Group"
                      (getpropertyvalue entity "BlockTableRecord/Name")
                   ) ;_ end of =
               ) ;_ end of or

               (setq object (vlax-ename->vla-object entity))
                                                  ; converts entity into vla-object
               (vlax-method-applicable-p object 'getboundingbox)
                                                  ; determines if object supports a bounding box
               (not (vl-catch-all-error-p
                      (vl-catch-all-apply
                        'vla-getboundingbox
                        (list object 'a 'b)
                      ) ;_ end of vl-catch-all-apply
                    ) ;_ end of vl-catch-all-error-p
               ) ;_ end of not
;;;	       (setq p (mapcar 'vlax-safearray->list (list a b)))
               (setq pointmin (vlax-safearray->list a))
               (setq pointmax (vlax-safearray->list b))
               (setq pointmaxc (list (car pointmax) (cadr pointmin)))


               (setq z (ssget "_F"
                              (list pointmin pointmaxc)
                              '((0 . "INSERT") (8 . "Items"))
                       ) ;_ end of ssget
               ) ;_ end of setq
               (setq n (getpropertyvalue entity "GROUPNUM"))
          ) ;_ end of and
        (repeat (setq j (sslength z))
          (and (setq g (ssname z (setq j (1- j))))
               (wcmatch (getpropertyvalue g "BlockTableRecord/Name")
                        "~Item"
               ) ;_ end of wcmatch
               (not (vl-catch-all-error-p
                      (setq c (vl-catch-all-apply
                                'getpropertyvalue
                                (list g "Size")
                              ) ;_ end of vl-catch-all-apply
                      ) ;_ end of setq
                    ) ;_ end of vl-catch-all-error-p
               ) ;_ end of not
               (setq m (if (vl-position c m)
                         m
                         (cons c m)
                       ) ;_ end of if
               ) ;_ end of setq
               (setq l (if (setq a (assoc n l))
                         (subst (cons n
                                      (if (setq b (assoc c (cdr a)))
                                        (subst (cons c (1+ (cdr b)))
                                               b
                                               (cdr a)
                                        ) ;_ end of subst
                                        (cons (cons c 1) (cdr a))
                                      ) ;_ end of if
                                ) ;_ end of cons
                                a
                                l
                         ) ;_ end of subst
                         (cons (list n (cons c 1)) l)
                       ) ;_ end of if
               ) ;_ end of setq
          ) ;_ end of and
;;;  (and

        ) ;_ end of repeat
;;;; (repeat


      ) ;_ end of if
    ) ;_ end of repeat
;;;; (repeat

  ) ;_ end of if

  (if l
    (progn

      (setq m (vl-sort m '<))
      (setq
        l (mapcar '(lambda (x)
                     (cons (car x)
                           (mapcar '(lambda (y / a)
                                      (if (setq a (assoc y (cdr x)))
                                        (itoa (cdr a))
                                        "0"
                                      ) ;_ end of if
                                    ) ;_ end of lambda
                                   m
                           ) ;_ end of mapcar
                     ) ;_ end of cons
                   ) ;_ end of lambda
                  (vl-sort l '(lambda (e1 e2) (< (car e1) (car e2))))
          ) ;_ end of mapcar
      ) ;_ end of setq
      (setq n (strcat (getvar 'DWGPREFIX)
                      (vl-string-right-trim ".dwg" (getvar 'dwgname))
                      ".csv"
              ) ;_ end of strcat
      ) ;_ end of setq
       (findfile n)
       


          (setq f (open n "w"))
          (write-line
            (write-line
              (strcat
                "GROUPNUM"
                (apply
                  'strcat
                  (mapcar '(lambda (x)
                             (strcat ",QTY OF BLOCKS WITH A SIZE " x)
                           ) ;_ end of lambda
                          m
                  ) ;_ end of mapcar
                ) ;_ end of apply
              ) ;_ end of strcat
            ) ;_ end of write-line
            f
          ) ;_ end of write-line
          (foreach entity l
            (write-line
              (write-line
                (substr
                  (apply 'strcat
                         (mapcar '(lambda (x) (strcat "," x)) entity)
                  ) ;_ end of apply
                  2
                ) ;_ end of substr
              ) ;_ end of write-line
              f
            ) ;_ end of write-line
          ) ;_ end of foreach
          (close f)

          (startapp "explorer" n)
       
      ) ;_ end of if
    ) ;_ end of progn

    (princ)

) ;_ end of defun
;|«Visual LISP© Format Options»
(72 2 50 2 T "end of " 60 9 1 0 0 nil T nil T)
;*** DO NOT add text below the comment! ***|;

 

 

 

Capture9.JPG

 

0 Likes
Message 14 of 14

Egbay
Contributor
Contributor

It is working after a couple a test runs. When coworker gets back form vacation Ill see if he is still having issues.

 

Just to make sure I am understanding the code, in the code section attached, whoever is using this lisp would need to update depending on how many "Group" blocks there are right? So if this had a group3 and group4 it would need to be added in.

 

I dont anticipate a large number of variations but just want to have the understanding. To me it seems like the top part would count how many "Groups" there are and iterate through. I could just be understanding it incorrectly though. I haven't done much lisp programming but know some C and C++ through school.

 

code snip.png

0 Likes