CADSharp.com API Programming Contest Winners

Blog 8.24.2012 No Comments

CADSharp.com’s first-ever SolidWorks API programming contest has come to a close. Some of the finest API programmers out there stepped up to the challenge described in our last post: Write a macro in as few lines as possible that discovers and displays a single message box listing the children of all part components in the assembly. Without further adieu, here are the results:

1. Ivana K. (15 lines)
2. Josh B. (19 lines)
3. Jeff Z. (20 lines)
4. Satheesh P. (26 lines)
5. Matteo O. (28 lines)
6. Anonymous (57 lines)

Congratulations, Ivana! You will receive a $100 gift card to Amazon.com or one of its international affiliates. Josh and Jeff will each receive a $50 gift card as well. Many thanks to all who participated!

Download Ivana K’s solution

The Solution

Writing a top-tier macro that meets the contest requirements involves three challenges, in my opinion.

The first challenge is simply determining how to obtain the children of a part component. Its not as simple as you might think. IComponent2::GetChildren only returns child components, not child features, which means that on a part component this method returns an empty array. To get the children, we actually need to get the IFeature pointer than corresponds to the part component and then use IFeature::GetChildren. This method returns whatever is listed in the Parent/Child dialog box of a part component. The lesson is, a component is considered a feature by the SolidWorks API. With that in mind, we know to traverse the assembly as a set of features rather than components.

The second challenge is understanding how to write recursive functions. Recursion refers to a function referencing itself. A great example of recursion can be seen in the API Help example Traverse Assembly at Component and Feature Levels Using Recursion. Indeed, many contestants used a heavily-trimmed version of this macro as a means of traversing the FeatureManager tree. Recursion lets a programmer re-use code, which can result in having to write fewer lines of code overall. Such was the case with this macro.

The third challenge is knowing tricks and shortcuts within the VBA or VB.NET programming language to remove as many lines as possible. Ivana’s winning solution illustrates this well:

  1. The text displayed in ISldWorks::SendMsgToUser2 is actually the return value of the getNames functions.
  2. Most of the variable names are declared as function arguments or as For Each loop elements, instead of on their own line. (Note that declaring variables in For Each loops is only possible in VB.NET.)
  3. Automatic type-casting is used to reduce the number of variable declarations. For example, using “swMod.FeatureByName(c.Name2).getchildren” to get the child features of a component.
  4. Use AndAlso and OrElse operators (available in VB.NET) to effectively squish two conditional statements into one line. Normal And and Or operators require all statements to be verified, whereas AndAlso and OrElse will begin executing the statements contained within the conditional once the outcome is guaranteed. So in Ivana’s case, the following logic was applied to each component in the assembly: If the component is a sub-assembly then traverse its features, or, if the component has child features then it must be a part component so add the names of those child features to the final results string.

We can see, then, that VB.NET does offer some significant advantages in terms of reducing line length.

(Note: Should you desire to count the lines in the winning solution on your own, keep in mind that comments, blank lines, Imports statements, and Class declarations are not counted. Also, lines containing 2 or more variables declarations on the same line are counted as separate lines.)

Do know of any alternate solutions or have any questions about the solution we discussed? Please share below.

Until next time,
Keith

Want to be informed of future CADSharp.com contests? Sign up for our newsletter.


Leave Comment

API Programming Contest: Win A $100 Amazon Gift Card

Blog 8.9.2012 No Comments

Think you’re a crack API programmer? We’ll find out! CADSharp.com is excited to announce its first SolidWorks API programming contest. Here’s how to enter and win one of three gift cards from Amazon or a 2-month membership to CADSharp.com:

  1. Download the example file set here and open “CADSharp_contest.SLDASM”.
  2. Write a macro in as few lines as possible that discovers and displays a single message box listing the children of all part components in the assembly.
  3. Submit the macro to contest@cadsharp.com before August 23, 12:00AM EST.
  4. The winners will be announced on our blog on August 24, along with everyone else who submitted a working macro, ranked from fewest lines to most lines.

A correct solution will contain the names of all of the children listed in the Parent/Child dialog box of each part (i.e., non-assembly) component. An example of the correct solution is shown here (list order may vary).

Prizes

Three winners will be chosen based on the number of lines of code in their macro.

First prize: $100 gift card at Amazon.com, Inc.
Second prize: $50 gift card at Amazon.com, Inc.
Third prize: $50 gift card at Amazon.com, Inc.

