-
Posted October 30, 2006
8203634:2006-10-31
By Kent Keller
I have had a lot of people ask me over the years, “How do I get started programming in Inventor?” My answer varies a little bit depending on if you have any previous experience programming in VBA or not. It is beyond the scope of this article to teach you the standard VBA programming language. Although I will explore some generic VBA code, the goal is to help beginners navigate the Inventor Application Programming Interface (API) and leverage Window Watches to enable their macros to execute smoothly. Since the generic code will work in any application that exposes the VBA API, you’ll have a head start in any application that can be manipulated using VBA, including Excel or Word.
However, I will assume that you have working knowledge of Inventor and can navigate the application. Let’s get started with creating a new part file.
Create a new part file
First create a new part file. Make sure it has a few features and a workplane or two. Leave the Workplanes visible, and make sure the Parts BOM Structure is set to Normal.
Next, we want to access the Inventor API IDE which stands for Application Programming Interface, Integrated Development Environment. Select the Tools pulldown > Macro > Visual Basic Editor, or just press the Alt + F11 keys.
Once in the VBA IDE select File menu > New Project. If the Project window shown to the right, isn’t visible, select the View pulldown > Project Explorer. Within the Project Explorer window expand the project we just added, most likely called User Project 1. Then Expand Modules, and double click on Module1.
This should fill in the window shown to the right which contains dropdown lists (General) and (Declarations) above it.
Finally, we are ready to start writing code.
Writing code snippets
If your window doesn’t already display Option Explicit at the top, type it in. Then navigate to the Tools dropdown > Options > Editor tab, and check Require Variable Declaration. This will make Option Explicit automatically be added any time you start a new project. Using Option Explicit will help reduce naming conflict errors and spelling mistakes.
Below Option Explicit, type in Public Sub MyPartMacro. Hit enter and notice that VBA automatically Adds a () at the end of the line, and also adds the line End Sub. VBA does a pretty good job at trying to help us keep our code in a valid format.
By making the Sub, Public rather than Private it will be available to you when you are back in Inventors window. For our purposes today, you can simply consider Sub as a grouping of code. MyPartMacro is the descriptive name we are giving the grouping. Sub names can not have spaces.
Below Public Sub MyPartMacro() type in
Dim oPDoc as PartDocument
Set oPDoc = ThisApplication.ActiveDocument
You should have something like the following.
The indentation shown above doesn’t make any difference in how the code works, but it improves readability when you start cranking out lines of code. The first line tells VBA that we want to reference a Part Document and name the reference oPDoc.
In creating this reference we will now be able to type in oPDoc any time we need to access something in the part document, rather than having to type in ThisApplication.ActiveDocument each time.
I loosely follow what is called Hungarian Notation, which is the practice of prefixing our descriptive names with the data type. Here our Part Document is considered a Object in VBA, so I prefix it with “o”. Most books or a online search of Hungarian Notation will give you more information on this practice.
Also note that we could have made the Reference to the generic Document Object such as Dim oPDoc as Document. There are cases where you might want to reference the file through the generic Document object but as long as you know you will be only working on a Part file, it is better to access it through the PartDocument object.
If you use the generic PartDocument, you won’t be able to take advantage of the AutoComplete List because the list will only show items that are common to all document types.
AutoComplete is the list that shows up sometimes as you are typing code. As you type it scrolls through the list finding the first item that matches how much you have typed. Once it gets to the item you want to use, all you have to do is hit the keyboard Tab to add the time to your code.
The second line of code simply tells it what Part Document we want it to reference. Think of ThisApplication as the Inventor session you have running, and ActiveDocument is whatever document is open and in focus in Inventor. I am not going to get into error control in this article but just be aware that if you have any kind of document open other than a part document you will get a error when trying to run this code.
We can now take a look at all the objects that are exposed to us through the Document object. Position your cursor inside the Sub - End Sub, and then press the F8 key. Public Sub MyPartMacro() should highlight. Press F8 twice more, until you are highlighting End Sub. We have just stepped through the code, and set oPDoc equal to the Part Document that you opened at the start of the article.
Using the Watch Window
With the End Sub still highlighted, go to the View pulldown, and turn on the Watches Window if it isn’t already visible. You could alternatively use the Local Window available in the View pulldown also but I prefer only watching a couple of items rather than everything in the sub. You may want to expose both windows and see which you prefer using.
The information that these windows expose, allows us to take a look at a number of things. First we can see the logical structure of any visual basic objects. Looking through this structure, will show us how to access sub objects and properties. It also shows us the Type of object or property these sub items are, which will help us if we want to Dim a variable to them.
The information also shows the current value of the properties or variables which will help to debug your code by showing when the value is changing, and if it is actually changing when we expect it to or not.
At either location of the word oPDoc in your code, double click on it to highlight the word, then right click and select Add Watch. In the Add Watch window click OK to add the watch to the Watches window.
In the Watches window, shown below, click on the + next to oPDoc to expand the tree. The vast majority of things in your Part Document available to you through the API are shown below oPDoc.Browse around a little and get a feel for how things are set up. I like to look at the structure as a very logical set of folders similar to what you would see in Windows Explorer. Instead of backslashes we use periods as a separator to drill down levels into the objects and properties.
Find and expand ComponentDefinition and you will see all the things that make up the actual component in the part file. Notice in the Type column it is defined as a PartComponentDefinition.
Since we are going to want to manipulate things with the Component, rather than things at the Document level, lets make it easier on ourselves, and add a couple of lines to the code. Hit F8 one more time to finish the Sub or else click on the Reset toolbutton which has a square on it.
Below the previous lines of code, but above End Code, make a reference to the actual Part component.Type in:
Dim oPCompDef As PartComponentDefinition
Set oPCompDef = oPDoc.ComponentDefinition
We knew to Dim it as a PartComponentDefinition from looking at the Type column in the Watches window. Note that we could have used the generic ComponentDefinition Type, but again AutoComplete wouldn’t have been as helpful. Also from the Watches window we knew that the Component Definition resided under the oPDoc. So we just need a period after oPDoc and then find PartCompoenentDefinition in the Auto-Complete list. Remember, we can think of these like files and folders on your system, but rather than backslashes we use periods as separators.
Double Click on oPCompDef to highlight it, and right click Add Watch, and click OK in the dialog. You can right click on oPDoc in the Watches window and delete it to keep the Watches window from getting cluttered if you would like
Step through the code again, using F8 and stop on End Sub.
Looking in the Watches window at our new oPCompDef we can get an idea of what we need to do to access the various areas of the Component without worrying about things above it in the tree.
Just to see some of the things we can do lets change the BOM Structure from Normal to Purchased, turn off all Work Plane visibility, get a list of how many parameters are used, and how many Extrude features are used to make the part.
Looking in the Watches window under oPCompDef find the listings for BOMStructure, WorkPlanes, Parameters, and Features > ExtrudeFeatures
Either make a mental note or jot down where each thing sits in relationship to the Component Definition.- BOM Structure is directly under the Component Definition (oPCompDef)
- Workplanes have the individual planes listed as Items under it, and
within those Items is the Visible setting - Parameters, when expanded, have a Count property
- Features, when expanded, have ExtrudeFeatures listed under it and under that is a Count property
Hit F8 to finish the sub, and we will add the code to access these items.
Below the previous code in the window, but above End Sub, type
OPCompDef.boms and then hit tab to select BOMStructure from the Auto-Complete list. Next on the same line type in = and look through the Auto-Complete to find the line that has a word which contains “Purchased” in it, and select it.
It should look like the following.
oPCompDef.BOMStructure = kPurchasedBOMStructure
You will notice that here we didn’t have to use the Set Statement like we have for other lines with the = in them. For items with simple values such as strings or variables we don’t need to use the Set statement. It is required if we are setting a variable to a Object which has its own methods and properties. This is to allocate memory space for the whole object.
Next comes the WorkPlanes. Since there are multiple workplanes we need to be able to step through them one at a time. To do this we Dim an Integer like this:
Dim iPlanes As Integer
Then we can step through the planes no matter how many of them there are, like this:
For iPlanes = 1 To oPCompDef.WorkPlanes.Count
oPCompDef.WorkPlanes.Item(iPlanes).Visible = False
Next
What it says in English is that our iPlanes integer is equal to 1 and when we come to the code Next, it will send us back to the For line until iPlanes has been incremented to be equal to the total number of WorkPlanes the Component contains. The For Next loop is a pretty standard way to loop through anything that there is multiple items of. Between the For and Next lines, as we saw in the Watches window, we access WorkPlanes through the ComponentDefinition and the individual WorkPlane through the WorkPlanes Item object. We are selecting which Workplane item by using the iPlanes value. With each Workplane we access its Visible Property and make it equal to false.See if you can figure out how to get to the Parameters count on your own now.
Start with the ComponentDefinition, and from there add parameters, and finally count.
Yours should look like this
oPCompDef.Parameters.Count
Since we want to be informed of the Parameter count we need to display it and the built in VBA MsgBox function will do this for us. We can also add some text to it to inform us what we are looking at, like this:MsgBox “We have a total of “ & oPCompDef.Parameters.Count & “ Parameters”
Any text will need quotation marks around it and remember to add a space to the text when we are stringing together things. We use the ampersand to tell VBA that we want to join together our text and the value, and another one after the value to tell it to join the remaining text after the Parameters Count.
Finally we get to the Extrude feature count. Give it a try yourself without scrolling down and copying and see if you can figure out how to display the quantity of Extrude features are in the part using a MsgBox.
Once you have finished that, step through the code again by pressing F8 until the BOMStructure line is highlighted. Hover your mouse over oPCompDef.BOMStructure and it should display a tool tip of a number such as 51970. Take note that yours may be different depending on what your BOMStructure is set to. Then hover your mouse over kPurchasedBOMStructure and you will see 51973.For many things Inventor uses unique numbers internally but also allows us to use values such as kPurchasedBOMStructure which are easier for us humans to read and know what it means.
You could change out kPurchasedBOMStructure with 51973 in the code and it would work just the same but would be much harder to look at and know what is happening. The main thing to note here is that once we press F8 one more time if we hover over oPCompDef.BOMStructure again it has changed to 51973. Your parts BOM structure has just been changed to Purchased.
Hover your mouse over iPlanes on the highlighted row and notice it is equal to 0. This is because it defaults to 0 when it is initiated and we have not yet processed the line we are on. Hover over oPCompDef.WorkPlanes.Count and it will tell you how many planes we are going to process.Hit F8 again and you can either hover the cursor over oPCompDef.WorkPlanes.Item(i).Visible or highlight it and add it as a watch. Continue stepping through them using F8 and watch to see that any that start out showing Visible as True end up with it showing False. You can also switch over to the Inventor after each trip through the For Next loop and see that the Planes Visibility is getting turned off , one by one.
Next F8 past the two MsgBox lines and see that it shows you the proper values for each object.
Go back to Inventor and change the BOM Structure back to Normal and turn the Workplanes on again. Then press Alt + F8 and find “MyPartMacro” and select Run. Your code should execute and just like when you stepped through it.
Here is what the complete code should look like. Make sure the MsgBox lines are all on one line or it will cause an error.
Option Explicit
Public Sub MyPartMacro()
Dim oPDoc As PartDocument
Set oPDoc = ThisApplication.ActiveDocument
Dim oPCompDef As PartComponentDefinition
Set oPCompDef = oPDoc.ComponentDefinition
oPCompDef.BOMStructure = kPurchasedBOMStructure
Dim iPlanes As Integer
For iPlanes = 1 To oPCompDef.WorkPlanes.Count
oPCompDef.WorkPlanes.Item(iPlanes).Visible = False
Next
MsgBox "We have a total of " & oPCompDef.Parameters.Count & "Parameters"
MsgBox "We have a total of " & oPCompDef.Features.ExtrudeFeatures.Count & "Extruded Features on the part"
End Sub
From there I would suggest stepping back into the code and looking through the oPCompDef object in the Watches window to find things you want to experiment with. Not everything is changeable though as some values are Read-Only. You can use the Object Browser to find if something is Read-Only or not. It is available in the View menu, or one of the main tool buttons, or simply by hitting F2. Once in it, set the dropdown at the top of its window to Inventor, so that we are only looking at things in the Inventor API.
Click on Angle Constraint in the left window and then AffectedOccurrenceOne in the right and you will see in the gray area in the bottom part of the window that it shows as Read-Only. We can’t change the Occurrence through this object, we can only find out what the occurrence is.
If you want to keep this code be sure to save it or Inventor will prompt you to save it when closing.
Once you have looked around the Part Document API open an assembly and create a new sub below the previous one with the following code.
Dim oADoc as AssemblyDocument
Set oADoc = ThisApplication.ActiveDocument
Step through the code until End Sub is highlighted and add a watch on oADoc. Look through the Watch to get a idea of what all you can get access in the Assembly. Just like the Part Document, most of the Assembly is accessed through the Component Definition, so add a couple of lines like this:Dim oACompDef As AssemblyComponentDefinition
Set oACompDef = oADoc.ComponentDefinition
Set a watch on oACompDef and see what all you can access. If you need to go more than a couple levels deep or access the same thing multiple times, I feel it is generally best to Dim a object to that level. For instance if we wanted to do a lot of work with the Property Sets, we would do something like this:Dim oPropSets As PropertySets
Set oPropSets = oADoc.PropertySets
And finally if we want to look around in a Drawing Document:Dim oDDoc As DrawingDocument
Set oDDoc = ThisApplication.ActiveDocument
The Watches Window can be your best friend when trying to find your way around a API. Set a watch on oDDoc and look around. Probably the most common areas here are in the Views and Sheets objects.Automating you tasks
This of course is just a very small glimpse of what is available to us through the Inventor API. With a little VBA experience and using the Watches window or the Locals window you should be able to find your way around the Inventor API and be on your way to writing useful macros to automate some of your tasks.usa.autodesk.com/adsk/servlet/item?siteID=123112&id=8203634
Comments
-
April 17, 2007 02:31 AM EZIO ENDRIGO
I'm using VC++. Where can I find example for this language. In particular for CComPtr
pProfile; pProfiles->AddForSurface( vtMissing, &pProfile). I dont wont use vtMissing but a specific skecth shape. Can anyone help me ? Thank in advance. Ezio Endrigo
You must be logged in to post a comment.
