You are on page 1of 23

December 2-5, 2003 MGM Grand Hotel Las Vegas

Customizing Autodesk Inventor: A Beginner's Guide to the API


Course ID: MA31-4 Speaker Name: Brian Ekins Course Outline:
This class is an introduction to using programming capabilities to customize and add new features to Autodesk Inventor. The class focuses on using the VBA development environment built into Autodesk Inventor and assumes no prior programming experience. Concepts will be demonstrated and discussed and the class notes will reinforce the concepts taught. A strong emphasis is placed on using the VBA tools and online help provided with Autodesk Inventor so that you can use these later to find information and successfully solve problems on your own. Introduction to VBA VBAs Development Environment VBA Projects Whats so visual about Visual Basic? Object-Oriented Programming Writing VBA Code Sample Program 1 Inventors API Sample Program 2 Running Macros Learning more about the Inventor API

About the Speaker:


Brian is a software engineer at Autodesk where he served for 4 years as the API product designer for Autodesk Inventor. He is currently working in Autodesk Professional Services where he supports developers using Inventors API and consults and writes custom applications for Inventor customers. Brian has worked exclusively in the CAD industry for the past 20 years and has designed and used the APIs for other CAD applications.

Customizing Autodesk Inventor: a Beginner's Guide to the API

Introduction to VBA
Visual Basic for Applications, or VBA as it is commonly called, is a programming environment developed by Microsoft. Microsoft makes it available for companies to integrate into their applications. VBA is part of the Visual Basic family of programming tools. Below is a brief description of each of the members of the Visual Basic family.

Visual Basic 6
Visual Basic is the world's most widely used application development tool for creating standalone software components. Visual Basic must be purchased separately and is available in three editions: Learning edition, Professional edition, and Enterprise edition. The Professional and Enterprise editions are both suitable for programming Inventor. Some functionality is excluded from the Learning edition that will preclude you from taking full advantage of the Inventor API. If you want to write applications, VBA is probably insufficient and you should purchase a copy of Visual Basic. The Professional edition is adequate for almost all applications.

Visual Basic .Net