Please note that Amazon gift cards can only be awarded to entrants living in the United States, Canada, United Kingdom, Germany, Italy, France, Spain, China, and Japan. If a winner does not live in one of these countries, a 2-month Power User membership (valued at $199) will be awarded instead. Optionally, a winner that is entitled to a gift card may choose to receive the 2-month CADSharp.com Power User membership instead.

Contest Details
  • Comments and blank lines will not be considered in the line count.
  • You may not hard-code the name of any entity into your solution.
  • The only acceptable precondition for running the macro is this: CADSharp_contest.SLDASM is open.
  • Please read the full list of contest rules here.

May the best programmer win!
Keith

Want to be informed of future CADSharp.com contests? Sign up for our newsletter.


Leave Comment

RunCommand: The Swiss-Army Knife of the API

Blog 8.7.2012 No Comments

ISldWorks::RunCommand is probably the most powerful call in the entire SolidWorks API. Using this single, easy-to-use API call you can execute over 3,000 individual SolidWorks commands. Need to copy and paste an object? ISldWorks::RunCommand. Need to bring up a feature’s PropertyManager page? ISldWorks::RunCommand. Need to hide the FeatureManager tree? ISldWorks::RunCommand. That’s right—many actions that seemingly have no corresponding API call can be fired using this incredibly versatile method.

But you know what’s amazing? Most API programmers don’t even know it exists! I was one of those programmers for much longer than I would like to admit. Let’s prevent that from being your case as well.

The Basics

First of all, you may have noticed in the API Help a command very similar to ISldWorks::RunCommand called IModelDocExtension::RunCommand. The only difference between the two is that the former can also simulate mouse clicks using the members of swMouse_e, whereas the latter cannot. Keep things simple by always using ISldWorks::RunCommand, which requires these two arguments:

CommandID – This is where you specify the desired SolidWorks command as defined in the swCommands_e enumeration, which contains the list of the 3000+ commands I mentioned earlier.

NewTitle – This is an arbitrary title that you pick that will appear in the title of PropertyManager pages, should you use ISldWorks::RunCommand to open such a page. If you have no need to specify a title, you can set it to Empty.

Finally, the return value is a True or False depending on whether the command successfully runs.

Example 1: Hiding the FeatureManager tree

I see this one in the API forums occasionally. Within SolidWorks, you can click the little tab with three arrows on it, and this will hide or show the FeatureManager tree. Search through the API all you want and you will never find an API call that shows or hides the FeatureManager tree. Yet if we go to the swCommands_e listing and search for the keyword “tree” then we will eventually come across swCommands_Hideshow_Brwser_Tree.

So what will this look like in our code? Try this out:

Dim swApp As SldWorks.SldWorks
    Sub main()
    Set swApp = Application.SldWorks
    Debug.Print swApp.RunCommand(swCommands_Hideshow_Brwser_Tree, Empty)
End Sub

The most difficult part, as you can tell, is actually finding the correct command in swCommands_e. My advice is to search for simple, obvious words like “tree” rather than “FeatureManager”. Nevertheless you may have to test out different commands before you find the right one.

Example 2: Displaying a feature’s PropertyManager page

Whereas most automation macros are not concerned with the user interface, other macros may want to involve the user at some point along the way. In that case it may be useful to bring up the appropriate feature PMP or dialog box. In this case, we want to display the extruded boss/base PMP. Notice that the PMP title is changed to “test”:

Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Sub main()
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    swApp.RunCommand swCommands_Fillet, "Test"
End Sub

If you want to see this example taken to the next level, check out our free macro “Run individual SolidWorks commands” which uses ISldWorks::GetRunningCommandInfo to return the information about the open PMP.

Example 3: Move a BOM to a different sheet

Ever wanted to move a BOM using the API? Good luck trying to do with IDrawingDoc or any other drawing-related interface. Instead you need to replicate with RunCommand what you would do manually, which is cut and paste the BOM. To use this example, open up a new drawing with two sheets, one of which is named Sheet2. Select the BOM and run this code.

Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Sub main()
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    Set swDraw = swModel
    swApp.RunCommand swCommands_Cut, Empty
    swDraw.ActivateSheet "Sheet2"
    swApp.RunCommand swCommands_Paste, Empty
End Sub

You might notice that the BOM is being pasted at the location of your cursor. If you’re a premium member, check out the version of this macro that programmatically selects the BOM so that the user need not pre-select it and also positions the BOM at a precise location on the drawing.

That concludes our look at what I call the “Swiss Army knife of the SolidWorks API”. Please share your comments and questions below.

Commanding,
Keith

Want to keep up with new CADSharp.com content? Sign up for our newsletter.


Leave Comment