Beginning API
Beginning API
Beginning API
October 10, 2008
Program Prototyping
In some of the previous postings I've talked about some of the advantages and disadvantages of the various
languages. One thing I mentioned was the use of VBA to prototype programs. A colleague stopped by my
office earlier today asking for some help with a program he's writing for a customer. Apparently the customer,
and now him, have been struggling with getting the program to work.
Here's a simplified description of what they were trying to do. While working in a drawing that contains
retrieved dimensions they want to be able to get to the associated tolerance information from the part. I didn't
immediately know the answer to this either but was able to figure it out in a couple of minutes. The reason I
was able to do this is because I know how to use VBA as a prototyping tool. The good part is that you can learn
how too. It's an extremely powerful tool when programming Inventor that you can take advantage of
regardless of what language you're writing your program in.
I'll go through the procedure step-by-step that I used to figure out the solution to this specific problem.
Although this looks at a specific case, the principles demonstrated here are generally applicable to any case.
Below is the example for this case for this case which consists of a drawing view with three retrieved
dimensions. Given a dimension we want to get the tolerance information from the associated parameter in
the model.
1. Have Inventor running with the document open that contains the type of data you want to query.
2. Select the object you're interested in. In this case it's one of the dimensions.
3. Open the VBA environment and write the following code. (I would write it in a module in your
application project then you can use it again later.)
Public Sub DebugObject()
Dim oDoc As Document
Set oDoc = ThisApplication.ActiveDocument
Dim oObj As Object
Set oObj = oDoc.SelectSet.Item(1)
Stop
End Sub
4. Run the VBA macro. You'll get an error like the one shown below if there isn't an entity selected. Just
stop the program, select the desired entity and run it again.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 2 of 16
5. The macro will stop execution at the Stop statement. (You could have also put a break in the code but
the Stop statement is convenient.)
6. Right-click the mouse anywhere within the variable oObj and select the "Add Watch..." command.
8. The Watch window should appear, if it wasn't already shown, and the variable "oObj" will be displayed.
The watch window shows three interesting things; Expression, Value, and Type. The expression is the
variable or property we're watching, the value is the value of that expression, and the type is the type of
the variable or object the expression results in. In this example we can see the type of oObj is a
DiameterGeneralDimension. You'll often see object types prefixed with "IRx" and you can just ignore the
prefix. The Value is empty because a DiameterGeneralDimension doesn't have an explicit value.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 3 of 16
9. Click on the "+" next to oObj to expand the object. Now all of the properties of the
DiameterGeneralDimension are displayed. Each property also shows it's value and type. Some of the
properties return objects and have a "+" next to them so you can expand them and see the properties
associated with that object. In this case there are two properties that are interesting for the problem we're
trying to solve; Retrieved and RetrievedFrom. The Retrieved property indicates if this drawing
dimension was created by retrieving a dimension from the model. You can see in the debug window that
the value is True for the currently selected dimension. The RetrievedFrom property returns the model
dimension this was retrieved from. In this case the type of object returned is a FeatureDimension.
10. Expanding the RetrievedFrom property you see the properties of the FeatureDimension object. One of
these is the Parameter property which returns a ModelParameter object. Expanding this we can see the
Tolerance property. Finally, expanding on this we can see the upper and lower tolerance values. All of
this is shown below.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 4 of 16
11. Here's the corresponding code that was written based on what was learned from the debugger window.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 5 of 16
End If
End Sub
The specifics of what the code is doing in this case isn't important but the method we used to arrived at this
code is. The debug window provides a "live" view of the object model that you can traverse through to see how
objects are connected through their various properties. Anytime you want to investigate how to use the API to
access a certain object or to get to particular information.
When VBA was integrated into Inventor we looked at other VBA integrations for ideas. All of the applications
that supported VBA that I had used at the time all used the idea of document projects so it seemed like that
was something we needed to provide as part of Inventor's implementation. However, when I had used some
of these applications that only had document projects I didn't like them because it made maintaining code
almost impossible. For example, I was writing a reasonably large program in one of the applications and it
was stored within a document. I would copy that document to use the program with other sets of data. When
I wanted to make a fix or enhancement to the program I had multiple copies of it and didn't know which
version of the program existed where. As a result of this frustration we also added support for external
projects in Inventor's implementation of VBA.
A feature of the document macros that Word and Excel supported that seemed good was the idea of automatic
macros. These are macros with a particular name that are run automatically when something happens in the
application. For example, when a document is opened or saved a macro is run. This functionality makes it
very easy for someone with limited programming experience to write a simple macro to respond to these
events in Inventor.
A couple of releases after we added VBA to Inventor we started getting reports of some problems. The
problem turned out to be a resource issue with VBA. People were creating document projects that used
automatic macros and were using these Inventor documents that contained these projects as their templates.
That meant that every file they created had a VBA document project. When a large assembly is loaded all of
the referenced documents are also loaded, and in the case of these documents also meant loading the
embedded VBA projects. It turns out that VBA has a limit to the number of VBA projects that can be loaded.
The other significant problem to having document macros in a template is that it creates the problem I already
talked about of having your program duplicated in all your documents making it very difficult to fix or
enhance that program. There is also another problem that recently came up with document projects and 64
bit Inventor.
My advice is: DO NOT USE document projects. The one exception to this is if you're writing a program
that is very specific to a single document. For example if you have a part and write a specific program to work
with only that part. In this case it's convenient to package the program with the document rather than worry
about passing an additional file with it.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 6 of 16
External VBA projects should provide most of the functionality you would want and also provide the
additional capability that you can create toolbar buttons to run the macros contained within them. What
external VBA projects don't provide is the ability to do the equivalent of automatic macros. The best answer
for this is to create an Add-In. (There have been some Add-In utilities written that add support for automatic
macros to VBA external projects but I've found for most people that these end up being confusing because
they don't understand how they work and as a result don't know how to debug and diagnose problems when
they occur.) An Add-In allows you to do anything you could do in VBA and more. The downside of an Add-In
is that there's a higher learning curve to getting started.
In my next posting I'll cover what's required to create an Add-In that replaces an existing automatic macro.
Posted at 11:34 AM in Beginning API, Visual Basic for Applications (VBA) | Permalink | Comments (1) |
TrackBack (0)
How you reference the API and access the Application object will differ slightly for the different languages.
These are discussed below along with example code that demonstrates getting the Application object and
calling its Caption property.
Inventor’s VBA
Because the VBA that’s delivered with Inventor is integrated with Inventor, it provides the easiest access to
Inventor’s object model. In Inventor's VBA, the Inventor API library is already referenced and it provides an
easy way of accessing the Application object by providing a global property called ThisApplication, which
returns the Application object. All you need to display Inventor’s caption with Inventor’s VBA is the code
below.
MsgBox ThisApplication.Caption
External Application
External Application refers to any application that runs outside of Inventor. Typically these are Windows
applications (.exe programs) but this also includes VBA programs written using VBA in another application
(i.e. Word or Excel). This term does not refer to Add-In applications.
How you Reference Inventor’s API varies for each of the programming environments and is discussed below
for each one. The mechanics of gaining access to the Application object also varies with the different
programming languages; however, for all languages there are two basic ways to connect. The first is to see if
Inventor is running and get the Application object associated with it. The second is to start Inventor and get
the associated Application object. Both are useful and which one to use depends on what you’re trying to
accomplish. Connecting to a running instance of Inventor is probably the most common. Starting Inventor is
common for batch processing types of programs.
VBA / VB 6
Referencing the API
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 7 of 16
Use the “References…” command (in the Tools menu in VBA and the Project menu in VB 6) to add a reference
to Inventor’s object library, as shown below.
MsgBox inventorApp.Caption
MsgBox inventorApp.Caption
VB.Net
Referencing the API
The .Net languages use something called an interop assembly to be able to call a COM Automation API. With
Inventor 2009, Inventor installs an interop assembly (Primary Interop Assembly or PIA) for all developers to
use. You reference this into your application using the “Add Reference…” command and selecting
Autodesk.Inventor.Interop from the .Net tab as shown below.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 8 of 16
For versions of Inventor previous to Inventor 2009 you need to select “Autodesk Inventor Object Library”
from the COM tab of the Add Reference dialog. This will generate a local interop assembly for your project.
Referencing the Inventor Object Library in VB.Net (Inventor 2008 and earlier)
MsgBox(inventorApp.Caption)
Starting an Instance of Inventor
Dim inventorApp As Inventor.Application
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 9 of 16
Try
inventorApp = CreateObject("Inventor.Application")
Catch ex As Exception
MsgBox("Error starting Inventor.")
Exit Sub
End Try
inventorApp.Visible = True
MsgBox(inventorApp.Caption)
C#
Referencing the API
Referencing the API in a C# application is exactly the same as for Visual Basic and the instructions above
apply. You'll need to add the following to the top of your project.
using System.Runtime.InteropServices;
MessageBox.Show(inventorApp.Caption);
try
{
// Start Inventor.
System.Type oType = System.Type.GetTypeFromProgID("Inventor.Application");
inventorApp = (Inventor.Application)System.Activator.CreateInstance(oType);
MessageBox.Show(inventorApp.Caption);
Visual C++
Referencing the API
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 10 of 16
Referencing the API for an unmanaged VC++ project is done by including a header file provided by Inventor’s
SDK. This header file imports Inventor’s object library and includes some other useful header files.
#include "InventorUtils.h"
Connecting to a Running Instance of Inventor
There are different flavors of VC++ (managed and unmanaged) and different ways to use Inventor’s API from
VC++. The samples below represent one style.
HRESULT Result = NOERROR;
CLSID inventorClsid;
Result = CLSIDFromProgID (L"Inventor.Application", &inventorClsid);
if (FAILED(Result)) return Result;
CComPtr pInventorAppUknown;
Result = ::GetActiveObject (inventorClsid, NULL, &pInventorAppUknown);
if (FAILED (Result)){
MessageBox(0, _T("Could not connect to Inventor."), _T("Error"), 0);
return Result;
}
CLSID inventorClsid;
Result = CLSIDFromProgID (L"Inventor.Application", &inventorClsid);
if (FAILED(Result)) return Result;
CComPtr pInventorAppUknown;
Result = CoCreateInstance(inventorClsid, NULL, CLSCTX_LOCAL_SERVER,
__uuidof(IUnknown), (void **) &pInventorAppUknown);
if (FAILED (Result)) {
MessageBox(0, _T("Could not start Inventor."), _T("Error"), 0);
return Result;
}
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 11 of 16
if (SUCCEEDED(Result))
MessageBox(0, bstrCaption, _T("Inventor Caption"), 0);
The Object Model is an important concept to understand in order user the API. The API objects are linked
together in a logical way. In order to get a certain object you need to understand how they're linked because
you'll need to go from one object to another to get to a specific object. The structure of the objects is referred
to as the object model. The object model is typically represented as a hierarchal chart that shows the
relationship between objects. If you’re familiar with C++ class diagrams, this IS NOT the same as that. It does
not show a class hierarchy but illustrates an ownership hierarchy. For example, a dimension constraint is
owned by a sketch, it's not derived from the sketch. If you have a reference to an API object you should be
able to traverse the object model to access any other object as long as you understand the structure of the
object model.
There are a few tools available to help you view and understand this object model:
Object Model Chart – This is a chart that illustrates the object hierarchy. It’s most useful in a hard
copy form because of it's size it's hard to view on a computer screen. Initially, it can look a bit
overwhelming because there are so many objects but because you’ll typically just be using a few objects
within a certain area of the API you'll end up learning it in small pieces.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 12 of 16
This chart is delivered as part of the Inventor API SDK (Software Development Kit) but you can also
download it here.
Online Help – Part of the programming help that’s delivered with Inventor contains a description of
every object along with details about the methods, properties, and events each object supports. You access
the programming help from the Help menu in Inventor.
Object Browser – The object browser is a user-interface for viewing the objects and their associated
methods and properties. Object browsers exist in various forms in the different languages but the object
browser that's part of VBA is probably the best for viewing Inventor's objects. From within VBA you show
the object browser by running the Object Browser command (F2). The drop-down in the upper-left of the
Object Browser dialog lets you choose which programming library you want to view. The field below that
allows you to search the library. The dialog contains two main areas. The one of the left is a list of all of
the objects in the selected library. When you select an object, the area on the right shows the methods and
properties of that object. Selecting a method or property will display specific information about it at the
bottom of the dialog.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 13 of 16
VBA Debugger – The VBA debugger is also useful outside of the normal context of debugging a
program. Because of VBA’s support of COM Automation it allows you to examine live objects and their
properties while traversing through multiple levels of the object model. This is an extremely powerful and
useful tool no matter what language you’re using, and well worth learning how to use.
1. Have Inventor running and a part open that contains a few features.
2. Open Inventor's VBA development environment (Alt-F11).
3. Double-click on a module in a project to open a code window. In the picture below it's Module1 from
the ApplicationProject.
4. Create the Sub as shown in the picture below.
5. Position the cursor anywhere within the Sub you just wrote and press F8 to start debugging.
6. Right-click the mouse over ThisApplication and choose "Add Watch..." from the context menu. Click
OK on the Add Watch dialog.
7. VBA will open the Watches window with the variable you selected displayed in the window, as shown
below. The object shown in this example is the Application object. The Application object represents
the entire Inventor application and is the top most object in the object model. You can click the "+"
next to the name to expand the object to show its properties. Each property shows its current value,
or if the property returns another object it will have a "+" next to it. You can traverse through the
hierarchy by expanding the plus signs.
This provides a live view of the object model. In the example below, the ActiveDocument property is
expanded to show the currently active document. For a part, most of the interesting information is
contained within an object called PartComponentDefinition which is returned by the
ComponentDefinition property of the PartDocument. You'll see this object provides access to
parameters, features, and other part related objects. Playing with this, along with the object model
chart, you can get a better understanding of the object model.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 14 of 16
When programming Inventor, Inventor doesn’t care which language you use. Inventor exposes its
programming interface using Microsoft technology called COM Automation. This technology provides a
formalized way to describe the details of a programming interface in a generic way. When you call an Inventor
API function the call goes through this Automation interface and when Inventor receives the call it doesn’t
even know what programming language the call came from. The only language requirement when
programming Inventor is that it supports COM Automation, which most languages do.
My reason for recommending VBA is because VBA was designed specifically for programming COM
Automation interfaces. Because of this there are two big advantages to using VBA; the Object Browser and
debugging. The Object Browser is a tool within VBA that allows you to look at the objects and functions
provided by an API. Other languages also provide object browsing functionality but they don’t work as well as
the VBA browser for viewing COM Automation interfaces. As far as debugging, almost all languages support
the ability to debug your programs; however VBA supports better debugging a COM Automation interface by
allowing you to view more details about objects. Another point in VBA’s favor is that’s it integrated with
Inventor, which means if you have Inventor you have VBA. This integration also makes it easier to access
Inventor’s API than when using any other language. One other advantage is that the API samples in the
online help are currently all written in VBA.
All of the reasons I’ve listed above make VBA an easier language to use when learning the API and even later
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 15 of 16
when prototyping and investigating the capabilities of the API. No matter what your programming experience
and language preferences I highly recommend gaining a basic understanding of VBA because I believe it will
benefit your overall programming efficiency when programming Inventor’s API. You can think of VBA as a
style of pseudo-code that you can run and test. The API principles you learn with VBA aren't language specific
and are easily transferred to any other language.
Even with the advantages of using VBA discussed above, I don’t recommend VBA for writing an Application.
It's ok for small macros but for larger work there are better choices. All languages have pros and cons and
VBA’s cons don’t make it the best language for writing applications. My current personal choice for writing
applications is Visual Basic .Net, which Visual Basic 2008 is the most current version. My choice of Visual
Basic over most of the other available languages is primarily personal preference but there are a couple of
reasons I would also recommend it to a newer programmer. First, it provides an easier upgrade path from
VBA and second, I believe it is easier to use than the other languages.
One version of Visual Basic worth spending a little time discussing here is Visual Basic 6. Many of the existing
larger samples provided with Inventor's SDK were written using VB 6. This is an older version of the Visual
Basic language and has many of the same advantages as VBA since it uses the same underlying engine. It was
made to program COM Automation types of programming interfaces and has the same object browser and
debugging support that VBA has. A big problem with VB 6 is that it has been discontinued and is no longer
available from Microsoft. It also does not support writing applications for 64 bit Windows. If you’re going to
make the effort to learn a programming language it doesn’t seem very good to spend your time learning and
writing a lot of code with an obsolete language. Becuase of that I can’t recommend using VB 6.
The .Net languages, C# and Visual Basic, both support COM Automation programming. Even though they
both have the object browser tool and support debugging they don't work as well as they do in VBA. However,
they have a lot of other advantages over VBA (and VB 6) that makes them a better choice for larger application
development. Whether you choose Visual Basic or C# is really just personal preference.
The other popular language, primarily with professional developers, is Visual C++. Visual C++ is a very
powerful language but is also difficult to learn and use. It supports programming a COM Automation
interface but is significantly harder than either Visual Basic or C# to use. If you choose to use Visual C++ you
can expect a higher learning curve and longer development times.
Finally, there are a few fringe languages. Some of these have been around for a long time, (i.e. Delphi), and
others are relatively new (i.e. Python). As I said earlier, Inventor doesn’t know or care what language you’re
using and you can use whatever you choose. However, you’ll have a hard time finding any samples or support
when using these languages. For me, they’re interesting to look at but at this point I would be hesitant to
begin a large development project using any of them.
No matter what language you choose I still recommend using VBA for prototyping investigating the API. For
the rest of this series of articles I’ll be using VBA to demonstrate the use of the API. Where there are actual
differences when using other languages with Inventor’s API, I’ll try and have code that demonstrates those
differences and what’s needed in the various languages to get things to work.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010
Mod the Machine: Beginning API Page 16 of 16
the series occasionally with various other topics that are usually more advanced or that I find interesting at the
moment. This post is the first in the getting started series. Here is the process I would suggest for anyone
wanting to program Inventor.
1. Learn how to use Inventor interactively. This is more important than you might think. Most of
Inventor’s programming interface is just an alternative way of doing the same things you do interactively
through the user-interface. For example, if you create an extrude feature through the user-interface you
see the required input; profile, solid or surface output, operation, extent information, and taper angle.
You supply all of this information through the Extrude dialog and by interacting with the model. To
create an Extrude through the API you call a method that has exactly the same type of input. The same
set of information is being gathered by both the command (user-interface) and the programming
interface and then both interfaces end up calling the same internal function to create the actual extrusion.
Understanding how Inventor works and the requirements for the various commands is easiest to learn
through the user-interface. Since these same concepts also apply when using the programming interface
it will make learning the programming interface much easier.
2. Choose and learn a programming language. To effectively program you need to have a basic
understanding of the programming language you’re using. To effectively customize Inventor you DO
NOT need to be an expert in that language. Any language has a lot of features and intricacies that you
could spend more time than most of us have learning them. A basic understanding of the language
should be enough. In my next posting I’ll discuss several different languages and the pros and cons of
each.
3. Begin learning Inventor’s programming interface. There are some basic concepts to learn to get started
and then you can expand into different functional areas of Inventor. You don’t need to learn the entire
API at once. Looking at different areas of the Inventor's API will be a running theme of this blog.
So, for now just keep working with Inventor and we’ll look at programming languages next time.
http://modthemachine.typepad.com/my_weblog/begging-api/ 28/9/2010