Visual Basic .Net is the latest version of Visual Basic and introduces the biggest changes in the language since it was introduced. Although it is very similar to Visual Basic 6, many people consider it a new language. Visual Basic .Net and the other .Net languages (C# and VC++) are not yet officially supported for Inventor. Because of the way Inventor exposes its API, these languages should just automatically work with Inventor. The reason theyre not supported at this time is that they have not been fully tested with Inventor and the documentation and tools have not been updated to show the use of the .Net languages with Inventor.

Visual Basic Scripting Edition


VB Script is designed to offer lightweight scripting capabilities for low-memory environments such as Web browsers and is most commonly used in creating HTML Web pages. VB Script is not very well suited for programming Inventor.

Visual Basic for Applications (VBA)


VBA provides the Visual Basic programming environment within an application. Microsoft uses VBA in most of its own applications, (Word, Excel, Access, etc.) and it is used by over 100 other popular applications including AutoCAD and Inventor. VBA uses the same engine as Visual Basic 6. Using VBA is very similar to programming in Visual Basic 6. VBA is primarily for creating macros. A macro is typically defined as a program that automates repetitive tasks. Just because VBA is designed for macro writing does not limit it to writing simple programs. VBA can be used for very sophisticated programs that provide elaborate user interfaces and interact with other applications. Because VBA is bundled with Inventor, every Inventor user has access to the VBA programming environment without the expense of buying additional software. Having a common programming environment supported by many different applications is a distinct advantage to you because the VBA experience you gain while working with Inventor is also applicable when programming any other VBA enabled application.

VBAs Development Environment


From within Inventor you activate VBAs development environment using the Visual Basic Editor command in the Tools menu, as shown to the right. (You can also use the short cut key Alt+F11.)

Customizing Autodesk Inventor: a Beginner's Guide to the API

The VBA IDE (Integrated Development Environment) is VBAs user interface. The IDE is provided in a separate window from Inventor. The various components of the VBA development environment are shown and described below.

2 5 4

1. Menus and toolbars. Like other Windows applications, VBA provides access to commands through menus and toolbars. The Standard, Debug, and Edit toolbars are shown displayed in the figure above. 2. The Project Explorer displays a hierarchical list of the projects and all of the items contained in and referenced by each of the projects. 3. The Properties window lists the design-time properties for selected objects and their current settings. You can change these properties at design time. 4. The Code window is where you write, display, and edit Visual Basic code. You can open as many Code windows as you have modules, so you can easily view the code in different forms or modules, and copy and paste between them. 5. The UserForm window allows you to create the forms and dialogs of your project. 6. The Toolbox displays the standard Visual Basic controls plus any ActiveX controls and insertable objects you have added to your project. 7. The Immediate window allows you to type or paste a line of code and press ENTER to run it. The result of Debug.Print statements is also displayed in the immediate window. 8. The Watch window allows you to view the current value of specified expressions.

Customizing Autodesk Inventor: a Beginner's Guide to the API

Options
Most of the default values for VBAs options settings are good, but there are a couple that I recommend changing. To change these use the Options command in the Tools menu, which displays the Options dialog shown below. I recommend turning off Auto Syntax Check, and turning on Require Variable Declaration, as shown below. These will only need to be set once because VBA will remember the settings for subsequent sessions.

VBA Projects
VBA uses projects to help you manage the programs you create. The Project Explorer provides a tree view that allows you to view and manage the contents of a project. The Project Explorer displayed to the right shows us that three projects are currently open; ApplicationProject, DocumentProject (Part8), and MyMacros. There can be any number of projects open at once, but typically all the forms and code associated with a particular program are contained within a single project. Within a project, there are three types of components; forms, code modules, and class modules. A project can contain any number of these components. Well look at these in more detail later. Inventor has two basic types of projects; document and external projects. The primary difference between the two types being where they are saved. A document project is a VBA project that is embedded within an Inventor document. Every Inventor document has a single VBA project associated with it. Having a project associated with the Inventor document allows you to write code that is specific to that document and easily keep the code with the document it applies to. An external project is a project thats saved in a file of its own. This file is known as an Inventor VBA file and uses the .ivb extension. External projects are typically used for programs that provide general functionality that might be used within multiple documents. For example, a program that helps to control the visibility of parts within an assembly can be useful in any assembly. Theres also one special external project that is known as the default or Application VBA project. Inventor allows you to specify one external project as the default VBA project. The default VBA project is loaded automatically every time Inventor is run, while other external projects must be loaded manually. By putting frequently used programs within the default VBA project, they will always be available. You define which external project is the default VBA project using the Default VBA Project on the File tab of the Application Options command within the Tools menu.

Customizing Autodesk Inventor: a Beginner's Guide to the API

Whats so visual about Visual Basic?


An important part of Visual Basics enormous success is that it provides an easy to use interface for creating Windows applications. A key component of any Windows application is the user-interface. VBA allows you to graphically design your user-interface in a way thats more like using a graphics application than a programming environment.

Forms and Controls


An important user-interface element used in almost all Windows applications are dialogs. Within VBA all graphical user-interfaces are created using forms. A form is an area where you lay out the various controls that you need for your application. The Toolbox contains the set of controls that are available to be placed on the form. Controls are things like text boxes, buttons, check boxes, labels, pictures, etc. VBA has a set of standard controls, but you can also import additional ActiveX controls and use them on your forms for more advanced features. (Using Visual Basic (not VBA) you can also create your own controls.) The figure to the right shows a form that contains one of each of the standard VBA controls and the Toolbox.

Object-Oriented Programming
An important concept when using VBA is Object-Oriented Programming (OOP). To explain, lets get started by creating a simple VBA program and learn as we go. Lets create this program within the default VBA project. To do this click on the project named Application Project in the project explorer window. This activates that project so any forms or modules created will be inserted into that project. To create a new form, use the UserForm command from the Insert menu as shown below.

This creates a new form in the current project and displays it in the development environment. An icon is also created for it in the Project Explorer. When any new object is created, (a form is an object), it is given a default set of properties. You can edit these properties to give the object the look and behavior you desire. Learning about properties leads us into a brief discussion of object oriented programming. The basics of object-oriented programming are actually quite simple to understand because the concepts more closely parallel the real world than other programming techniques. For example, instead of a program that consists of a bunch of functions and variables, an object oriented program is made up of objects that have defined behaviors. These can be objects that youve defined or you can reuse predefined objects that someone else created.

Customizing Autodesk Inventor: a Beginner's Guide to the API

Lets look first at a real-world example of an object and see how object oriented programming terminology can be used to describe it. A company that sells chairs might allow a customer to design their own chair by filling out an order form, like the one shown below, that describes the chair they want.

The options on the order form define the various properties of the desired chair. By setting the properties to the desired values the customer is able to describe the specific chair they want. In addition to properties, objects also support methods. Methods are basically instructions that the object understands. In the real world these are actions you would perform with the chair. For example, you could move the chair, cause it to fold up, or throw it in the trash. In the programming world the objects are smarter and instead of you performing the action you can tell the object to perform the action itself. A third aspect of objects is that they can support events. In the real-world events would be equivalent to installing sensors on an object to track when certain things happen to the object. For example, you can attach a sensor to the seat of the chair to be notified whenever anyone sits on it. One final concept of object-oriented programming is that of a class. Going back to the chair object, you can think of the class as the order form the customer can fill out to describe the specific chair they want. A class isnt the object itself but the template that defines all the properties, methods, and events of a particular type of object. For example, using the chair order form you can order two different styles of chairs by defining different properties for each chair. The order form represents the class and the chair is the object, or an instance of the class. Now well look at objects in VBA. In VBA, a form and all the controls you place on a form are objects. These objects have properties, methods, and events. Each type of object has different properties, just like the properties that describe a chair would be different from those used to describe a swimming pool. For example, a button control has properties that specify the text, font, size, position, color, etc. The properties of an object are accessed by selecting the object on the form. This causes the objects properties to be shown in the Properties window, as shown to the right. Editing any of the properties using the Properties window causes the associated control to visibly change. One common property of all VBA control objects is the Name property. The Name property is the unique identifier for a control object and is used to reference a specific control object in your program, which well see demonstrated in the next section. When you create an object, VBA assigns it a default name but its usually best to rename the object to better describe its use in your program. For example, instead of the default name of CommandButton1 you might rename the button to be cmdOK or cmdCancel depending on what the button will be used for. A common naming practice is to append the name with some characters that help describe the object type. This is known as Hungarian notation. In the previous example cmd was used to denote that the object is a command button. VBA doesnt care what the names of the controls are as long as they

Customizing Autodesk Inventor: a Beginner's Guide to the API

are unique, but it makes your code more readable and easier to write by following these conventions, but its up to you. Some typical Hungarian notation characters for different controls are shown below. Command button cmd Text box txt Combo box cbo Label lbl List box lst Check box chk Option button opt Image control img Form frm

For this sample, well create a simple dialog that allows you to specify a value. The value is defined by entering the value directly within a text box. The completed dialog is shown below.

This dialog contains one text box, with a label to identify to the end-user what its for. It has another label at the bottom of the dialog to display messages. Finally, it has two buttons: one that will do something with the current value and the other to dismiss the dialog. These were all placed onto the form using the Toolbox and graphically arranging them on the dialog. The properties of the form and the controls were edited to the values shown below. Form Name frmValue Caption Value Definition Label Caption Value: Label Name lblResult Caption Result: 0 Text Box Name txtValue Text 0 Command Button Name cmdApply Caption Apply Command Button Name cmdCancel Caption Cancel

This completes the visual portion of this sample. The form can be run and visually tested at this point by clicking on the form to make it the active object then clicking the Run Macro command as shown to the right. When the form is running you can interact with all the controls, but since theres not any code to instruct it what to do it doesnt do anything useful yet. The coding step of creating a VBA program adds the intelligence of what happens when the user interacts with the controls. Weve looked briefly at the visual portion of writing a program and although its simple to place controls on a form, the visual part of creating a program is critical to an easy to use application because it is the only part of the program that the end-user actually sees and works with.

Writing VBA Code


Now well start writing the code that adds the intelligence behind the user-interface. Windows programs with a form user-interface they dont have a predefined workflow, (at least for the portion of the program that gathers the input from the end-user). Because were using a form to gather input, the user is not forced to follow a predefined sequence to enter the information but can interact with the controls on the form in any order they want. Because of this the code is written to respond to the end-user. This is done by responding to events that the controls generate as the user interacts with them.

Customizing Autodesk Inventor: a Beginner's Guide to the API

Lets look at the code for this specific example and then well look at VBA coding in general. To create code that will handle an event from a control, first select the form from the Project Explorer and click the View Code button at the top of the Project Explorer, as shown to the right. This will open a code window for that module, as shown below. At the top of the code window there are two combo boxes. The one on the left provides a list of available objects, and the one on the right displays the available events for the selected object. In the figure below, the text box txtValue has been chosen and the Change event for it has been selected. VBA automatically creates the sub that will be called whenever the value of the text box changes. You can now add code to this sub to define what happens for this event.

Before looking in detail at adding code to this sub lets step back and discuss some of the basic building blocks of a VB/VBA program.

Subs and Functions


Subs and Functions are a way to group a set of related code so that it can be conveniently executed and reused as needed. Events are also Subs and can be called the same way as any other Sub, but theyre special in that VBA knows to call them when their associated action occurs. You can also create your own Subs and Functions. Below are several examples of different Subs and Functions along with an explanation of the Sub or Function definition.
Sub StartDiet() MsgBox "Time to stop eating." End Sub

The StartDiet sub is a sub with no arguments. This type of Sub is also known as a macro because it can be called directly from Inventor. Subs with no arguments are used to execute a process that doesnt require any information and doesnt return anything back to the caller.
Sub ShowDate(InDate As Date) MsgBox Format(InDate, "dddd, mmm d, yyyy") End Sub

The ShowDate sub is a sub with a single argument. In this case, a date is passed in and then the Sub displays the date to the end-user.
Sub ShowDate2(InDate As Date) MsgBox Format(InDate, "dddd, mmm d, yyyy") InDate = DateAdd("d", 1, InDate) End Sub

The ShowDate2 sub is similar to the ShowDate sub expect that it changes the date that was passed in by incrementing it by one day. Its best to be explicit in the declarations of the sub and specify which arguments are meant for input and which are meant for output. This is done using the ByVal and ByRef keywords. An argument that is declared using ByVal is an input only argument and if the value is changed within the sub the change is only within the sub and the modified value is not passed back to the caller. If an argument is not declared specifically as ByVal or ByRef then it defaults to ByRef, as in the previous examples. A ByRef argument can be changed within the sub or function and the modified value will be passed back to the caller. The following is a more explicit declaration for the earlier ShowDate sub.

Customizing Autodesk Inventor: a Beginner's Guide to the API Sub ShowDate(ByVal InDate As Date) MsgBox Format(InDate, "dddd, mmm d, yyyy") End Sub

Frequently, subs are used when there are multiple outputs required, as in the following example. In the GetEngineInfo Sub below, the EngineName argument is the input and the rest of the arguments are the returned values. (The _ at the end of the first line indicates the line continues onto the next line.)
Sub GetEngineInfo(ByVal EngineName As String, HorsePower As Integer, _ Cylinders As Integer, CCs As Double, Torque As Double) Select Case EngineName Case "Ford 250" HorsePower = 250 Cylinders = 6 CCs = 50 Torque = 950 Case "Ford 350" HorsePower = 350 Cylinders = 8 CCs = 75 Torque = 1350 End Select End Sub

Functions are similar to subs except that functions have a return value for the function itself. Below is a sub and a function that perform the same thing; they both tell whether today is Wednesday or not.
Sub IsWednesday(Yes As Boolean) If Format(Now, "dddd") = "Wednesday" Then Yes = True Else Yes = False End If End Sub Function IsWednesday() As Boolean If Format(Now, "dddd") = "Wednesday" Then IsWednesday = True Else IsWednesday = False End If End Function

Lets look at the small differences between the sub and function. The sub has one argument to allow the result to be passed back. The Function doesnt have an argument because the function itself will return a value. The declaration is different than the sub because the function is specified as a type. The only other difference is which variable within the function or sub is set to the return value. In the case of the sub, the input argument is set to the correct value so it can be passed back. In the case of the function, the name of the function is used as the variable thats set to the return value. Now, to see why you would choose a function over a sub lets look at the code that calls the sub. It first declares a variable in order to save the return value. Then it uses the return value.
Dim ItsWednesday As Boolean Call IsWednesday(ItsWednesday) If ItsWednesday Then MsgBox "It's Wednesday" End If

To call the function that performs the same thing there is no variable declaration but the function is called directly and the result of the call can be immediately used.
If IsWednesday Then MsgBox "It's Wednesday" End If

You can see that the function call is much more readable than the call to the sub. This makes your code easier to read and maintain.

Customizing Autodesk Inventor: a Beginner's Guide to the API

Function calls can also have arguments and those arguments can be both input and output. One way this can be useful is to use the return value of the function to signify if the function was successful or not. In the call to the GetFeatureInfo function below, it passes in a feature name and some information from the feature is returned. The return value of the function is True if the call was successful and False if it failed. This could have also been accomplished with a sub but would have resulted in more code and would be more difficult to read, just as in the previous example.
If GetFeatureInfo("Hole1", Size, IsCounterBore, Depth) then ' Do something with the hole. Else ' The specified hole doesnt exist. End If

The declaration of the GetHoleInfo function is shown below.


Function GetHoleInfo(ByVal Name As String, Size As Double, _ IsConterBore As Boolean, Depth As Double) As Boolean

The use of functions is also obvious in the case where you have one or more input values and a single output value, which is the case for most math functions. For example, below is a function that converts inches to centimeters.
Function InchesToCm(ByVal Inches As Double) As Double InchesToCm = Inches * 2.54 End Function

The use of this function in a call is shown below.


MsgBox "5 inches = " & InchesToCm(5) & " cm"

Variables
VBA supports several different variable types. Below is a list of the most commonly used variable types. Integer A whole value in the range of -32,768 to 32,767 Long A whole value in the range of -2,147,483,648 to 2,147,483,647 Double A floating point value in the range of -1.79769313486231E308 to -4.94065645841247E-324 for negative values; 4.94065645841247E-324 to 1.79769313486232E308 for positive values String A character string of 0 to approximately 2 billion characters. Date - January 1, 100 to December 31, 9999 Boolean True or False Object Any object reference. Variant A type that can be used for any of the other variable types. Variables are declared within a Sub or Function using the Dim statement. For example
Dim Counter As Integer

This creates a variable called Counter that is of the type Integer. If you dont specify a type, VBA will automatically create it as a Variant, as in the example below. Its best to use specific types for your variables instead of using Variants. This results in more efficient code and is easier to read and maintain.
Dim Counter

You need to be careful when creating multiple variables within a single Dim statement, like that shown below.
Dim Age, Height As Double

In the previous statement it looks like two variables were declared as the type Double. In reality, Height is type Double, but Age is type Variant since its type was not specifically stated. To declare them both as Double the following can be used.
Dim Age As Double, Height As Double

Its safer to declare a single variable per line, as shown below, to avoid this common mistake.
Dim Age As Double Dim Height As Double

10

Customizing Autodesk Inventor: a Beginner's Guide to the API

Scope
Scope is an important topic that surprisingly many existing VBA developers do not have a good understanding of. This is because in most cases youll tend to naturally declare variables in the correct location so scope does not become an issue. But its best to understand this from the beginning so you dont run into problems later. Scope is the ability to control how visible a variable, function, or sub is to other functions or subs. There are two things that control the scope of a variable, function, or sub; where it is declared and how it is declared.

Scope for Variables in Code Modules


The following illustrates two different code modules that exist within the same project. Module 1 contains the definition of a function and Module 2 uses the function. Notice that the variable Height is declared outside of any sub or function. A variable declared this way is called a global variable and is accessible from anywhere within that module and depending on how its declared, anywhere within the project. In this example the variable Height is available from anywhere in the project, so its referred to as having project scope. The Function CheckHeight is also available from anywhere in the project. The HeightStuff sub illustrates this by calling the CheckHeight function and using the Height variable. The variable NewHeight within the CheckHeight function is only available within the CheckHeight function. It has function scope. Module 1
Dim Height As Double Function CheckHeight() As Boolean Dim NewHeight As Double NewHeight = GetCurrentHeight If NewHeight > Height Then CheckHeight = True Else CheckHeight = False End If End Sub

Module 2
Sub HeightStuff() If CheckHeight Then MsgBox "Height: " & Height End If End Sub

This variable and function could also be declared differently to control and limit their scope. The modified version is shown below. In this case, the declaration of the global variable Height was done using the keyword Private instead of Dim. Using Private limits the scope of the variable to within the module it is declared within. Using the Private keyword for the declaration of the CheckHeight function also limits its scope to within the module its declared within. The code in Module 2 will now fail because its unable to see either the variable Height or the function CheckHeight. Module 1
Private Height As Double Private Function CheckHeight() As Boolean Dim NewHeight As Double NewHeight = GetCurrentHeight If NewHeight > Height Then CheckHeight = True Else CheckHeight = False End If End Sub

Module 2
Sub HeightStuff() If CheckHeight Then MsgBox "Height: " & Height End If End Sub

The opposite of Private is Public. Not specifying Public or Private for a sub or function will cause it to default to Public. Also, declaring a global variable using the Dim statement will create a Public variable. The following two lines will result in exactly the same behavior for a global variable declaration.
Dim Height As Double Public Height As Double

Scope for Variables in Form and Class Modules


11

Customizing Autodesk Inventor: a Beginner's Guide to the API

Declaration of variables, subs, and functions within form and class modules is the same as with code modules. However there is a difference when they are called. Because multiple instances of objects can be created (remember that form and class modules define objects), you have to specify the object when you use the variable, function, or sub. The sample below declares the global variable Height and the function CheckHeight in the form called frmTest. Both are declared as Public so they have project scope. To call these from any other module you have to specify the object as part of the call, as is shown in the call below. frmTest
Public Height As Double Public Function CheckHeight() As Boolean Dim NewHeight As Double NewHeight = GetCurrentHeight If NewHeight > Height Then CheckHeight = True Else CheckHeight = False End If End Sub

Module 2
Sub HeightStuff() If frmTest.CheckHeight Then MsgBox "Height: " & _ frmTest.Height End If End Sub

Making Decisions
VBA supports several types of statements for making decisions. The most common is the IfThenElse statement. Below is a Sub that uses the If statement to check a value and display a message. The If statement branches into different code depending on if the statement for that branch results in a True or False statement.
Private Sub CheckWeight(Height As Double, Weight As Double) If Height < 60 And Weight > 200 Then MsgBox "Time to lose some weight." ElseIf Height > 60 And Weight < 140 Then MsgBox "A little skinny, aren't we?" Else MsgBox "You're ok." End If End Sub

Another statement for making decisions is the Select Case statement. Its used when you need to look for specific values. The Select Case statement branches into code based on which case matches the comparison value.
Private Sub ShowEmployeeInfo(ID As Long) Select Case ID Case 10 MsgBox "Bob" Case 20 MsgBox "George" Case 30 MsgBox "Martha" Case 40 MsgBox "Henry" Case Else MsgBox "Unknown ID" End Select End Sub

Looping
Below are three of the most common methods of looping. The first is the ForNext statement that uses a counter to loop a specified number of times.
Dim i As Long For i = 1 To 15 Debug.Print "i = " & i Next

12

Customizing Autodesk Inventor: a Beginner's Guide to the API

The next looping statement is a variation of the ForNext statement called the ForEach. This is used to iterate over the contents of a collection. Well see collections some more when we look at accessing Inventor functionality.
Dim oFeature As PartFeature For Each oFeature in ThisDocument.ComponentDefinition.Features Debug.Print oFeature.Name Next

The next looping statement is the DoLoop where the looping continues until a condition is met. There are two flavors of the Do that are shown below. There are also some additional options not shown in the examples below that you can see in the VBA help.
Dim i As Long i = 0 Do While i < 15 i = i + 1 Debug.Print "i = " & i Loop Dim i As Long i = 0 Do i = i + 1 Debug.Print "i = " & i Loop While i < 15

Sample Program 1 (VBA Portion)


Now that weve looked at some of the basics of programming with VB/VBA lets get back to the sample program we started earlier. So far, weve created the form shown below.

In the previous section, you used the combo boxes at the top of the edit window to add a Sub for the Change event of the text box. Now well add some code to this event. Remember that this sub is called automatically by VBA whenever the value of the text box changes. By adding code to this sub youre defining the behavior when this event occurs. Below is the sub for this event and the line of code to add. The line is setting the Caption property of the label control to be the result of concatenating a string with the value of the text box.
' Event to handle when the value of the text box changes. Private Sub txtValue_Change() lblResult.Caption = "Result: " & txtValue.Text End Sub

In addition to handling the text boxs Change event, we also want to handle the Click events of the Cancel and Apply buttons. The final code for these events is shown below.
' Event to handle when the cancel button is clicked. Private Sub cmdCancel_Click() Unload Me End Sub ' Event to handle when the apply button is clicked. Private Sub cmdApply_Click() MsgBox "The value is: " & txtValue.Text End Sub

The cmdCancel_Click sub handles the event when the Cancel button is clicked. In this case it unloads the form. The variable Me refers to the object the code is within. In this case, it is in the form, so Me refers to the form object.

13

Customizing Autodesk Inventor: a Beginner's Guide to the API

The cmdApply_Click sub handles the event when the Apply button is clicked. Well make this do something interesting in the next section, but for now it just displays a message box echoing the text that is currently in the text box. If you run the program you can enter text in the text box and click the buttons. As you enter text, the label at the bottom of the form should display the current value of the text box. So far, weve been running the form directly from the VBA environment. Typically, a form will be used from within a program and the program will cause it to be displayed. For example, a common approach is to create a public sub in a code module and have that module display the form, as shown below.
Public Sub EditParameter() frmValue.Show End Sub

If you run this sub now youll notice that while the form is running you cant do anything else within Inventor. When you run the form directly from the VBA environment or display it using the Show method it is displayed as a modal form. When a modal form is displayed it takes over the windows and is the only thing that can accept input, everything else is frozen until the dialog is dismissed. The opposite of a modal form is a modeless form. A modeless dialog allows you to perform other actions while it is displayed. Depending on your program, either modal or modeless forms can be the best choice. Whether a form is modal or modeless depends on how it is shown. To have a modeless form you need to provide an argument to the Show method to specify that the form should be shown as a modeless form, as shown below. In the previous use of the show method this argument was left out, allowing it to default to the value vbModal.
Public Sub EditParameter() frmValue.Show vbModeless End Sub

The next section extends the functionality of this form so that it will interact with Inventor.

Inventors API
Inventor has an API (Application Programming Interface) to allow programs to interact with it. There are two critical reasons for an API. The first is the acknowledgement that Inventor provides general part and assembly modeling and drawing functionality. However, each customer has specific needs relative to the products theyre designing or their unique use of Inventor. The existence of an API allows them to customize Inventor to add functionality that is specifically useful to the types of products they create. The second critical need for an API is to allow third-party applications the ability to integrate with Inventor. This allows companies other than Autodesk to write new functionality or integrate their existing applications with Inventor. Some examples of these types of products are PDM, FEM, and NC applications. Inventor exposes its API to programs through a technology called Automation. (AutoCAD refers to this as an ActiveX interface.) The rest of this document focuses on how to use Inventors API.

Automation Programming Basics


An Automation API is an object oriented API. This means the API is exposed through a set of objects and you can use the methods and properties of these objects to create new objects and query and edit existing objects. This is the same as accessing the properties of a control on a form. Its just extending this concept so that instead of objects like command buttons and text boxes, you now have access to objects like sketches and features. For example you can obtain a SketchArc object, (an arc in a sketch), which supports properties like Radius, StartAngle, and SweepAngle. To use the Inventor API you need to become familiar with the various objects that the Inventor API supports and understand how you use the API to gain access to a specific object. An important concept to understand to help you in obtaining a specific object is the object model. The structure of the API is defined through the object model. The figure below represents a simplified case of Inventors object model. The object model shows the relationships between various objects and describes how to traverse through the object model to gain access to a particular type of object. A key feature of the hierarchy is the Application object. This is always the object at the top of the object hierarchy and is the object that represents Inventor. The Application object is typically the access point into the object model.

14

Customizing Autodesk Inventor: a Beginner's Guide to the API


Application Documents PartDocument Sketches Features AssemblyDocument ComponentOccurrences Constraints Environments Environment

ExtrudeFeature

RevolveFeature

Inventors VBA provides an easy way of accessing Inventors Application object. A global variable called ThisApplication is available from any project and contains a reference to the Application object. When working within a document project you also have access to a variable that has document scope called ThisDocument which contains a reference to the document the project is contained within.

Sample Program 1 (Inventor Portion)


Lets enhance the previous sample so that it will interact with Inventor. Well change it so that editing the value on the dialog will cause a parameter within Inventor to change. Before we begin writing the additional code lets look at several features within VBA that help you use Inventors object model. The first of these is the Object Browser, which is shown below. The object browser is a tool that lets you examine Inventors objects. You access the browser from within VBA using F2 or the browser button on the main toolbar, .

The left side of the browser contains a list of all of the classes provided by Inventor. Remember, a class is a description of a particular type of object. When you select a class, the right-hand side of the browser displays the properties, methods, and events associated with that object. When you select one of the properties, methods, or events, information about it is shown at the bottom of the browser. For example, in the browser shown above, the HoleFeature class and its CBoreDiameter property has been selected. The information at the bottom tells us this property is read-only and that it returns a Parameter object. We can access additional information about this property by pressing F1 to display its help topic. All Inventor classes, properties, methods, and events have associated help topics.

15

Customizing Autodesk Inventor: a Beginner's Guide to the API

VBAs Intellisense is another tool that helps you to use Inventors object model. This tool comes into play while youre actually writing the code. In the example below a variable has been declared as HoleFeature type. When you use this variable and type a period to indicate you want to access one of its properties or methods, the Intellisense window pops up showing you the available properties and methods. You can select the desired method or property using the mouse or by pressing the Tab key.

Another way to use VBA to examine Inventors object model is to use the debugging facilities of VBA. This approach allows you to view a live version of the object model and actually see the current property values of objects within Inventor. To use the debugger we need to be running a program. Fortunately we dont need much code to enable access to the Inventor objects. The specific steps to use this feature are listed below.

Create a sub, like the sub Test shown below, within any code module. Click the mouse anywhere within the sub and press F8 to step into the code. Youre now running the sub one line at a time. Click anywhere within the word ThisApplication. Run the Quick Watch command from the Debug menu and click Add in the Quick Watch dialog.

The debug window will appear and ThisApplication will appear within the debug window. This represents a view of the live Inventor Application object. You can click on the + sign next to ThisApplication to expand it and view the properties of the object. Properties that return other objects will also have the + sign next to them allowing you to continue to expand the objects and view their properties.

16

Customizing Autodesk Inventor: a Beginner's Guide to the API

Using this technique of viewing a live version of the object model can save enormous amounts of time when trying to understand how to access specific objects and how the object model works. Another tool that Inventor provides in helping to understand the object model is the online help. As seen previously, the help is context sensitive and can be activated using F1 from within the VBA IDE. You can also access the programming help using the Programming Help command from the Help menu in Inventor. The programming help consists of three sections; new features, overview, and reference. The API Overview section contains discussions of various areas of the API. For example, theres a topic on using the API to access iProperties and another about working with sketches. The API Reference section provides detailed information about the Inventor objects and their associated methods, properties, and events. This is the same information thats displayed when you press F1 from within the VBA development environment. The API reference section also contains many samples that demonstrate various uses of the API. Now, lets back to our value editing program. The portion of the Inventor object model that well use is shown to the right. The diagram shows the objects that provide access to parameters and also an object that supports some unit utilities that well use. At the top of the diagram is the Application object. The Application object supports a property called Documents that returns the Documents object. The Documents object provides access to all of the documents currently open in Inventor. It also supports methods to open documents and create new document. The Documents object is an example of a special type of object in an Automation interface called a collection object. A collection is an object, but its primary purpose is to provide access to other objects. Collection objects also frequently provide functionality to create new objects. For our sample we want to change the value of a specific parameter. This is represented by the Parameter object. Below is some code that will access the parameter named Offset in the currently active document.
Dim oParam As Parameter Set oParam = ThisApplication.ActiveDcoument.ComponentDefinition.Parameters.Item("Height")
Application Documents PartDocument UnitsOfM easure PartCom ponentDefinition Parameters Parameter

If you look at this line, youll see that its just navigating the object model to get to the parameter. It starts off by accessing the Application object by using the global ThisApplication. It then uses the ActiveDocument property of the Application object to get the currently active document. Part and Assembly documents support a property called ComponentDefinition that returns a PartComponentDefinition or AssemblyComponentDefinition object. The ComponentDefinition object contains the information that is specific to a part or assembly. For example, the PartComonentDefinition object provides access to all of the feature and sketch information. They also contain the parameters, which is what were using in this case. The ComponentDefinition object supports the Parameters property which returns the Parameters object. The Parameters object is a collection object that provides access to all of the parameters in the document. The Item property of the Parameters object allows you access a specific item within the collection. You can specify items by index, i.e. 1, 2, 3, or you can specify an item by name. In this case were asking for the parameter named Height. Finally, a reference to this parameter is saved in the variable name oParam, which was declared on the first line as type Parameter. The Set keyword is used to assign an object to a variable. You can see from the previous statement that you can combine a series of calls into a single line. Often this is convenient, but there are also cases when you want to break it down into a series of statements. Breaking it up into multiple statements can make it easier to read, easier to debug, and more efficient. For example the following code performs exactly the same operation but does it in a series of steps. First it obtains a reference to the active document. (In this case, it assumes it will always be a part document.) Next it gets a reference to the Parameters object. And finally, it obtains a reference to a particular parameter.

17

Customizing Autodesk Inventor: a Beginner's Guide to the API Dim oDoc As PartDocument Set oDoc = ThisApplication.ActiveDocument Dim oParams As Parameters Set oParams = oDoc.ComponentDefinition.Parameters Dim oParam As Parameter Set oParam = oParams.Item("Height")

The reason this can be more efficient is that you may need to use the document again in your code or obtain more than one parameter. This way you dont have to make repeated calls to obtain those objects but can create a single reference and reuse it. Lets get back to our sample. If we incorporate the code from above in our sample, we can update the Click event of the Apply button to take the value entered in the text box and assign it to the parameter. It does this by setting the Expression property of the Parameter object. This is exactly the same as editing the Equation field of a parameter within the Parameters dialog. After setting the expression of the parameter it calls the Update method of the document to cause the model to update. This is the same as the Local Update command (lightning bolt) in Inventor.
Private Sub cmdApply_Click() Dim oDoc As PartDocument Set oDoc = ThisApplication.ActiveDocument Dim oParams As Parameters Set oParams = oDoc.ComponentDefinition.Parameters Dim oParam As Parameter Set oParam = oParams.Item("Height") oParam.Expression = txtValue.Text oDoc.Update End Sub

That completes the basic functionality of this sample application. However, it has one problem in that the user can enter anything for the value and there is no validation of whats entered. Ideally you would like this to behave like the Inventor dialogs do and allow them to enter any valid equation and even reference existing parameters. It should also take into account the current documents units. For example if you enter 3, what units should be used? If the default length units of the document are inches then you would want it to be treated as 3 inches, however if they are centimeters you would expect it to be treated as centimeters. To enable this functionality in the sample application well use another object from Inventors API called UnitsOfMeasure. The UnitsOfMeasure object provides functionality that allows you to interact with Inventors internal unit system. For this sample well use the method GetValueFromExpression. This method takes any string as input and a description of what type of unit the input string is expected to be and returns the actual value defined by the string, if it is a valid expression. If the input string is not a valid expression an error occurs. To implement this checking well change the implementation for the OnChange event of the text box to that shown below.
Private Sub txtValue_Change() Dim oUOM As UnitsOfMeasure Set oUOM = ThisApplication.ActiveDocument.UnitsOfMeasure On Error Resume Next Dim dValue As Double dValue = oUOM.GetValueFromExpression(txtValue.Text, kDefaultDisplayLengthUnits) If Err Then lblResult.Caption = "Result: Invalid expression." txtValue.ForeColor = vbRed Else lblResult.Caption = "Result: " & Format(dValue, "0.00000") & " cm" txtValue.ForeColor = vbWindowText End If End Sub

18

Customizing Autodesk Inventor: a Beginner's Guide to the API

Lets look at whats happening now in the Change event. The first two lines get the UnitsOfMeasure object from the active document. The next line turns on error handling. Using the Resume Next version of error handling, VBA will continue to run when an error occurs, but will set error information in the global Err object, which well use later. Next, the sample calls the GetValueFromExpression, passing in the current text in the text box. It also specifies that it expects this to be a length and to assume it is using the default units for length. The GetValueFromExpression then returns the actual value of the input string, if it is a valid string. The If statement checks the result to see if there was an error. If there was an error then it changes the Caption property of the label to display that the input expression is invalid and also changes the text in the text box to red using the ForeColor property of the text box. If there isnt an error, then it displays the result of the call in the label and changes the text color of the text box back to the original color. One thing to notice is that its hard coded to display the resulting value using centimeters as the unit. This is because the UnitsOfMeasure object works with Inventors internal units and length units are always centimeters. So, the value returned by the GetValueFromExpression will always be in centimeters. You can read more about Inventor and units in the Units of Measure chapter in the overview section of the online help. Now if you run the program, the dialog will behave just the same as when you enter values into any of the Inventor dialogs. This sample may seem very trivial, but the ability to access and change parameters is the basis for many complicated applications. The challenge it see past the basic functionality exposed and look at how it can be expanded and used with other tools to create much more sophisticated applications. For example, instead of just entering a value, your application might access a set of values from an external spreadsheet or database and set several parameters.

Sample Program 2
Accessing the structure of an assembly is a very common need for many types of programs. Almost any functionality written for assembly documents is dependent on the assembly structure. Since it is used so much and because there are features within it that are not particularly intuitive, this sample demonstrates the assembly structure portion of the API. The finished sample will allow you to enter a string that contains wild cards and will turn the display of any occurrences with matching names on or off. Because this functionality is generic and not limited to a specific assembly, it makes more sense to save it in an external VBA project (probably the application VBA project) so it can be easily shared among different assemblies. The user interface for this sample is shown below.

The values of the various controls are shown below. Form Name frmOccurrenceDisplay Caption Occurrence Display Label Caption Search Name: Text Box Name txtSearchName Command Button Name cmdShow Caption Show Command Button Name cmdHide Caption Hide

19

Customizing Autodesk Inventor: a Beginner's Guide to the API

This completes the visual portion of the program. Before starting on the code portion of the program we need to understand the portion of the Inventor API well be using to access the assembly. Below is the portion of the Inventor object model that provides access to the assembly structure.
AssemblyDocument AssemblyComponentDefinition ComponentOccurrences ComponentOccurrence ComponentOccurrenceEnumerator ComponentOccurrence ComponentDefinition SurfaceBodies SurfaceBody

Within the API, a part or subassembly within an assembly is represented by the ComponentOccurrence object. Looking at the object model, you can see that the AssemblyComponentDefinition provides access to the ComponentOccurrences object. This is a collection object that provides access to all of the occurrences within that assembly document. (The ComponentOccurrences object also supports the ability to create new occurrences in the assembly.) The picture below illustrates a simple assembly and the associated structure as shown in the assembly browser. Using this vise assembly where Vise.iam is the main assembly, the AssemblyDocument object represents Vise.iam. Just as in the case of part documents, the AssemblyComponentDefinition object contains all of the information that is specific to assemblies. From this object we can obtain the ComponentOccurrences object. For this example, the CompoentOccurrences object returns two ComponentOccurrence objects; one for BaseAsm.iam:1 and one for JawAsm.iam:1. These are the only two occurrences directly in Vise.iam, or in other words, they are the only top level parts or subassemblies. To access the other occurrences, that are contained within these subassemblies, you use the ComponentOccurrenceEnumerator object obtained using the SubOccurrences property of the ComponentOccurrence. This is also a collection object and provides access to the occurrences directly within that subassembly. By continuing to iterate over the occurrences within each subassembly you can traverse through the entire assembly tree.

20

Customizing Autodesk Inventor: a Beginner's Guide to the API

As in the previous sample, add code to a code module to display the form in a modeless state.
Public Sub OccurrenceDisplay() frmOccurrenceDisplay.show vbModeless End Sub

The entire code for the form is shown below.


Private oAsmDoc As AssemblyDocument Private Sub UserForm_Initialize() ' Check that a document is open. If ThisApplication.Documents.Count = 0 Then MsgBox "An Assembly document must be active." Exit Sub End If ' Check that an assembly document is active. If ThisApplication.ActiveDocumentType <> kAssemblyDocumentObject Then MsgBox "An Assembly document must be active." Exit Sub End If ' Set a reference to the active document. Set oAsmDoc = ThisApplication.ActiveDocument End Sub Private Sub cmdHide_Click() ' Call the function that traverses the assembly and sets the visibility. Call SetVisibility(oAsmDoc.ComponentDefinition.Occurrences, _ txtSearchName.Text, False) ' Update the view. ThisApplication.ActiveView.Update End Sub Private Sub cmdShow_Click() ' Call the function that traverses the assembly and sets the visibility. Call SetVisibility(oAsmDoc.ComponentDefinition.Occurrences, _ txtSearchName.Text, True) ' Update the view. ThisApplication.ActiveView.Update End Sub Private Sub SetVisibility(Occurrences As ComponentOccurrences, _ SearchName As String, VisibilityOn As Boolean) ' Iterate through each of the occurrences in the collection provided. Dim oOccurrence As ComponentOccurrence For Each oOccurrence In Occurrences ' Check to see if the occurrence name matches the search name. ' The strings are converted to upper case to remove context sensitivity. If UCase(oOccurrence.Name) Like UCase(SearchName) Then ' Check to see if the visibility is different than the specified visiblity. If oOccurrence.Visible <> VisibilityOn Then ' Set the visibility of the occurrence. oOccurrence.Visible = VisibilityOn End If End If ' If this occurrence is a subassembly, recursively call this ' function to traverse through the subassembly. If oOccurrence.DefinitionDocumentType = kAssemblyDocumentObject Then Call SetVisibility(oOccurrence.SubOccurrences, SearchName, VisibilityOn) End If Next End Sub

21

Customizing Autodesk Inventor: a Beginner's Guide to the API

If you look at the code, much of it will make some sense. The UserForm_Initialize sub is an event of the form that is called when the form is first displayed. This sample uses it to check that an assembly is open and to set a reference to the assembly document. The Click events of the two command buttons are almost identical. Both of them call the SetVisibility sub and then update the view. The bulk of the work is performed by the SetVisibility sub. Lets take a closer look at the SetVisibility sub. It has three arguments; the first is a ComponentOccurrences collection that defines the current set of occurrences to iterate over. This argument is typed as ComponentOccurrences, but it will also accept a ComponentOccurrenceEnumerator object because these two objects are based on the same class. The second argument is the search name entered in the form. The final argument specifies if any matching occurrences should have their visibility turned on or off. The first thing the sub does is use the For Each statement to iterate through all of the occurrences in the ComponentOccurrences object that was passed in. For each occurrence it uses the VBA operator Like to see if the search name matches the name of the occurrence. If it does match then it sets the visibility of the occurrence. Its the last few lines in the sub that do the traversal work. First, the If statement checks to see if the current occurrence is a part or assembly. If it is an assembly then its contents need to be traversed. This is done by calling the SetVisibility sub again. When a sub or function calls itself, this is called recursion. This time the SubOccurrences property of the ComponentOccurrence object is used so that the call will traverse the contents of this current component occurrence. To better understand how this works, it can help to step line by line through the sample as it traverses through a small multi-level assembly. Just by looking at the value of the occurrences Name property youll be able to see where it currently is in the traversal and see the process as it progresses. Its also useful to use the watch window, as explained earlier, where you can expand down through the various levels of the assembly. This sample demonstrates the traversal of an assembly and performs a simple operation on the CompoentOccurrence objects it finds. However, the ability to traverse an assembly is useful in many other contexts too. The ComponentOccurrence object provides access to the document that is being referenced so you can access the contents of that document and perform operations. For example, using the traversal functionality in the sample and accessing the iProperties of each document as you encounter it you can create your own Bill of Material functionality. Another example is that you can traverse through an assembly to find a particular part and then use the parameter functionality of the API within that part to change the size of the part. By expanding on this to change multiple parts and parameters you can create a simple configuration tool.

Running Macros
Once youve created a program you need a method of running it besides going through the development environment. The simplest is to use the Macros command in the Tools menu (also Alt+F8). This displays the dialog shown below. This dialog displays a list of all of the macros currently available. This list can be filtered using the "Macros in" combo box. This allows you to list the macros contained in a particular project (document, user, or application project), or to list all of the macros in all of the loaded projects. Remember that macros are defined as public subs in a code module that dont have any arguments.

22

Customizing Autodesk Inventor: a Beginner's Guide to the API

Another method of executing a macro is to create a button for it. This is done using the Commands tab of the Customize command accessed from the Tools menu, as shown below. Macros in the Application project are listed as Commands. A macro can be dragged and dropped from the Commands list to any existing toolbar. Clicking on that button will cause the macro to run.

When macros are associated with a toolbar button they are given a default icon and the tool tip will be the macro name. However, you can also create your own icons. You do this by creating a bitmap using any bitmap editor that can create .bmp files. By creating the bitmap using a specific size, name, and file location, Inventor will use that bitmap for the button. The following describes the rules used for creating the bitmaps. To get consistent results you should use specific sizes for the bitmaps. In some cases Inventor is able to scale any size bitmap and use it for the button, but this can result in skewed images and does not always work. Within Inventor the user can specify whether to use large or small icons for buttons. Because of this you can supply both a large and small icon. Small buttons are the default size. The small bitmap should be 15 pixels high by 16 pixels wide and the large bitmap should be 22 pixels high by 24 pixels wide. The number of colors does not matter. In order for Inventor to associate a bitmap with a particular macro, it uses the name of the bitmap. The naming scheme is: ModuleName.SubName.IconSize.bmp For example, here are the filenames that are used for the small and large icons for the EditParameter macro: Module1.EditParameter.Small.bmp Module1.EditParameter.Large.bmp The names are not case sensitive so module1.editparameter.small.bmp will also work. Besides having the correct name, the bitmap file must also be in the same directory as the application project ivb file.

Learning More About the Inventor API


This was a very brief introduction to VBA and the Inventor API. Besides Inventors online help you can also find additional information at the sources listed below. There is a discussion group specifically for Inventor API isssues: autodesk.inventor.customization There is also a website that provides access to Inventor API information: www.autodesk.com/developinventor

23

You might also like