Example - Framed Box

If you have seen any presentation on VB and the SolidWorks API, you have probably seen a simple demonstration that uses the macro recorder to create a simple flat part.  The presenter then went ahead and created a form that allows the user to specify the sizes of the flat part.  This example is similar, but takes it another step by adding a few more features to the part.

In this example, I started a new part and turned on the macro recorder and created a cube.  I then created a sketch on one of the existing planes, used the offset entities, then cut extrude thru all.  I repeated the Sketch/Offset//Cut two (2) more times.  The final result is a frame created from the original cube.

To reuse this macro, start a new part first then run the macro.  When you run the macro, it will automatically create the model for you.  If you have the option "Input dimension value" turned on, you will be prompted twice to enter the values for the twp (2) dimensions in the sketch.  You can hit enter for these prompts.  If you enter a value, the macro will still build a 3" x 3" x 3" box.

This works fine, but:
* Can we get rid of the annoying prompts if the "Input dimension value" turned on?
* Can we make a 4" x 4" x 4" cube or 2" x 3" x 4" block instead?
* Can we make a thicker or thinner frame?
The answer is yes for all of these.

When editing the macro, we can see that all of the code is in a single module.  In examining the code, you will see all of the necessary Visual Basic code and the SolidWorks API instructions to do the work.  We will start with this code and modify it to suit our needs.

First, let's turn off that pesky "Input dimension value" while we are creating the model.  This is a simple user preference toggle.  So we don't alienate the user, we need to retrieve and save the current setting, set the toggle to off/false, complete the work, then set the toggle back to the original setting.  To do this, we need to put the following code (save the setting and turn it off) at the start of the routine:

DimValuePreset = swApp.GetUserPreferenceToggle(swInputDimValOnCreate)
swApp.SetUserPreferenceToggle swInputDimValOnCreate, False

then add this code (change the setting back) at the end of the subroutine.

swApp.SetUserPreferenceToggle swInputDimValOnCreate, DimValuePreset

In this example, we created the variable "DimValuePreset" so we can hold the current "Input dimension value" setting until we are done.

Next, we need to create a simple form and decide what information we need to get from the user.  In this example, we need the user to define the Width, Height, and Depth of the cube, and the frame thickness.  Don't forget to add the Create and Close buttons.  The Create button is used to launch the custom code, while the Close button gives the user a clean way of getting out of making the part.

Once the form is created, we need to move some code around and link the user data into the right places in the existing code.  While viewing the form, double click on the "Create" button.  This will create the subroutine "CommandCreate_Click" .  Go to the "Main" module and cut the code between the "Set swApp = Application.SldWorks" line and the next "End" line.  Paste this code between the "ButtonCreate_Click()" and the "End line"  This forces the user to enter the data in the form before the recorded code is executed. 

Back in the "Main" module we need to make some changes.  First of all, we need to make the variables global (defined in the whole macro, not just this module).  At the top of the main module, change the word "Dim" to "Global".

Next, we need to be able to display the form to the user.  In the "Sub Main()" routine, add the following line right after "Set swApp = Application.SldWorks" to show the user form.

UserForm1.Show

Back in the form, we need to link the form fields to various places I the recorded macro code.  If you attempt to change the values as the model is being created, you may notice that the macro may abort while creating the sketches and offsets.  This is because of selections made on the screen.  We don't want to interfere with these screen selections so we will use the "Part.Parameter" feature to change the dimensions after the model is created.  Because there are 6 dimensions, we need to add 6 "Part.Parameter" lines at the end of the "CommandCreate_Click" routine.

Part.Parameter("D1@Sketch1").SystemValue = TextBoxHeight.Value / 25.4
Part.Parameter("D2@Sketch1").SystemValue = TextBoxWidth.Value / 25.4
Part.Parameter("D1@Extrude1").SystemValue = TextBoxDepth.Value / 25.4
Part.Parameter("D1@Sketch2").SystemValue = TextBoxFrameWidth.Value / 25.4
Part.Parameter("D1@Sketch3").SystemValue = TextBoxFrameWidth.Value / 25.4
Part.Parameter("D1@Sketch4").SystemValue = TextBoxFrameWidth.Value / 25.4

To get the correct dimension parameters, go to an automatically created model and display the dimensions.  You can right click on each dimension to get the appropriate parameters from the "Full Name" field in the dimension properties dialog.  We will also need to add the appropriate "TextBox???.Value" for retrieving numerical values from the form.  Don't forget, if you are working in inch units, you need to convert the value from the form to metric, since SolidWorks values are always entered/received in metric units.  

The last steps we need to do are rebuild the model, redraw the graphics, and show the model in Isometric, and zoom to fit just so the user can see everything when we are done.  We can also close the macro so the user can't run it again.  This is easily done by adding the following lines at the end of the routine.

Part.ForceRebuild3 True
Part.GraphicsRedraw2
Part.ShowNamedView2 "*Isometric", 7 
Part.ViewZoomtofit
End

At this point, we need to test the macro to see that it works as expected.  Go ahead and start a new part, go to the "Main" module, hit "F5" to run the macro, enter the desired values, and see what happens.  I you did everything right, you should see the geometry recreated with the values entered when the macro was run.

In doing this macro, we started with the macro recorder.  Upon customizing the macro to accommodate user defined sizes, we kept it simple.  To reduce potential problems with using this macro in the future, you will want to consider adding the following functionality:
* Add code in the "Main" routine that checks to see if the active document is a part.  If a part is found, it then shows the form and waits for user input.  This simple code prevents a user from trying to run the macro within an assembly or drawing.  
* Check the part to see if there is any mass.  If you find mass, this could indicate that a body already exists in the model.  In this case, you should prompt the user before showing the form.
* In the form, you should run a check to insure that all textboxes have valid entries, before creating the geometry. If there is a problem, tell the user what they need to fix.  You should check the frame thickness to ensure that the offsets can be modified without causing errors.
* Check your units.  As written, my macro works in inch units.  All values entered into the form will have to be converted to meters when they are placed into the code.  Remember, SolidWorks values are entered/received in metric units.  You can always read the unit settings in the model and then process the input values accordingly.

You can get the sample macros, and model here.  This archive includes the recorded macro, updates as defined above, and a more robust version that includes many of the additional checks I mentioned near the end of this article.  

Is this macro done?  Not really.  It all depends on your experiences while using the macro.  In the future you may realize that you could add a few new features that will make this macro even better than what it is now.

Between the time I initially created this macro and blog, I have since added code (see FrameBox4.swp macro) to do the following:
* Allow the user to keep changing the values, and re-applying those values to the model when the user hits the "Create" button.  To do this, I checked the mass property again.  If mass existed, then I skipped the recorded portion of the macro and went right to applying the dimensions to the model.
* If there are no documents active in SolidWorks, this macro will load the default part (if properly defined in the Tools/Options/Default Templates).

This is an example of how a macro can keep evolving as you continue to use it, and another example how Old Macros Don't Die... (http://designsmarter.typepad.com/lennyworks/2007/03/old_macros_dont.html)

Once again, good luck.
