Solved

VB Macro to Count Blocks

Posted on 2004-08-30
8
19,493 Views
Last Modified: 2012-05-05
This comment concerns AutoCAD 2002,
I need to create a little code that will enable the user see how many occurances of a block there are in a drawing simply by clicking on one.  Eventually I would like to make it functional enough so that the user could click them off one by one with each counted block turning a different color.  I have programmed extensively in Excel with VBA but have done absolutely nothing in AutoCAD.  I have looked into LISP but have not been able to make heads or tails of any of it.  What I need is just kind of a jump start.  For instance, how do you allow the user to select objects in code?  Is there a control that does this?  In Excel it's a Refedit control.  Do I need to change the selection mode?  Is there a blocks collection for each block in AutoCAD?  Can I do a For Each Block in BlockName.Blocks?  If anybody knows of any good tutorials on programming with VB in AutoCAD I would like to take a look at them.  

As you can see I'm pretty bogged down here.  Any suggestions will be appreciated.

Kyle
0
Comment
Question by:kgerb
  • 3
  • 2
  • 2
  • +1
8 Comments
 
LVL 12

Author Comment

by:kgerb
Comment Utility
Also, how "difficult" is my little endevour going to be.  Is this a monsterous project that I'm starting in on, or is it doable for a newbie to AutoCAD VBA.
0
 
LVL 1

Assisted Solution

by:odd lie
odd lie earned 150 total points
Comment Utility
I hope you can use some of this code to manage what you want, I am at work now but I have some lisp code that can be used if you want !!

Use scale factors with XP option of ZOOM command

Use VBA to access blocks and block reference data

Use VBA to access blocks and block reference data

Published date: 2002-02-21
ID: TS70489

Applies to:
AutoCAD® 2002
AutoCAD® 2000i
AutoCAD® 2000
AutoCAD® Release 14

Issue



This document explains how to access blocks and block reference data using VBA (Visual Basic for Applications).
Solution



Overview

You can use VBA to manage blocks and block references.

A block is a collection of objects that you associate together to form a single object, called a block definition.  When you insert a block in a drawing, you create a block reference. That is, the block reference references the block definition. It is important to know the difference between a block definition and a block reference, because it helps you to understand how you can manipulate these objects in VBA.

We explain how to do this by commenting a short program that illustrates the process. The following sections use commented code examples that show you how to access blocks (block definitions) and block reference data using VBA.

Create the application interface

Assume that you have defined a main form in VBA, with the following controls:
ListBox named lstBlockObject  
ListBox named lstBlockReference  
Command Button named cmdCreateBlock  
Command Button named cmdLister  
Command Button named cmdChangeColor

Create a module and add the following declarations.

'Blocks collection
Public blkColl As AcadBlocks
'Block object
Public BlkObj As AcadBlock
'Block reference object
Public BlkRefrence As AcadBlockReference
'ModelSpace collection
Public mspace As AcadModelSpace
'PaperSpace collection
Public pspace As AcadPaperSpace
Public count As Integer
Public I As Integer
Public elem As Object
Public subelem As Object
'Block insertion point
Public blkInsPnt (0 To 2) As Double
Public circleObj As AcadCircle
'Circle center point
Public center(0 To 2) As Double
'Circle radius
Public radius As Double
Public lineObj as AcadLine
'Line start point
Public startPnt (0 To 2) As Double
'Line end point
Public endPnt (0 To 2) As Double

Add the following declarations to the Initialize event of the form.

'Returns the ModelSpace collection
Set mspace = ThisDrawing.ModelSpace
'Returns the PaperSpace collection
Set pspace = ThisDrawing.PaperSpace
'Returns the blocks collection
Set blkColl = ThisDrawing.Blocks

Create a block

To create a block reference, first you must create a block definition (block). You do this using the Add method. After you create the block you can insert an instance of it into the drawing using the InsertBlock method. In this example, we create a block in model space that is made up of a circle and a line.

Add the following code to the Click event procedure of the cmdCreateBlock button.

blkInsPnt(0) = 0#: blkInsPnt(1) = 0#: blkInsPnt(2) = 0#
'Add the block to the blocks collection
Set BlkObj = blkColl.Add(blkInsPnt, "NewBlock")

