Professional Documents
Culture Documents
Hands-On Introduction To VB - NET Add-Ins For AutoCAD - SD197926-L PDF
Hands-On Introduction To VB - NET Add-Ins For AutoCAD - SD197926-L PDF
Speaker
Lab Assistants
Karl Hill, Alaska Native Tribal Health Consortium, IT Manager/CAD Equipment Manager
James Johnson, Synergis Technologies LLC Sr. Application Developer
Gyorgy Ordody, Autodesk, Inc Software Engineer
Learning Objectives
• Learn how to extract block and attribute information through the .NET API
Lab Description
Knowing how to write AutoCAD add-ins lets us create new AutoCAD commands that automate routine tasks, perform complex cal-
culations, or integrate multiple systems to help us be more productive, more precise, and more effective. The use of Microsoft's
free Visual Studio Community together with the information presented in this class will help anyone immediately begin creating
AutoCAD add-ins with VB.NET.
Speaker Bio
https://visualstudio.microsoft.com/vs/community/
The download will be a 1.2 MB file. When this file is executed, it will download and install Visual Studio Community Edition.
During the installation process, you may be asked for your preferred language. If you are asked this, select “Visual Basic”.
This first step we work on is the most difficult, complex, challenging thing we will do during this lab. This is not
intended to scare you but to prepare you. There are very specific steps that need to be followed and if we
leave even one of these steps out we will not be able to do anything else.
Pre-requisites
• Visual Studio 2017 Community Edition is installed
• AutoCAD 2019 is installed
We will go through steps 1-4 multiple times because if we return home after attending Autodesk University
and can not create a new Add-In for AutoCAD, well, that would not be good.
1. Start Visual Studio
After installing Visual Studio, you will be able to start Visual Studio just as
you do any other application in Windows. If you plan on writing AutoCAD
Add-Ins on a regular basis, you may want to pin Visual Studio to your Task
Bar.
Now we need to select the type of project we want to create. There are 5 things we need to do here. First,
make sure the Visual Basic—Windows Desktop node is selected in the Tree (on the left). Second, select
“Class Library (.NET Framework)” is selected. Third, give the project a Name. Fourth, uncheck the “Create
directory” checkbox. Fifth, set the Framework to “.NET Framework 4.7”
Next, in the File name combobox, type “ac*mgd.dll” and hit Enter
This filter reduces the number of files that show up in the list. We are looking for 3 files: accoremgd,dll,
acdbmgd.dll, and acmgd.dll
If we set up the Startup Application correctly (from Step 4), clicking the “Start” button will start AutoCAD for
us. When this happens, we’ll start a new Drawing.
• Visual Studio starts the program in the “Start external program” Debug page.
• A ‘link’ between Visual Studio and AutoCAD is created so Visual Studio ‘listens’ to what is happening in-
side AutoCAD.
Now, our code is compiled and AutoCAD is started. The next step is to have AutoCAD load our .NET Add-In.
Netload is the command we run to load our
program into AutoCAD. When we run
“Netload”, we browse to the directory where
the .dll is compiled into. Where is that, you
ask? What a great question.
When we created our project, the “Location” was put in for us by Visual Studio. It may or may not match what
we see below. But the important thing is that we take note of the Location because based on our settings
here, the path we want to browse to right now is:
C:\Users\JerryWinters\source\repos\ProgramA\bin\debug
Now, what do we do? Nothing. We didn't write any code so there’s nothing to do. Let’s close AutoCAD now.
That may seem like we didn't accomplish very much but that’s not the case. Here’s what we just did:
1. Start Visual Studio
Create a New VB.NET Class Library Project
Add References to the following files: accoremgd.dll, acdbmgd.dll, acmgd.dll
Set the acad.exe file as the Debug Startup Application
Started the debugging process
Netloaded our application.
If we can go through those steps a few more times during this Lab, we will be able to create a new project
when we get back home and are ready write amazing, incredible code.
Here’s code you can copy and paste into your Visual Studio project:
<Autodesk.AutoCAD.Runtime.CommandMethod("RunMe")>
Public Sub RunMe()
MsgBox("I hope this works.")
End Sub
<Autodesk.AutoCAD.Runtime.CommandMethod("RunMe")>
This code is used to define a new command in AutoCAD. The command name is “RunMe”. It is placed
directly above a Public Sub statement.
End Sub
This line closed the procedure named “RunMe”. The code between “Sub” and “End Sub” runs line by line
when the “RunMe” command is run.
I really hope the program works on your computer. If it does, you will see a message box as shown above.
Now, before we close down AutoCAD, let’s see if we can debug our program.
Switch back over to Visual Studio and click in the grey column on line 4. This is called adding a “Breakpoint”.
The line of code highlighted yellow is the next line of code that will be run.
Hit the F11 button on the keyboard. This will run the line of code highlighted yellow.
There’s our MessagBox. After we click the “OK” button, we are taken back to
Visual Studio on Line 5.
Now that we are successfully debugging, let’s make a little change to our code. After all, the code does work.
Right?
Let’s click and drag the yellow arrow from Line 5 up back to Line 4.
Now if we hit the F11 button again, Line 4 will be executed but with the new message.
Let’s copy and paste this code from the handout into our project. Then let’s add a Breakpoint, begin
debugging, run the command, and step through the code line by line.
<Autodesk.AutoCAD.Runtime.CommandMethod("DrawGrid")>
Public Sub DrawGrid()
Dim myDoc As Document = DocumentManager.MdiActiveDocument
Dim myDB As Database = myDoc.Database
Dim myEditor As Editor = myDoc.Editor
Using myTrans As Transaction = myDoc.TransactionManager.StartTransaction
Dim myBTR As BlockTableRecord = myDB.CurrentSpaceId.GetObject(OpenMode.ForWrite)
For X As Double = 0 To 10 Step 0.5
For Y As Double = 0 To 10 Step 0.5
Dim startPoint As New Point3d(X, 0, 0)
Dim endPoint As New Point3d(X, 10, 0)
Dim myLine As New Line(startPoint, endPoint)
myBTR.AppendEntity(myLine)
myTrans.AddNewlyCreatedDBObject(myLine, True)
startPoint = New Point3d(0, Y, 0)
endPoint = New Point3d(10, Y, 0)
myLine = New Line(startPoint, endPoint)
myBTR.AppendEntity(myLine)
myTrans.AddNewlyCreatedDBObject(myLine, True)
Next
Next
myTrans.Commit()
End Using
End Sub
Let’s take a look at a little more code. First we will add a Function named “DrawLineFunction”. Then we will
create a new Command named “DrawLineTest”. Notice how the DrawLineFunction allows us to specify X, Y,
and Z values for both the Start and End points. Then “DrawLineTest” calls “DrawLineFunction” repeatedly.
<Autodesk.AutoCAD.Runtime.CommandMethod("DrawLineTest")>
Public Sub DrawLineTest()
'draw square first
DrawLineFunction(0, 0, 0, 4, 0, 0)
DrawLineFunction(4, 0, 0, 4, 4, 0)
DrawLineFunction(4, 4, 0, 0, 4, 0)
DrawLineFunction(0, 4, 0, 0, 0, 0)
'now draw corner to corner
DrawLineFunction(0, 0, 0, 4, 4, 0)
DrawLineFunction(0, 4, 0, 4, 0, 0)
End Sub
If we create a Function like “DrawLineFunction” we can call it whenever we need to create a Line and we will
be more productive and our code will be easier to maintain.
The Database
The first thing we need to understand is that an AutoCAD .dwg file is a database. And this database is
organized into Tables and Records.
Layers are in a Table called “LayerTable” with records called “LayerTableRecord”.
If we run this code on a totally new AutoCAD drawing, we will see the following:
If you are familiar with AutoCAD, these names may look like something familiar.
ModelSpace is a BlockTableRecord in an AutoCAD Database.
PaperSpace Layouts are BlockTableRecords in an AutoCAD Database.
If I draw a dimension in my new AutoCAD drawing and run this same command again, we
will see this:
Dimensions are BlockTableRecords in an AutoCAD Database.
XRefs are BlockTableRecords in an AutoCAD Database.
And, as you may have guessed, Blocks are BlockTableRecords in an AutoCAD Database.
Go to this page:
https://knowledge.autodesk.com/support/autocad/downloads/caas/downloads/content/autocad-sample-files.html
Download one of the “Blocks and Tables” dwg files and open it in AutoCAD. If we run this same
GetBTRNames command we will see
Block Extraction
We are going to make a few assumptions here for a few minutes. First off, we are going to be extracting
Blocks from ModelSpace in an AutoCAD file. We are going to copy and past the following Function into our
Add-In:
Public Function GetBlockReferencesInModelSpace(DBin As Database) _
As Dictionary(Of String, List(Of ObjectId))
With this structure, we can look into the Dictionary and pull out whichever block we want to access.
<Autodesk.AutoCAD.Runtime.CommandMethod("WriteBlocksOut")>
Public Sub WriteBlocksOut()
Dim myDB As Database = HostApplicationServices.WorkingDatabase
Dim myBlocks As Dictionary(Of String, List(Of ObjectId)) =
GetBlockReferencesInModelSpace(myDB)
For Each myKVP As KeyValuePair(Of String, List(Of ObjectId)) In myBlocks
If myKVP.Key.ToUpper = "WINDOW" Then
Using myTrans As Transaction = myDB.TransactionManager.StartTransaction
Dim myDesktop As String =
My.Computer.FileSystem.SpecialDirectories.Desktop
Dim myOutput As New IO.StreamWriter(IO.Path.Combine(myDesktop,
"Windows.txt"))
For Each myOID As ObjectId In myKVP.Value
Dim myBRef As BlockReference = myOID.GetObject(OpenMode.ForRead)
myOutput.WriteLine(DateTime.Now.ToString & vbTab &
myKVP.Key & vbTab &
myBRef.Position.X & vbTab &
myBRef.Position.Y & vbTab &
myBRef.Position.Z & vbTab &
myBRef.ScaleFactors.X & vbTab &
myBRef.Rotation)
Next
myOutput.Close()
End Using
End If
Next
End Sub
We will discuss this code in detail during the Lab. If we run this code, a file named “Windows.txt” is created on
our Desktop.
Here’s the magic code that will write the Attributes out.
We are going to copy and paste ‘WriteBlocksOut” and create a new Command named
“WriteBlocksAndAttributesOut”.
<Autodesk.AutoCAD.Runtime.CommandMethod("WriteBlocksAndAttributesOutToExcel")>
Public Sub WriteBlocksAndAttributesOutToExcel()
Dim myDB As Database = HostApplicationServices.WorkingDatabase
Dim myBlocks As Dictionary(Of String, List(Of ObjectId)) =
GetBlockReferencesInModelSpace(myDB)
Now, I understand this is an Introductory Lab. No one would expect anyone else to understand each and
every line of code here. However, if I were to ask you to put the Rotation in column “H” instead of column “G”,
my guess is that you would be able to find that and make that change.
As always, we will add a BreakPoint in our code so when it runs we can stop it and step through it.
By the way, this code assumes Microsoft Excel is installed on the machine it is run on.
This function has been used by a few of our commands thus far. If we break down this declaration’s individual
parts we would find the following:
Public Function—This is Public so it can be called by other pieces of code even outside of the Class in
which this Function resides. It is a Function which means it will be returning some sort of value for us.
GetBlockReferencesInModelSpace—This is the name of the Function.
(DBin As Database)—This Function has one Parameter. It wants a Database Object.
As Dictionary(Of String, List(Of ObjectId))—If we ask for it, this Function will return a Dictionary with a
String for the Key and a List of ObjectIDs as the value.
It may seem a little late in the game to be digging into the anatomy of a Function Call. But there’s a reason
why we’re doing it now.
(DBin As Database)
This Function asks for a Database. If we can give it a Database, it can give us the return value. In the exam-
ples we have worked with thus far, we have been giving it the “WorkingDatabase” which is the database of
the document currently in focus in AutoCAD. But it doesn’t have to be the WorkingDatabase.
We added the Form to our Project for 1 reason only. It’s one of the easiest ways to get a Reference to the
System.Windows.Forms namespace.. And we need that for what we’re about to do.
This is an Introductory Tutorial. IF we can squeeze it in, I would like to introduce you to the power of VB.NET.
In this example, we ask the user to select the file(s) they want to extract. Yes, more than one file can be
selected. Then we go through each of the selected files and open them IN MEMORY only. This means the
code can run very fast because the file does not have to be opened in the editor. And we have removed the
code that is looking just for the Window Block. So we get everything from every file selected.
REVIEW
We have had 90 minutes to provide an Introduction to creating AutoCAD Add-Ins using VB.NET. That’s not a
lot of time. We could have spent that time discussing different variable types. We could have discussed
syntax. We could have discussed a million different things. But we didn’t. We showed the following:
• How to extract block and attribute information through the .NET API
I would love to help you continue on your journey to learning VB.NET Add-In Development. Please email me
and let me know how I can help.
Jerry Winters
jerryw@vbcad.com