A foundation plan carries three hundred pile symbols. You need to know exactly how many, you want the whole lot recoloured so they read clearly, and at the end of the day you need to explode one kind of symbol to edit it. Three jobs, and AutoCAD does none of them properly.
This article publishes the Institute's lisp file for all four, with the source printed in full so you can read it before running it. Counting blocks in AutoCAD is the command that gets used most, but the other three are where the hours are saved. For the whole approach to blocks in a drawing set see our AutoCAD for Construction course.
Why what AutoCAD already has is not enough
Four jobs, four gaps:
| Job | What exists | Where it falls short |
|---|---|---|
| Counting blocks | BCOUNT | Lives in Express Tools, not present in every installation |
| Colouring by block name | QSELECT then edit | Through a dialog, one condition per pass |
| Renaming a block | RENAME | Works, but warns you about nothing |
| Exploding one kind of block | nothing | Every insertion has to be picked by hand |
The last one hurts most. On a plan dense with symbols, exploding only the pile marks while leaving the column marks alone means picking by hand — or exploding everything and regretting it. Exploding in general is covered in our article on the explode command in AutoCAD.
Download the Institute's file
| Command | What it does |
|---|---|
BKD | count blocks by name and print a table |
BKM | colour every insertion of one block |
BKT | rename a block; every insertion follows |
BKP | explode every insertion of one block, leaving the rest alone |
The file linked above prompts in English. A Vietnamese version is also published, with the same four command names.
;;; ==================================================================
;;; BLK-IIC-EN.LSP - working on BLOCKS in bulk
;;; Institute of Information Technology in Civil Engineering (IIC)
;;; Hanoi University of Civil Engineering
;;; https://iic.huce.edu.vn - Tel: 0989 427 809
;;; ------------------------------------------------------------------
;;; Four commands:
;;; BKD count blocks by name and print a table
;;; BKM colour EVERY insertion of one block
;;; BKT rename a block; every insertion follows
;;; BKP explode every insertion of ONE block, leaving the rest alone
;;;
;;; Why this file is needed: AutoCAD has BCOUNT for counting blocks, but
;;; it lives in Express Tools and not every installation has them. For
;;; colouring or exploding one kind of block there is no command at all:
;;; QSELECT can select by block name, but only through a dialog and only
;;; one condition at a time.
;;;
;;; FOUR THINGS TO KNOW BEFORE RUNNING:
;;; 1. BKD counts INSERTIONS, not definitions. A block placed 40 times
;;; counts 40. An insertion nested inside another block is NOT
;;; counted - only the outermost level is. Autodesk's own BCOUNT
;;; behaves the same way.
;;; 2. BKM sets the colour of the INSERTION, not of the linework inside
;;; it. Anything inside the definition with a HARD colour (not
;;; ByBlock) keeps its old colour however often you run this. That
;;; is the familiar "I changed the colour and nothing happened".
;;; 3. BKT renames the block definition. Any drawing xrefing this one,
;;; and any schedule looking the old name up, breaks.
;;; 4. BKP explodes insertions; a block placed with X and Y scales that
;;; differ still explodes, but circles inside it become ELLIPSES.
;;; There is no way round that.
;;; Every command PRINTS how many insertions it touched, so the result
;;; can be checked.
;;;
;;; Command names were checked before being chosen: the acad.pgp alias
;;; file of the 2027 release has no BKD, BKM, BKT or BKP.
;;;
;;; To load: type APPLOAD, pick this file, click Load.
;;; Saved as UTF-8. If you edit it in Notepad, save it back as UTF-8.
;;; ==================================================================
(vl-load-com)
;;; pad right / pad left to width n
(defun iic-pad (s n) (while (< (strlen s) n) (setq s (strcat s " "))) s)
(defun iic-rpad (s n) (while (< (strlen s) n) (setq s (strcat " " s))) s)
;;; ------------------------------------------------------------------
;;; The real name of an insertion. A dynamic block reports a temporary
;;; name like "*U123", so EffectiveName has to be asked for.
;;; ------------------------------------------------------------------
(defun iic-name (e / o tn)
;; Do NOT name a local variable "t": in AutoLISP T is the constant for
;; true, and binding it raises "; error: incorrect object to bind: T".
(setq o (vlax-ename->vla-object e))
(setq tn (vl-catch-all-apply 'vlax-get (list o 'EffectiveName)))
(if (or (vl-catch-all-error-p tn) (null tn))
(cdr (assoc 2 (entget e)))
tn
)
)
;;; ------------------------------------------------------------------
;;; BKD - count blocks by name
;;; ------------------------------------------------------------------
(defun c:BKD (/ ss i e nm tbl o total)
(princ "\nSelect an area to count (Enter for the whole drawing): ")
(setq ss (ssget '((0 . "INSERT"))))
(if (null ss) (setq ss (ssget "_X" '((0 . "INSERT")))))
(if ss
(progn
(setq tbl nil i 0)
(while (< i (sslength ss))
(setq e (ssname ss i)
nm (iic-name e)
o (assoc nm tbl))
(if o
(setq tbl (subst (cons nm (1+ (cdr o))) o tbl))
(setq tbl (cons (cons nm 1) tbl))
)
(setq i (1+ i))
)
(setq tbl (vl-sort tbl (function (lambda (a b) (> (cdr a) (cdr b))))))
(setq total 0)
(princ "\n")
(princ "\n Block name Insertions")
(princ "\n ---------------------------------------------")
(foreach o tbl
(setq total (+ total (cdr o)))
(princ (strcat "\n " (iic-pad (car o) 32) (iic-rpad (itoa (cdr o)) 11)))
)
(princ "\n ---------------------------------------------")
(princ (strcat "\n Total insertions" (iic-rpad (itoa total) 29)))
(princ (strcat "\n Distinct block names" (iic-rpad (itoa (length tbl)) 25)))
(princ "\n")
)
(princ "\nNo block insertions found.")
)
(princ)
)
;;; ------------------------------------------------------------------
;;; BKM - colour every insertion of one block
;;; ------------------------------------------------------------------
(defun c:BKM (/ nm col ss i e n)
(setq nm (getstring T "\nBlock name to colour: "))
(if (= nm "") (progn (princ "\nNo name given.") (exit)))
(setq col (getint "\nColour number (1 red, 2 yellow, 3 green, 4 cyan, 5 blue, 7 white): "))
(if (null col) (progn (princ "\nNo colour given.") (exit)))
(setq ss (ssget "_X" '((0 . "INSERT"))) i 0 n 0)
(if ss
(progn
(while (< i (sslength ss))
(setq e (ssname ss i))
(if (= (strcase (iic-name e)) (strcase nm))
(progn
(entmod (append (vl-remove-if (function (lambda (x) (= (car x) 62)))
(entget e))
(list (cons 62 col))))
(setq n (1+ n))
)
)
(setq i (1+ i))
)
(princ (strcat "\nColoured " (itoa n) " insertion(s) of block \"" nm "\"."))
(if (= n 0)
(princ "\nNo insertion of that name. Run BKD to see the list of names.")
(princ "\nNote: linework inside the block with a hard colour does not follow.")
)
)
(princ "\nThe drawing holds no blocks.")
)
(princ)
)
;;; ------------------------------------------------------------------
;;; BKT - rename a block
;;; ------------------------------------------------------------------
(defun c:BKT (/ old new bl r)
(setq old (getstring T "\nCurrent block name: "))
(setq new (getstring T "\nNew name: "))
(if (or (= old "") (= new ""))
(progn (princ "\nA name is missing.") (exit))
)
(setq bl (tblobjname "BLOCK" old))
(if (null bl)
(princ (strcat "\nNo block named \"" old "\". Run BKD to see the list."))
(if (tblobjname "BLOCK" new)
(princ (strcat "\nA block named \"" new "\" already exists. Pick another name."))
(progn
(setq r (vl-catch-all-apply
'vla-put-Name
(list (vla-item (vla-get-Blocks
(vla-get-ActiveDocument
(vlax-get-acad-object))) old) new)))
(if (vl-catch-all-error-p r)
(princ (strcat "\nCould not rename: " (vl-catch-all-error-message r)))
(progn
(princ (strcat "\nRenamed \"" old "\" to \"" new "\"."))
(princ "\nNote: any schedule looking the old name up will no longer find it.")
)
)
)
)
)
(princ)
)
;;; ------------------------------------------------------------------
;;; BKP - explode every insertion of ONE block
;;; ------------------------------------------------------------------
(defun c:BKP (/ nm ss i e ds ds2 n x)
(setq nm (getstring T "\nBlock name to explode: "))
(if (= nm "") (progn (princ "\nNo name given.") (exit)))
(setq ss (ssget "_X" '((0 . "INSERT"))) i 0 ds (ssadd))
(if ss
(progn
(while (< i (sslength ss))
(setq e (ssname ss i))
(if (= (strcase (iic-name e)) (strcase nm))
(setq ds (ssadd e ds))
)
(setq i (1+ i))
)
(setq n (sslength ds))
(if (= n 0)
(princ (strcat "\nNo insertion named \"" nm "\"."))
(progn
;; Explode them ONE AT A TIME. Handing the whole selection set to
;; (command "_.EXPLODE" ds) explodes exactly ONE of them and then
;; stops - measured on the 2027 release: five insertions selected,
;; one new object produced. Collect the enames into a list FIRST,
;; because exploding removes them from the drawing.
(setq i 0 ds2 nil)
(while (< i n)
(setq ds2 (cons (ssname ds i) ds2) i (1+ i))
)
(foreach x ds2 (command "_.EXPLODE" x))
(princ (strcat "\nExploded " (itoa n) " insertion(s) of block \"" nm "\"."))
(princ "\nNote: circles inside a block placed at uneven scales become ellipses.")
)
)
)
(princ "\nThe drawing holds no blocks.")
)
(princ)
)
(princ "\nBLK-IIC-EN loaded. Commands: BKD (count), BKM (colour), BKT (rename), BKP (explode).")
(princ)
The count matches a drawing counted beforehand
Build a drawing whose insertions are known, then run the counting command:
| Block | Times inserted |
|---|---|
IIC_COT | 5 |
IIC_COC | 3 |
IIC_CUA | 1 |
IIC_TO | 1 |
| Total | 10 |
Running BKD prints:
Block name Insertions
---------------------------------------------
IIC_COT 5
IIC_COC 3
IIC_CUA 1
IIC_TO 1
---------------------------------------------
Total insertions 10
Distinct block names 4
Every row agrees. The table sorts by count, so the commonest block sits at the top — useful once a drawing carries a few dozen names.
Pressing Enter at the first prompt counts the whole drawing. To count one area, window it and press Enter.
Nested blocks are not counted
This is what makes two people counting the same drawing come back with two different numbers.
In the test drawing, block IIC_TO holds an IIC_COC insertion inside it. So there are four IIC_COC shapes on screen: three placed directly and one inside IIC_TO.
The table reports IIC_COC as 3, not 4.
The command counts only the outermost level. For drawing-set purposes that is usually the right answer: the one inside IIC_TO is part of IIC_TO, not an independent symbol. But it has to be known, or the number becomes an argument. Making and nesting blocks is covered in our article on blocks in AutoCAD.
Worth noting that Autodesk's own tool behaves identically. Autodesk's BCOUNT page states: "BCOUNT does not select or count nested blocks or blocks nested in associative array objects." So the figure from the Institute's file and the figure from Express Tools agree, and both leave nested blocks out.
That sentence carries a second case worth remembering: blocks inside an associative array are not counted either. On a drawing where symbols were laid out with the array command, that is where the number quietly comes up short. Arrays are covered in our article on the array command in AutoCAD.
Colouring blocks in bulk, and why nothing happens
Run BKM, give the block name and a colour number, and the whole lot changes at once. In the test, IIC_COT and colour 1 changed all five insertions.
But plenty of people run exactly that and see nothing change on screen. Here is the measured reason.
Build two blocks identical in shape, differing in one respect: the circle inside the first is left ByLayer, the circle inside the second is fixed to colour 2. Colour both insertions to 1:
| Insertion colour after | Colour of the linework inside | |
|---|---|---|
Block left ByLayer | 1 | still 256, meaning ByLayer — so it displays as colour 1 |
| Block fixed to colour 2 | 1 | still 2 |
The second insertion really does carry colour 1, yet on screen it stays yellow. The linework inside it is fixed to colour 2, and a fixed colour does not listen to the insertion.
The only cure is to edit the block definition and set its linework back to ByLayer or ByBlock. Editing definitions is covered in our article on editing blocks in AutoCAD, and the difference between ByLayer and ByBlock in our article on layers in AutoCAD.
Renaming a block: easy, but think first
BKT asks for the old name, the new name, and renames. In the test, renaming IIC_COC to IIC_COC_MOI made all three insertions report the new name immediately — an insertion holds no name of its own, it simply points at the definition.
The command refuses in two cases, and says so in both: no block carries the old name, or another block already uses the new one.
What to weigh before renaming: everything that looks the old name up breaks. A schedule built on block names, somebody else's lisp filtering by name, another drawing xrefing this one — renaming snaps all of it. External references are covered in our article on xrefs in AutoCAD.
So there is one right moment to rename: when the drawing first arrives, before any work is done on it.
There is one renaming job that is always worth doing, and most offices skip it. A drawing set assembled from four consultants usually carries four sets of arbitrary block names — A$C1de05, Block1, 123, or abbreviations nobody can decode. One run of BKD shows the whole list, and renaming them to a consistent scheme makes every later schedule readable.
Keep the scheme short and lead with the group: PILE-D300 for a 300 diameter pile, COL-C1 for column C1. Names that lead with the group sort together alphabetically, so nothing has to be hunted for.
Exploding one kind of block
This is the command with no equivalent in stock AutoCAD.
Run BKP, give a block name, and every insertion of that block is exploded. The test drawing held 10 insertions; naming IIC_COT:
| Before | After | |
|---|---|---|
| Objects in the drawing | 10 | 10 |
| Block insertions | 10 | 5 |
| Loose circles | 0 | 5 |
Five IIC_COT insertions became five loose circles, and the five insertions of the other three blocks were left untouched. Exactly as intended.
One caveat already measured in the article on exploding: a block placed with X and Y scales that differ still explodes, but the circles inside become ellipses. There is no way round it, so for that kind of block, editing the definition is the better move.
Worth being deliberate about when to reach for this at all. Exploding is usually the wrong instinct: a drawing full of blocks is lighter, easier to revise and easier to schedule than the same drawing exploded into loose linework. The legitimate cases are narrow — a symbol that has to be edited once and never reused, or a block arriving from a consultant that has to be merged into your own library. Counting blocks in AutoCAD before and after any such operation is the cheapest check there is that nothing was lost along the way.
Five things people say that are not true
| What people say | What was measured |
|---|---|
| AutoCAD has a built-in block counter | BCOUNT is in Express Tools, absent from some installations |
| Counting picks up every insertion | Insertions nested inside another block are not counted |
| Colour a block and its symbols change colour | Linework fixed to a colour inside the definition keeps it |
| Renaming a block just changes a label | Schedules and xrefs looking the old name up all break |
| Exploding one kind of block means picking by hand | BKP explodes the named block and leaves the others alone |
Frequently asked questions
Which command counts blocks?
BKD. Press Enter at the first prompt for the whole drawing, or window an area to count that.
Why is the count lower than what I can see?
Because some insertions sit inside another block. Only the outermost level is counted.
I coloured the block and nothing changed — why?
The linework inside the definition is fixed to a colour. Edit the definition and set it back to ByLayer or ByBlock.
Does renaming a block break anything?
Yes. Any schedule or drawing looking the old name up stops finding it. Rename when the drawing first arrives, not later.
Can it explode just one kind of block?
Yes, with BKP and the block name. Every other block is left alone.
Does it count dynamic blocks under the right name?
Yes. It asks for the block's effective name rather than the temporary *U123 name a drawing gives a dynamic block.