Add elements to block

This section provides the code examples that add the elements to the block.

Add the circle

center(0) = 0#: center(1) = 0#: center(2) = 0#
radius = 1
'Add the circle to the block
Set circleObj = BlkObj.AddCircle(center, radius)

Add the line

startPnt(0) = 1#: startPnt(1) = 1#: startPnt(2) = 0#
endPnt(0) = 5#: endPnt(1) = 5#: endPnt(2) = 0#
'Add the line to the block
Set lineObj = BlkObj.AddLine(startPnt, endPnt)

Insert the block in model space

The following code example inserts the block in model space.

Set BlkRefrence = mspace.InsertBlock(blkInsPnt, "NewBlock", 1#, 1#, 1#, 0)
'Zooming the block
ZoomExtents

Access the Block and BlockReference Objects

VBA provides a link to the active drawing in the current AutoCAD session through the ThisDrawing object. By using ThisDrawing, you gain immediate access to the current Document object and all of its methods and properties, and all of the other objects in the hierarchy.

To access a block, you refer to the ThisDrawing object; to access a block reference you refer to the ModelSpace or PaperSpace collection.

Access the block objects

You now need to scan the Block collection, retrieve block names and put them in the ListBox lstBlockObject. There are two ways to scan the Block collection.

You can use an index to scan the Block collection. Once you know how many items the collection contains, you can use a For.Next conditional statement. To do this, add the following code to the Click event procedure of the cmdLister button.

'Returns number of blocks in the blocks collection
count = blkColl.count
'Clear the list box
lstBlockObject.Clear
'Create the block list
For I = 0 To count - 1
 lstBlockObject.AddItem blkColl.Item(I).Name
Next
lstBlockObject.ListIndex = 0

Note: In a collection of N items, the index goes from 0 to N-1.

However, a better way is to use a For Each.In.Next conditional statement. For example, the following statements repeat a block of statements for each object in a collection or each element in an array. VBA automatically sets a variable each time the loop runs. Therefore you could rewrite the previous code using the following example.

'Clear the list box
lstBlockObject.Clear
'Create the block list
For Each elem in ThisDrawing.Blocks
 lstBlockObject.AddItem elem.Name
Next
lstBlockObject.ListIndex = 0

By using this alternative code you
Reduce the number of operations.
Improve code readability.
Reduce the number of user variables.
Reduce the need for error checking (for example, the range control for conditional statements).
Implement a more elegant programming style.

Access the block references

To retrieve similar entities, you perform a similar set of operations; but instead of searching the Blocks collection, you need to search the ModelSpace or PaperSpace collection of an AutoCAD ActiveDocument. To do this, add the following code to the Click event procedure of the cmdLister button.

'Clear the list box
lstBlockReference.Clear
'Create the block list
'Scanning the Model Space collection
For Each elem In mspace
 'Filter only the block references
 If elem.EntityName = "AcDbBlockReference" Then
  lstBlockReference.AddItem elem.Name
 End If
Next
lstBlockReference.ListIndex = 0

At this point, every time you click the Create block button, you only have one block called NEWBLOCK in the ListBox lstBlockObject. However, a new block reference called NEWBLOCK is added to the ListBox lstBlockReference. The new block reference is appended, because you created a new reference to the block (block definition).

Note: Even if the block reference has the same name as existing block references, the handle is different. To AutoCAD, they are different objects.

Modify objects within the block

You can modify an object within a block without exploding the block. To do this, you need to go inside the block object, retrieve the entity to modify and change its properties. The following code example changes the color property of the line to Red.

Add the following code to the Click event procedure of the cmdChangeColor button:

'Scanning the blocks collection
For Each elem In blkColl'Searching the block we want
 If elem.Name = "NewBlock" Then
 'Scanning the block entities
  For Each subelem In elem
    'Filter the line
    If subelem.EntityName = "AcDbLine" Then
     'Assign a new color
     subelem.Color = acRed
    End If
  Next
 End If
Next
'Regenerating the drawing
ThisDrawing.Regen True

This code changes the color property for the line in all block references called NEWBLOCK. What actually happens is that the code changes the color property for the line in the block object (the block definition) and the references are updated because they reference the block object.
See also


Using VBA to modify how AutoCAD DesignCenter inserts blocks

Removing invisible text from a drawing

Drawing is completely empty but file size is very large


Regards
oldelphi
0
 
LVL 5

Accepted Solution

by:
thenrich earned 350 total points
Comment Utility
Here is the exact code you need:

Sub main()
  Dim blk As AcadEntity
  Dim ent As AcadEntity
  Dim newblk As AcadBlockReference
  Dim pnt As Variant
  Dim cnt As Integer
  Dim blkName As String
 
  On Error GoTo ExitError
 
  AppActivate ("AutoCAD")
  ThisDrawing.Utility.GetEntity blk, pnt, "Select block:"
  If TypeName(blk) = "IAcadBlockReference" Then
       blkName = blk.Name
       For Each ent In ThisDrawing.ModelSpace
          If TypeName(ent) = "IAcadBlockReference" Then
             If ent.Name = blkName Then
                cnt = cnt + 1
             End If
          End If
       Next
    Else
     MsgBox "You've selected a " & TypeName(blk) & Chr(13) & "A block must be selected."
     Exit Sub
  End If
  MsgBox cnt & " occurences of " & blkName
  Exit Sub

ExitError:
  MsgBox Err.Description
End Sub
0
 
LVL 5

Expert Comment

by:thenrich
Comment Utility
Actually the help in AutoCAD is pretty good. In AutoCAD 2002 go under the help menu and select the 'Developer help' under the help menu vs. the regular help. Lots of good books out there especially from AutoDesk Press. Not much need for LISP any more - did it for years - ICK!!! Stick with the VBA, VB, or .NET when it comes to AutoDesk products.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 12

Author Comment

by:kgerb
Comment Utility
oldelphi,
Thanks for all the code and the generous explainations.  They are very informative.

thenrich,
your code works great!  Thank you!

I'm having a little trouble figuring out how to make it so that I can use the macro in any open drawing without having to find and load the .dvb file each time.  If I can't figure it out I'll ask another question.  Thanks so much to you both.

Kyle
0
 
LVL 5

Expert Comment

by:thenrich
Comment Utility
' If I can't figure it out I'll ask another question.'

yup - let me know
0
 
LVL 1

Expert Comment

by:odd lie
Comment Utility
You can bay a book on the subjekt
Autocad 2005 Bible
the 2004 version includes a nice explenation on how to use
visual basicContains the Book on PDF and All the code in the book
ISBN 0-9645-3992-2
Lock at http://www.wiley.com/WileyCDA/WileyTitle/productCd-0764569899.html

best regards
Oldelphi

Cad instructor since 1988
0
 

Expert Comment

by:daviper
Comment Utility
There seems no easy way to make commands with Macros.  Thus I have this first bit of Code in my Acad.lsp file which is in our standards directory. This also gets the VBA system up and running when AutoCAD loads up allows AutoCAD to find the acad.DVB file. The DVB file has entries to load every macro we use.  The lisp just calls the appropriate Model.

This code is in my ACAD.lsp

      (setvar "acadlspasdoc" 0)
      
;***Used to Initialize the Visual Basic Sub System***

      (command "-vbarun" "InitVBA" )

I then have a bunch of entries such as this one in my ACADdoc.lsp file for each macro I would like a command for as AutoCAD starts up.

(load "S:/Standards/Programming/Lisp/cut.lsp")

That Cut.lsp file simply has this bit of code which basically calls a small bit of Code in a module which says frmCutsheet.show or something.

(defun c:cut () ;Begin defun

(command "-vbarun" "CUTSHEET")

) ;End defun


If you would like a more detailed explination and the VBA code as well let me know.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Following a number of instances of re-installing Solidworks I thought that it may be a  good idea to detail the procedure that I follow each time to ensure a good stable install. Backup: Backup your system.  It goes without saying that this i…
The following article will describe how to add/edit a dimension style through AutoCAD VBA. AutoCAD VBA has its quirks and when it comes to dimensions and controlling how they look through VBA.  This is where AutoCAD can be vividly confusing. The…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now