Autodesk Inventor - VBA-api pt2
Autodesk Inventor - VBA-api pt2
VBA/API - Part 2
By Neil Munro
Last time, we built the user interface for a center of gravity tracker for Autodesk Inventor assemblies. This month we'll add the
programming code to insert a special center of gravity (Marker) part, position the Marker part at the assembly, and display the assembly
COG coordinates in the current document units.
Download Files
First download, unzip, and save to a folder in your current project, the COG_A.zip file. It is important that the Marker.ipt file in the zipped
file be placed in a folder included in the active project.
Marker.ipt
COG_A.ivb
The included part file (Marker.ipt) is designed specifically for use as an assembly COG marker and the part has the following properties:
The COG_A.ivb file contains the results of last month's tutorial. Feel free to continue on with your own file, but if you missed out, rename
this file to COG.ivb and load the project through the Autodesk Inventor VBA IDE.
1. Select Tools > Macro > Visual Basic Editor from the Autodesk Inventor pull-down menu.
2. Select File > Load Project from the VBA pull-down menu. Browse to the folder containing COG.ivb and load it.
The VBA IDE contains a number of tools for sizing and aligning the controls on a form. By default, controls snap to a grid. You can
control the grid spacing on the General tab of the Options dialog box (select Tools > Options from the VBA pull-down menu). A selection
of alignment and sizing tools is available on the Userform toolbar (select View > Toolbars > Userform from the VBA pull-down menu).
You can align and size controls at the same level on a form. Controls within a Frame control are at a different level than controls outside
1 of 7 1/21/2010 6:36 PM
Autodesk - Autodesk Inventor Services & Support - VBA/API - Part 2 http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=234599...
the Frame control. You can select any number of controls, and the last control selected is used as the seed for alignment and sizing.
In the top image of Figure 1, the two label controls are selected. The topmost label control is the seed control for sizing and alignment
(white grip points). In the middle image, the controls are aligned on their left edges (Label2 aligned to Label1). The bottom image has
both controls matched in height and width. Additional spacing and grouping controls are available on the toolbar and from the Format
menu.
Our macro requires access to a number of Autodesk Inventor objects. We'll look at specific objects in detail as we access them. Figure
2 includes a hierarchy of all objects required for our program. You can download a PDF file outlining the complete Autodesk Inventor
object hierarchy from the Autodesk Inventor Product Resources on Autodesk.com.
Let's quickly overview the objects depicted in Figure 2. The two objects directly below the Application object are the AssemblyDocument
and TransientGeometry objects.
TransientGeometry objects, such as points and matrices, are placeholders for geometric information required to place or move real
geometry. In our macro, we'll use a Matrix object (contains position and rotation information) to hold information required to move the
Marker part to the current assembly COG.
The AssemblyDocument object represents an assembly file. There are two first-level children of this object that are of interest to us
for this macro, the UnitsOfMeasure object and the AssemblyComponentDefinition object.
All Autodesk Inventor parameters are unit specific for each document. The UnitsOfMeasure object enables us to retrieve and set unit
types and precision. Our program will display the assembly COG coordinates in the current length units for the document.
While the AssemblyDocument object represents the assembly file, its first-level child, the AssemblyComponentDefinition object
contains the geometry in the file. It is through this object that we can obtain assembly mass properties and information about
assembly components.
The MassProperties object is a key object in our program. It contains a CenterOfMass property that holds the X, Y, and Z
coordinates of the assembly COG. No complex calculations are required; our goal is simply to retrieve this information and move our
Marker part there.
An assembly is made from parts and subassemblies related by assembly constraints. You can access assembly components in the
assembly through the API, and we'll use this to find the Marker part across Autodesk Inventor sessions. You can then move the
Marker part into position, scale it, and control the visibility of its origin geometry. We'll examine these objects in more detail later in
the tutorial.
2 of 7 1/21/2010 6:36 PM
Autodesk - Autodesk Inventor Services & Support - VBA/API - Part 2 http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=234599...
of numbers, strings, and even objects. Good programming practice includes declaring each variable to hold only a specific type of
information, such as an integer, string, or a CenterOfMass object.
When you declare a variable as a specific object type, it enables the IntelliSense feature in VBA to present the properties and
methods associated with the object as you use it in a program statement. Failure to declare variable types often results in difficult-
to-solve program errors. VBA can check for undeclared variables if you check the Require Variable Declaration option on the Editor tab
of the Options dialog box. (Select Tools > Options from the VBA pull-down menu.) (See Figure 3.)
1. Right-click frmCog in the project explorer and select View Code from the shortcut menu.
2. Scroll to the top of the code window. Enter Option Explicit as the first line in the code window if it is not already present. This turns on
variable declaration checking (for all code in the form) even if it was not specified in the Options dialog box.
You must declare variables that will hold the objects outlined in our project object model (see Figure 2). Because you are declaring them
outside a specific procedure, but inside the form, they will be available from all the procedures created within the form.
3. Type Private m_oDoc as asse under the Option Explicit line (see Figure 4).
4. Note the IntelliSense window scrolls to the first type that matches the current text after the word as. Select AssemblyDocument as the
object type for this variable.
What about the notation used for the variable name? It is common practice to precede variable names that are declared outside a
procedure with an m_ (module) or g_ (global) to indicate the scope of the variable. The variable was preceded by the word Private,
making it accessible to all procedures defined inside the form (called module- or form-level variable scope).
Procedures in other forms or modules will not be able to access this variable. A Public declaration would make the variable accessible in
all procedures in all program modules (a global variable). Declaring Public variables should be avoided if possible; it is easy to lose track
of when and where the value of a global variable is changed. The lower case o that precedes the variable name is a reminder that the
variable holds an object.
Note: Variables that hold objects are often referred to as object variables.
5. Declare the following variables as Private variables in the form (for example, Private m_oTG as TransientGeometry).
m_oTG TransientGeometry
M_oCompDef AssemblyComponentDefinition
m_oMassProps MassProperties
m_oOccMarker ComponentOccurence
m_ouom UnitsOfMeasure
Document Checking and Form Initialization
When a user runs the macro for the first time in an Autodesk Inventor session, the form is loaded by the frmCog.Show statement in the
macro. Since the macro only makes sense in an assembly document, we'll add a few lines of code to check if the active document is an
assembly.
3 of 7 1/21/2010 6:36 PM
Autodesk - Autodesk Inventor Services & Support - VBA/API - Part 2 http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=234599...
1. In the project explorer, expand the Modules folder and double-click Module1.
2. In the CogTool subroutine, enter the code shown in Figure 5 above the line that loads the form.
The code checks the current document and exits without loading the form if the document is not an assembly.
4. Scroll down to the Userform_Initialize routine. You entered one line of code there in the last tutorial to set the height of the form as it
loads.
During the loading of the form, we'll assign values to the object variables declared earlier in
the tutorial. To assign a value to an object variable, you must use the Set keyword. Variables
that are not objectsare assigned values without the Set keyword.
5. Enter the code shown in Figure 6. ThisApplication is interpreted as the Autodesk Inventor
Application object because VBA is running inside Autodesk Inventor. Refer to our object
model (see Figure 2) to track the relationship of the objects created.
View Larger
Figure 6: Checking for assembly
document.
Note: The green text items are comments. It is highly recommended that you add comments to your code as you go. You will find it
difficult to understand any lengthy uncommented program when you return to edit it tomorrow or six months from now. Anything after
the first single quote in a line is interpreted as a comment.
The challenge of finding the Marker part in a large assembly still remains. In a five-thousand-part assembly, there will almost certainly be
a smaller number of unique first-level components. The AssemblyComponentDefinition has an object property that contains the unique
component definitions (first level) in the assembly. We'll search through these to find the Marker part. The question of whether the
Marker part is currently in the assembly is one that may be asked at different points in the program. The programming code to ask this
question will be placed in a user-defined procedure, so that it can be called from anywhere in the program.
Note: The information required from this routine is a simple yes or no. The user-defined procedure will be in the form of a function,
rather than a subroutine. A function differs from a subroutine in that the results of the procedure are returned in the function name.
This enables the function to be called in an expression. The subroutine presented in the first VBA tutorial (last month) is shown below
as a function.
4 of 7 1/21/2010 6:36 PM
Autodesk - Autodesk Inventor Services & Support - VBA/API - Part 2 http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=234599...
4. Click OK.
5. Enter the code shown in Figure 8 and then enter the code in Figure 9 to complete the
function. The comments are not required but recommended.
Let's review the code in Figures 8 and 9. The unique component definitions in the assembly
are obtained and iterated through using a loop. The component definitions are stored in a
VBA collection (group of common items). The collection has a Count property (number of
items in the collection) and an Item property to enable index-based access to individual
objects in the collection. Check the object model in Figure 2 against the code to help
understand the hierarchy.
View Larger
Figure 8: Function code.
The associated file name of each component definition is compared against Marker.ipt to
find the Marker part in the assembly. If it is found, all extra occurrences of Marker.ipt in the
assembly are deleted (after warning the user). The ImmediateOccurences collection holds
all occurrences of the component in the assembly. When you remove an item from a
collection, all items above the removed item drop down one item number. If there are three
occurrences of the Marker part in the assembly, deleting the second item in the collection
will leave a first and second item in the collection. Deleting the second item again removes
the original number-three item.
The function name is then assigned a value of True to indicate the part was found. Finally,
you assign the Marker part occurrence to the previously declared module-level object
variable m_oOccMarker. View Larger
Figure 9: Function code completed.
Completing the Form Setup
After all that, you can now complete the code in the Userform_Initialize subroutine.
Based on the answer to the search for Marker.ipt, you set the state of the
controls on the form. Disabled command buttons appear grayed out and do
not react to user interaction (for example, mouse click). The UpdateXYZ
subroutine updates the display of the assembly COG coordinates on our
form. We'll add the UpdateXYZ routine later in the tutorial.
Call InsertMarker
5 of 7 1/21/2010 6:36 PM
Autodesk - Autodesk Inventor Services & Support - VBA/API - Part 2 http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=234599...
The code in Figure 11 creates a transient (temporary) matrix that is then filled with the coordinates of the assembly COG. The rotation
portion of the matrix is left at the default of zero rotation about each axis.
How do we know what information is required by the SetTranslation method of the Matrix object? To obtain help on any object, property,
or method, click on the word and press the F1 function key. This displays a help page outlining syntax, argument types, and often
includes example code. Go ahead, try it.
The most important part of the help system is the sample code section. Many short examples demonstrate how to perform basic
operations, such as placing a component in an assembly.
Everything is now in place to insert the Marker part. Thinking ahead like good programmers do, we realize that the Marker part may not
always be in a folder where Autodesk Inventor can find it (in a project path). An error will occur in our program if the Marker part cannot
be found. To handle this possibility, we'll add code to capture and recover from the error. There are numerous techniques for error
handling in VB/VBA; we'll use a technique that handles errors for a single instruction (turn on error handling, execute the code statement
that may produce an error, handle the error if it occurs, and finally turn off error handling).
Most of the code in Figures 12 and 13 is easy to understand (again, use comments for your
own benefit). The line of code placing the Marker part occurrence in the assembly assigns
the occurrence to the module-level m_oOccMarker variable. You can now access the
Marker part directly through this variable.
View Larger
Figure 12: Insert Marker part.
5. Complete the subroutine by adding the code in Figure 13 immediately below the On Error
Goto 0 line.
View Larger
Figure 13: Code to complete
InsertMarker subroutine.
Updating the XYZ Labels
Your last task is to update the labels on the form to display the assembly COG coordinates. The form remains visible while you are
working in Autodesk Inventor software, so the assembly COG coordinates are always visible.
1. Scroll down to the end of the code window and enter the code shown in Figure 14. You
can add subroutines and functions without using Insert > Procedure from the pull-down
menu.
You use the m_oMassProps object variable that was set during form initialization to provide
the assembly COG data. For each label, you call a function (value returned in the function
name) named ToFourDec to generate a string containing the coordinate in the current View Larger
document units. Figure 14: Update labels subroutine.
2. Finally, add the ToFourDec function by entering the code shown in Figure 15.
The ToFourDec function is an example of working with values and units in Autodesk
Inventor. All distance values in Autodesk Inventor are stored internally in centimeters. All
angular values are stored in radians. Users will expect that the information displayed will use
the current document units. The UOM object contains methods to convert internal units to
documents units. To obtain help on the VBA functions (for example, Format$, or CStr), click
on the word and press the F1 function key.
View Larger
Figure 15: Generating coordinates in
local units.
6 of 7 1/21/2010 6:36 PM
Autodesk - Autodesk Inventor Services & Support - VBA/API - Part 2 http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=234599...
Note: The first statement in the ToFourDec function has an underscore chanracter at the end of the first line. VBA interprets this as a
continuation character, with the remainder of the statement on the second line. You can type the statement on a single line; we broke
the line to fit the graphic on the page.
Testing the Macro
4. Click Run in the Macros dialog box. The form loads, and the Insert command button is the only enabled button.
5. Click the Insert button. The Marker part is placed in the assembly, and the form displays the assembly COG coordinates.
6. Click Cancel.
7. Run the macro again. This time the program finds the Marker part is present in the assembly. The Insert button is disabled, and the
Update button is enabled.
8. Click Cancel.
10. Run the macro again. A message is displayed warning of the extra Marker part occurrences, and the extra occurrences are deleted.
Conclusion
Learning both the VBA and Autodesk Inventor object models is a substantial task. Examining code written by others is a great learning
opportunity. Another excellent resource is the great number of books available on VB/VBA programming.
Next month we'll conclude (finally) this project by adding an Update routine, code to scale the Marker part, and routines to get and set
the visibility of the Marker part's origin geometry. Also, look for an introduction to the new Autodesk Inventor Series, which includes
Autodesk Inventor 5.3 and Autodesk Mechanical Desktop 6.
7 of 7 1/21/2010 6:36 PM