My last post contained VB.Net and C# versions of a VBA program from an earlier post. Converting the VBA program to VB.Net was relatively easy. The conversion to C# wasn’t as easy. In this post I want to begin covering many of the issues you’ll run into when converting VBA code to C#.
One question that might come to mind is why would you want to convert from VBA and not just write everything in C# to begin with? The first reason is that many of the programming samples you’ll find for the Inventor API are written using VBA. The second reason is that VBA remains the fastest and easiest way to access and use the Inventor API. Having said that, it does have a lot of other shortcomings so I wouldn’t recommend it for general development, but if you’re not using it for prototyping you’re missing out on a very powerful tool.
To go from VBA to C#, I’ve found the simplest method is to first convert the code to VB.Net. This is typically fairly easy, particularly if the VBA code was written with going to VB.Net in mind. For example, all arrays should be 0 based. In many cases it’s just a copy and paste and Visual Studio will automatically do some syntax conversion. Some of the manual changes that were required I went over in the previous post. The next step is to go from VB.Net to C#. There are some converters that do a pretty good job of automatically converting the VB.Net code to C#. I found an online converter using Google that worked great. (For any syntax issues that might still come up, here’s a good comparison of VB.Net and C#.) Next you’ll need to account for other differences that are typically specific to a COM Automation API, like Inventor’s. It’s those issues that this series of posts will attempt to cover.
Item Property
C# hides the fact that there’s an Item property on the Inventor collection objects so you access the contents of the collection as if it was a read-only array, except the first item has an index of 1.
Set body = partDef.SurfaceBodies.Item(1)
C#
body = partDef.SurfaceBodies[1];
Comparing Two Objects
Sometimes you need to check if two variables referencing objects are referring to the same object. Here’s how you do it in VBA and C#
Dim var1 As Parameter
Set var1 = partDef.Parameters.Item("Length")
Dim var2 As ModelParameter
Set var2 = partDef.Parameters.ModelParameters.Item("Length")
' Verify that the variables are referencing the same parameter.
If var1 Is var2 Then
MsgBox "The two variables reference the same object."
End If
C#
Parameter var1 = partDef.Parameters["Length"];
ModelParameter var2;
var2 = partDef.Parameters.ModelParameters["Length"];
// Verify that the variables are referencing the same parameter.
if (var1 == var2)
{
MessageBox.Show("The two variables reference the same object.");
}
Checking the Type of an Object
Sometimes it’s useful to be able to check if an object is a certain type. Both VBA and C# provide an easy way to do this.
' This will fail if nothing is selected.
Dim selectedObject As Object
Set selectedObject = _
ThisApplication.ActiveDocument.SelectSet.Item(1)
' Check that the selected object is a sketch line.
If TypeOf selectedObject Is SketchLine Then
MsgBox "Selected object is a sketch line"
Else
MsgBox "Something besides a sketch line is selected."
End If
C#
// This will fail if nothing is selected.
object selectedObject = invApp.ActiveDocument.SelectSet[1];
// Check that the selected object is a sketch line.
if (selectedObject is SketchLine)
MessageBox.Show("Selected object is a sketch line");
else
MessageBox.Show("Something besides a sketch line is
selected.");
Iterating Through the Contents of a Collection
Using a For Each loop is the most efficient way to iterate through the contents of a collection. In some cases it can be much faster than using the collection’s Count and Item properties.
Dim area As Double
Dim partFace As Face
For Each partFace In partDef.SurfaceBodies.Item(1).Faces
area = area + partFace.Evaluator.area
Next
MsgBox "Total surface area: " & area & " cm^2"
C#
double area = 0;
foreach( Face partFace in partDef.SurfaceBodies[1].Faces)
{
area += partFace.Evaluator.Area;
}
MessageBox.Show("Total surface area: " + area + " cm^2");