Author Topic: Counting Blocks  (Read 19709 times)

0 Members and 1 Guest are viewing this topic.

Luke

  • Guest
Counting Blocks
« on: April 09, 2007, 05:39:49 PM »
I've tried this before and was having a difficult time getting the results I was hoping for.

I am using Vanilla AutoCAD 2008 Full Version.

I am doing some drawings that require the use of several hundres "icons".  These "icons" are blocks that represent a fixture to be used on the floor plan.  I want AutoCAD to count all of the blocks for me.  Now I know I can export the information to different types of external files but I do not want to do that.  I want my drawing and the table to all be contained on the same paper so I can send 1 pdf to my installers.  What I would like to do is put the information, the table right there on my drawing, with a picture of the icon or block and a description and a count.  That way it will work as a legend and as a very basic Bill of Material.  I have figured out how to get the "data Extraction" to initially count my blocks but I am having trouble getting the qty to update with any changes.  For example if I insert 3 of block "Widget-B" and create the table and then add 2 more of "widget-b" tomorrow I thought there is a way to get the table to update rather than completely regenerating it.  Problem is I'm not having much luck getting it to happen. 

Any help or suggestions directly relating to this topic would be greatly appreciated.

Thanks in advance

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Counting Blocks
« Reply #1 on: April 09, 2007, 06:11:40 PM »
Just  a guess ... is there a 'field' you can use that keeps a count of blocks in the dwg?
TheSwamp.org  (serving the CAD community since 2003)

Luke

  • Guest
Re: Counting Blocks
« Reply #2 on: April 10, 2007, 12:36:10 PM »
OK sure that is what I was hoping.  Can you tell me what the field is?

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Counting Blocks
« Reply #3 on: April 10, 2007, 02:40:40 PM »
I didn't find a specific field but I do have something that will work, of course it involves lisp.

1. Insert field of DIESEL expression $(getenv, blk_count)
2. Load the following AutoLISP app and run it every time you want to update your block count.

Code: [Select]
(defun c:recount ( / cnt )
  (if
    (setq cnt (itoa (sslength (ssget "x" '((0 . "INSERT")(2 . "<block name>"))))))
    (setenv "blk_count" cnt)
    )
  )

3. Run 'updatefield' and select your table.
TheSwamp.org  (serving the CAD community since 2003)

Luke

  • Guest
Re: Counting Blocks
« Reply #4 on: April 10, 2007, 02:43:11 PM »
I've never used Diesel at all but do enough lisping to be dangerous.  I'll give this a try, hopefully this evening.  Thanks for you help.

deegeecees

  • Guest
Re: Counting Blocks
« Reply #5 on: April 10, 2007, 03:24:58 PM »
If you have Express Tools (I may be getting off the wrong train here) you could use "bcount". Try typing it in the command line.

Luke

  • Guest
Re: Counting Blocks
« Reply #6 on: April 10, 2007, 03:38:23 PM »
please explain how to get that information yielded by 'bcount" into a table or list that will show up on my drawing and can be easily updated.

I think Mark is on the right track I just need to get a free minute to try his suggestion.

deegeecees

  • Guest
Re: Counting Blocks
« Reply #7 on: April 10, 2007, 03:48:52 PM »
All I know is the "old school" method using attributes and Lisp, dont wanna gum up the issue at hand...

Luke

  • Guest
Re: Counting Blocks
« Reply #8 on: April 10, 2007, 04:03:59 PM »
Mark,
In the code you supplied, do I need to identify the name(s) of each of my blocks somewhere?

Luke

  • Guest
Re: Counting Blocks
« Reply #9 on: April 10, 2007, 04:06:47 PM »
Sorry, I see it now.

Luke

  • Guest
Re: Counting Blocks
« Reply #10 on: April 10, 2007, 04:17:46 PM »
OK Mark. I've got it partially working.  What would my code look like for 4 or 5 different blocks?  I've got it working for a single block but do not know how to change the code properly to work for multiples. 

Or would I have to have a different diesel expression and different lisp for each block?  Sure hope not but will do if necessary.

Thanks,
Luke

Crank

  • Water Moccasin
  • Posts: 1503
Re: Counting Blocks
« Reply #11 on: April 11, 2007, 02:24:50 AM »
Mark, that is fantastic!

Never noticed before that diesel also can be used in fields.
Vault Professional 2023     +     AEC Collection

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Counting Blocks
« Reply #12 on: April 11, 2007, 10:11:53 AM »
Or would I have to have a different diesel expression and different lisp for each block?

You'll have to have a different diesel expression for each block, I don't see anyway around that.

Here's the code that handles multiple blocks.

Code: [Select]
(defun c:recount (/ block_list cnt env_name)

  ;; The intent of this app is to count the number of blocks inserted into
  ;; a given dwg and set environment variables based on the block name so
  ;; one can use the diesel expression '$(getenv, <name>)' in a table cell
  ;; to track the number of block insertitions therein
  ;;
  ;; Typical output
  ;;
  ;; Set BLOCK_COUNT_ELM to 6
  ;; Set BLOCK_COUNT_CITRUS to 5
  ;; Set BLOCK_COUNT_OAK to 11
  ;; Set BLOCK_COUNT_PALM to 5
  ;;
  ;; Given the above output you would use '$(getenv, BLOCK_COUNT_OAK)' in
  ;; your table cell
  ;;
  ;; version 1.0
  ;; Wed Apr 11, 2007
  ;; Mark S. Thomas ( mark@theswamp.org )

  ;
  ; list of blocks you wish to count
  ;
  (setq block_list
        (list
          ;
          ; add a line for each block you wish to count
          ; the following are just samples
          ;
          (cons '2 "ELM")
          (cons '2 "CITRUS")
          (cons '2 "OAK")
          (cons '2 "PALM")
          )
        )


  (foreach i block_list
           (if
             (setq ss (ssget "X" (list '(0 . "INSERT") i)))
             (progn
               (setq
                 ;
                 ; count the number of blocks inserted
                 ; create the environment name, i.e. "BLOCK_COUNT_ELM"
                 ;
                 cnt (itoa (sslength ss))
                 env_name (strcat "BLOCK_COUNT_" (cdr i))
                 )

               ; finally we set the environment variable
               (setenv env_name cnt)

               ; show the user what was set and how many blocks were counted
               (princ (strcat "\nSet " env_name " to " cnt))
               )
             )
           )
  (princ)
  )

This is the block I used for testing.

TheSwamp.org  (serving the CAD community since 2003)

Luke

  • Guest
Re: Counting Blocks
« Reply #13 on: April 11, 2007, 10:47:34 AM »
Mark,
Perfect! This is doing exactaly what I want.  And your comments in the code help me understand what is going on so next time I can give it a shot on my own.

Thanks so much!

So one final question.  Right now doing this in a table it does not count the block in the table.  Great, just what I want, but If I wanted to do this as just a list (so no gird or headaches of a table show up) it would count the block in the list resulting in 1 too many.  Is there a way to tell the lisp to subtract 1 from the total?

OK now I'm done bothering you.  Thanks a ton for your help!

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Counting Blocks
« Reply #14 on: April 11, 2007, 11:02:53 AM »
Is there a way to tell the lisp to subtract 1 from the total?

Try changing the line ...

Code: [Select]
cnt (itoa (sslength ss))
to ...

Code: [Select]
cnt (1- (itoa (sslength ss)))
TheSwamp.org  (serving the CAD community since 2003)

Guest

  • Guest
Re: Counting Blocks
« Reply #15 on: April 11, 2007, 11:04:15 AM »
Luke: you can turn off the borders of the table so you don't see the individual cells.

ML

  • Guest
Re: Counting Blocks
« Reply #16 on: April 11, 2007, 11:19:38 AM »

I may be repeating something that has already been mentioned in this post but I tried bcount and it is really cool but I noticed that it only seems to address Block (inserted) references but it does seem to break them down between paper and Model. It does not seem to address Block Definitions.

I have a VBA module I would be glad to share if it would help anyone.

It gives you Block references in Model, Paper and Block Table Definitions in the drawing.

Mark

Luke

  • Guest
Re: Counting Blocks
« Reply #17 on: April 11, 2007, 12:08:48 PM »
Mark,

The code:
cnt (1- (itoa (sslength ss)))

Results in the following:
ERROR: bad argument type: numberp: "3"

Any thoughts?



ML

  • Guest
Re: Counting Blocks
« Reply #18 on: April 11, 2007, 12:11:58 PM »

Not sure Luke, sorry  :-(

Luke

  • Guest
Re: Counting Blocks
« Reply #19 on: April 11, 2007, 12:16:59 PM »
Sorry, I was hoping Mark Thomas who gave me the code might be able to help. 

Thanks,
Luke

ML

  • Guest
Re: Counting Blocks
« Reply #20 on: April 11, 2007, 12:19:07 PM »

What is the code suppose to do?

Mark

Luke

  • Guest
Re: Counting Blocks
« Reply #21 on: April 11, 2007, 12:19:58 PM »
ML, not sure if you read any of the posting above this but it pretty much explains it all in great detail.

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Counting Blocks
« Reply #22 on: April 11, 2007, 12:42:47 PM »
Mark,

The code:
cnt (1- (itoa (sslength ss)))

Results in the following:
ERROR: bad argument type: numberp: "3"

Any thoughts?




Try this:
(itoa (1- (sslength ss)))

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Luke

  • Guest
Re: Counting Blocks
« Reply #23 on: April 11, 2007, 12:45:52 PM »
Nailed it!  Thanks a ton!

Crank

  • Water Moccasin
  • Posts: 1503
Re: Counting Blocks
« Reply #24 on: April 11, 2007, 12:53:14 PM »
You can also do this in diesel:
Code: [Select]
$(-,$(getenv, blk_count),1)
Vault Professional 2023     +     AEC Collection

Luke

  • Guest
Re: Counting Blocks
« Reply #25 on: April 11, 2007, 01:07:48 PM »
So just to be clear here Crank, you would continue using the original code but your Diesel Expression would subtract 1?

ML

  • Guest
Re: Counting Blocks
« Reply #26 on: April 11, 2007, 01:10:06 PM »


I'm sorry
I would use VBA to get the same results but it would probably result in more code

Mark

ML

  • Guest
Re: Counting Blocks
« Reply #27 on: April 11, 2007, 01:19:40 PM »

If you put this code in a Sub Module and run it, you will get the count for Blocks and Block References
Mark

Code: [Select]
Sub Blocks_Count()

Dim Blks As AcadBlocks
Dim BLCollect As AcadSelectionSet
Dim GCode(0) As Integer
Dim GData(0) As Variant
Dim GPCode As Variant
Dim GPData As Variant

Set Blks = ThisDrawing.Blocks

GCode(0) = 0
GData(0) = "Insert"
GPCode = GCode
GPData = GData
 Set BLCollect = ThisDrawing.SelectionSets.Add("BLOCKREFS")
BLCollect.Select acSelectionSetAll, , , GPCode, GPData
 MsgBox "There are " & Blks.Count & " blocks in this drawing and", vbInformation, "Blocks"
 MsgBox BLCollect.Count & " Block References", vbInformation, "Block References"
 'MsgBox "There are " & ThisDrawing.Blocks.Count & " block(s) in the block table and " & BLCollect.Count & " blocks inserted (Blockref) in the drawing", vbInformation, "Block Information"
BLCollect.Delete
 Set BLCollect = Nothing
 
End Sub

Quote
Thanks to Keith for the help in writing this

Crank

  • Water Moccasin
  • Posts: 1503
Re: Counting Blocks
« Reply #28 on: April 11, 2007, 01:46:38 PM »
So just to be clear here Crank, you would continue using the original code but your Diesel Expression would subtract 1?
That's what it does. But lisp is also ok.

With diesel you can minipulate the routine for each situation. Now you want to substract 1, but the next time you perhaps need the exact amount.
Vault Professional 2023     +     AEC Collection

Luke

  • Guest
Re: Counting Blocks
« Reply #29 on: April 11, 2007, 01:48:08 PM »
Yes I see, I like that better.  I likt the idea of only having 1 lisp, afterall I have to have a different diesel for each block / field I want to update.

Thank you all for you help!

ML

  • Guest
Re: Counting Blocks
« Reply #30 on: April 11, 2007, 01:49:18 PM »

Luke

Give The VBA a try
I will help you if you need it

Mark

Luke

  • Guest
Re: Counting Blocks
« Reply #31 on: April 11, 2007, 02:00:27 PM »
The diesel / lisp that Mark & Crank supplied work great and aside from understanding the exact code to type I already knew where and how to do all the other things they were describing. 

I'm always looking to learn new things but I've never done anything with VBA so I'll need you to hold my hand, step by step throught this.

What is first?

ML

  • Guest
Re: Counting Blocks
« Reply #32 on: April 11, 2007, 02:12:32 PM »

OK, Go to Tools-Macro-VBA Manager-Click New (For New VBa Project)
Click the button that says Visual Basic Editor

Righ Click on your new project, by default it will be called ACADProject
Click insert Module, then paste the code in the code that I gave you.

By default the new module puts in Sub and End Sub, so make sure you delete it because my code already has it.
Save it

Then you can go back to Tools-Macro-Macros and run it from there

I hope this helps?

Let me know if you have any problem   :-)

Mark

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Counting Blocks
« Reply #33 on: April 11, 2007, 02:16:03 PM »
A word of cautions....

When you use 'setenv' it will be available to all drawings, and in future sessions.  It can be good or bad, so just and FYI.

Continue....  :-)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Luke

  • Guest
Re: Counting Blocks
« Reply #34 on: April 11, 2007, 02:29:46 PM »
OK so I did all that. 

When I run it it pops a little windows box up on my screen that says "There are 71 blocks in this drawing and" OK.  When I click OK it then says "886 Block references" OK.  When I click OK there it seems to be done. 

Is this working how you planned?

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Counting Blocks
« Reply #35 on: April 11, 2007, 02:56:39 PM »
A word of cautions....

When you use 'setenv' it will be available to all drawings, and in future sessions.  It can be good or bad, so just and FYI.

Just to follow-up, the values are stored in the registry as seen below.


TheSwamp.org  (serving the CAD community since 2003)

CottageCGirl

  • Guest
Re: Counting Blocks
« Reply #36 on: April 11, 2007, 03:05:48 PM »
If you have Express Tools (I may be getting off the wrong train here) you could use "bcount". Try typing it in the command line.

NiiiiiiiCE one thanks, did not know about that...it is FABULOUS for systems furniture..........you get the good fairy points for the day!!! :-)
won't use it for ordering , but for general budgeting this will be awesome....

Luke

  • Guest
Re: Counting Blocks
« Reply #37 on: April 11, 2007, 03:18:52 PM »
Well everything Mark Thomas & Crank gave me previously works great and does just what I want.  I'm not concerned with the Model Paper space issues.  I'm only working in 1.  Additionally I have no interest in messing with or going into and extracting info from my registry. 

Thanks again all. I've done what I need to do.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Counting Blocks
« Reply #38 on: April 11, 2007, 03:43:13 PM »
A word of cautions....

When you use 'setenv' it will be available to all drawings, and in future sessions.  It can be good or bad, so just and FYI.

Just to follow-up, the values are stored in the registry as seen below.

<cut> image </cut>

Thanks for pointing out where it went.  I tried looking, but looked in the wrong place to start with.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

ML

  • Guest
Re: Counting Blocks
« Reply #39 on: April 11, 2007, 03:48:17 PM »

Yep,

That was it Luke.
I'm sorry if it isn't what you are looking for but that is how you insert VBA code and run a macro.
You can also launch the macro from a toolbar button, a pulldown menu etc.
If it is a routine you will use frequently, like LISP, you can put it in Startup Suite

Mark

Luke

  • Guest
Re: Counting Blocks
« Reply #40 on: April 11, 2007, 03:49:43 PM »
Thanks Mark,
Good to know, just doesn't give me the results I was looking for. 

Regards
Luke

ML

  • Guest
Re: Counting Blocks
« Reply #41 on: April 11, 2007, 04:07:04 PM »

Sure man, no problem
Now, it is VBA forever, right?   :-D

Remember VBA crosses over to MS Products, LISP is limited to ACAD, though LISP still has a place for sure.

Mark

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: Counting Blocks
« Reply #42 on: April 11, 2007, 04:23:50 PM »
A word of cautions....

When you use 'setenv' it will be available to all drawings, and in future sessions.  It can be good or bad, so just and FYI.

Just to follow-up, the values are stored in the registry as seen below.



Just for no other reason but to ask why.

Why are you accessing and storing data to the registry?
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

Luke

  • Guest
Re: Counting Blocks
« Reply #43 on: May 02, 2007, 09:30:35 AM »
Mark Thomas,

Thanks again for your previous help on this post. 

I have another question now...

What do I need to change to get it to result a zero if the qty truely is zero.  What is happening to me is when the block is not in the drawing the lisp recognizes nothing and does not update the qty.

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Counting Blocks
« Reply #44 on: May 02, 2007, 09:51:46 AM »
Mark Thomas,

Thanks again for your previous help on this post. 

I have another question now...

What do I need to change to get it to result a zero if the qty truely is zero.  What is happening to me is when the block is not in the drawing the lisp recognizes nothing and does not update the qty.

That shouldn't be to hard to do, give me a little while to work it out.
TheSwamp.org  (serving the CAD community since 2003)

Luke

  • Guest
Re: Counting Blocks
« Reply #45 on: May 02, 2007, 09:52:45 AM »
No sweat.

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Counting Blocks
« Reply #46 on: May 02, 2007, 10:42:56 AM »
Try this one Luke

Code: [Select]
(defun c:recount (/ block_list cnt env_name)

  ;; The intent of this app is to count the number of blocks inserted into
  ;; a given dwg and set environment variables based on the block name so
  ;; one can use the diesel expression '$(getenv, <name>)' in a table cell
  ;; to track the number of block insertitions therein
  ;;
  ;; Typical output
  ;;
  ;; Set BLOCK_COUNT_ELM to 6
  ;; Set BLOCK_COUNT_CITRUS to 5
  ;; Set BLOCK_COUNT_OAK to 11
  ;; Set BLOCK_COUNT_PALM to 5
  ;;
  ;; Given the above output you would use '$(getenv, BLOCK_COUNT_OAK)' in
  ;; your table cell
  ;;
  ;; version 2.0
  ;; Wed May 02, 2007
  ;; Mark S. Thomas ( mark@theswamp.org )

  ;
  ; list of blocks you wish to count
  ;
  (setq block_list
(list
  ;
  ; add a line for each block you wish to count
  ; the following are just samples
  ;
  (cons '2 "ELM")
  (cons '2 "CITRUS")
  (cons '2 "OAK")
  (cons '2 "PALM")
  )
)

  (foreach i block_list
   (setq ss (ssget "X" (list '(0 . "INSERT") i)))

   (if ss
     (progn
       (setq
;
; count the number of blocks inserted
; create the environment name, i.e. "BLOCK_COUNT_ELM"
;
cnt (itoa (sslength ss))
env_name (strcat "BLOCK_COUNT_" (cdr i))
)

       ; finally we set the environment variable
       (setenv env_name cnt)

       ; show the user what was set and how many blocks were counted
       (princ (strcat "\nSet " env_name " to " cnt))
       )
     ;; else if ss = nil then no blocks were found and
     ;; we set 'env_name' to zero
     (progn
       (setq
;
; create the environment name, i.e. "BLOCK_COUNT_ELM"
;
env_name (strcat "BLOCK_COUNT_" (cdr i))
)

       ; finally we set the environment variable to zero
       (setenv env_name "0")

       ; show the user what was set and how many blocks were counted
       (princ (strcat "\nSet " env_name " to 0"))
       )
     )
   )
  (princ)
  )
TheSwamp.org  (serving the CAD community since 2003)

Luke

  • Guest
Re: Counting Blocks
« Reply #47 on: May 02, 2007, 11:28:35 AM »
Mark,
Thank you.  That did it.

Luke

bdaiss

  • Guest
Re: Counting Blocks
« Reply #48 on: June 23, 2014, 03:55:08 PM »
I know this thread hasn't been posted in for a while but I'm curious if its possible to set the block counts to a specific window within a drawing and set it to recount the blocks every time you regen. This would basically function like the block count function in AutoField but with more control. My goal is to have the window be able to be adjusted like any polyline so that it doesn't have to be reset in the code every time. Its beyond my abilities in lisp and diesel. I saw this thread and thought it was worth a try to ask for help......

functions needed:
-select object for window and be able to edit the object after it is selected
-count objects and set them to a field using diesel or other ways if needed