GetObject( ) or CreateObject( )? Is there a difference? - Part I
October 4, 2007
Disclaimer: 99.9% of all the API programming I do these days is in .NET so for the times that I do answer a question incorrectly, 80% of the time it is a VBA (Visual Basic for Applications) question. Since most people start with VBA before they move on to .NET, however, I decided to cover this topic for VBA.
Set swApp = CreateObject(”SldWorks.Application”)
Almost all SolidWorks Macros start out with that same, famous line of code. In fact, whenever you record a Macro in SolidWorks, the SolidWorks Macro Recorder is kind enough to fill that line in for you. What does it really mean, though? And why do a few Macros begin instead with this line of code:
Set swApp = GetObject(,”SldWorks.Application”)
Is there a difference? If there were no difference, then this would be a very short article. You have probably guessed correctly that there is a difference. The GetObject( ) call will attach to an existing instance of SolidWorks if one is running. If there is no instance of SolidWorks already running, then GetObject( ) will return an error. The CreateObject( ) call will also attach to an existing instance of SolidWorks if one is running. However, if there is no instance of SolidWorks already running, then CreateObject( ) will create one and attach to it. Because of this, most Macros contain the CreateObject( ) call as a way of hedging bets.
Why should I care? This behavior can be used to your advantage when you run into situations where you need to know if the application being called was running before you called it. You might need to know, for instance, whether or not to shut down Excel when your Macro is finished.Let’s say, for example, that a user who already has Excel up and running decides to run your Macro. If your Macro arbitrarily closes Excel when it is finished, then any unsaved changes to Workbooks will be lost. This could make you the target of nasty phone calls and maybe even litigation. One solution is to leave Excel running. This is not a desirable solution because of the resources that would be tied up by Excel (or any other application that you start up and leave running when finished). It is also a slight breach of programming etiquette.
How do I use this to my advantage? It is very simple.You start out by declaring an ‘alreadyRunning’ flag (i.e. a Boolean variable) and then you make a call to GetObject ( ). If that call doesn’t throw an error, then you make sure that ‘alreadyRunning’ is set to True and you procede with your Macro. If, however, the GetObject( ) call throws an error, then you make sure ‘alreadyRunning’ is set to False and you make a subsequent call to CreateObject( ). From there, you proceed with your Macro and at the end of your Macro, you put a line of code in that will close Excel because alreadyRunning=False.
Below is sample code for an Excel Macro (i.e. written for and residing in Excel) that employs this method. In this example, however, it is SolidWorks itself that needs to be either closed or left running depending on its state at Macro execution time. Because of this, the ‘alreadyRunning’ variable mentioned above is called “swxAlreadyOpen” for this specific application of the concept.You can download the files for this example from here.The Macro below will:
- Run upon opening the Excel Workbook that contains it
- Open the specified (i.e. hard-coded) model in SolidWorks
- Query the model for some information
- Write that information to the Excel Spreadsheet
- Close the model
- Close SolidWorks if it wasn’t running when the Workbook was opened
Disclaimer: The provider of this Macro assumes no liability for this Macro and makes no warranties for the Macro. Use at your own risk.
Note: This Macro builds upon an earlier and simpler example which can be downloaded from here.
Excuses: The Macro could benefit from some other programming best practices but I intentionally kept it as simple as possible so as to not confuse the readers.
**************Begin Excel Macro*********************
Option Explicit
Private Sub Workbook_Open()
‘This event handler is called every time the workbook is opened in Excel.
Dim swapp As SldWorks.SldWorks
‘Booleans have a default value of false.
Dim swxAlreadyOpen As Boolean
‘If the call below errors out, then we know SolidWorks wasn’t running. Workbook_OpenErrorHandler will handle this case for us.
On Error GoTo Workbook_OpenErrorHandler
‘Try to get a handle to an already running session of SolidWorks.
Set swapp = GetObject(, “SldWorks.Application”)
‘SolidWorks was already running. We know this because we would not have hit this line if SW was not running – the ErrorHandler would have already redirected us.
swxAlreadyOpen = True
‘Make sure we have a handle to SolidWorks.
If Not swapp Is Nothing Then
Call
populateSpreadsheet(swapp, Not swxAlreadyOpen)
Else
‘Put a msgbox here to warn the user that the macro couldn’t attach to SolidWorks.
Exit Sub
End If
Exit Sub
Workbook_OpenErrorHandler:
‘GetObject() call errored out so we know that SolidWorks isn’t running yet.
‘Create a new instance of SolidWorks.
Set swapp = CreateObject(”SldWorks.Application”)
If Not swapp Is Nothing Then
Call populateSpreadsheet(swapp, Not swxAlreadyOpen)
End If
‘Release COM objects
Set swApp = Nothing
End Sub
Sub populateSpreadsheet(ByRef swapp As SldWorks.SldWorks, ByVal
closeSolidWorksWhenFinished As Boolean)
Dim swDoc As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim swModelExt As SldWorks.ModelDocExtension
Dim xSheet As Excel.Worksheet
Dim xBook As Excel.Workbook
Dim strPartPath As String
Dim nErrors As Long
Dim nWarnings As Long
Dim nStatus As Long
Dim sheetIndex As Integer
Dim vMassProps As Variant
‘Note: The file “Upper Fence - RH.SLDPRT” must reside in the same folder as this spreadsheet.
strPartPath = Excel.ActiveWorkbook.Path
strPartPath = strPartPath & “\Upper Fence - RH.SLDPRT”
Set swDoc = swapp.OpenDoc6(strPartPath, swDocPART, swOpenDocOptions_Silent Or SwConst.swOpenDocOptions_ReadOnly, “”, nErrors,
nWarnings)
Set swPart = swDoc
‘Since PartDoc inherits from ModelDoc2, we can query PartDoc for ModelDoc2.Extension
Set swModelExt = swPart.Extension
‘Get mass properties from modeldocextension object
vMassProps = swModelExt.GetMassProperties(1, nStatus)
‘Loop through worksheets
For Each xSheet In Excel.ActiveWorkbook.Sheets
If xSheet.Name = “PartProps” Then
‘Since PartDoc inherits from ModelDoc2, we can query PartDoc for ModelDoc2.GetTitle
xSheet.Cells(1, 2).Value = swPart.GetTitle
‘Since PartDoc inherits from ModelDoc2, we can query PartDoc for ModelDoc2.GetPathName
xSheet.Cells(2, 2).Value = swPart.GetPathName
If Not IsEmpty(vMassProps) Then
‘Mass
xSheet.Cells(3, 2).Value = vMassProps(5)
‘Area
xSheet.Cells(4, 2).Value = vMassProps(4)
‘Volume
xSheet.Cells(5, 2).Value = vMassProps(3)
Else ‘vMassProps is empty so just overwrite old
values with question marks
‘Mass
xSheet.Cells(3, 2).Value = “?”
‘Area
xSheet.Cells(4, 2).Value = “?”
‘Volume
xSheet.Cells(5, 2).Value = “?”
End If
End If
Next
‘Close SolidWorks if it wasn’t already running. Otherwise, just close the document being queried.
If closeSolidWorksWhenFinished Then
swapp.CloseAllDocuments (True)
swapp.ExitApp
Else
swapp.QuitDoc (swDoc.GetTitle)
End If
‘Release COM objects
Set swPart = Nothing
Set swModelExt = Nothing
Set swDoc = Nothing
End Sub
**************End Excel Macro*********************
Thanks to Wayne Tiffany who contributed to this article.
If you enjoyed this post, make sure you subscribe to my RSS feed!
Comments
3 Responses to “GetObject( ) or CreateObject( )? Is there a difference? - Part I”
Got something to say?




This is a GREAT little blog article. Not only does it explain things clearly and simply as to the difference between two similar object calls, it even gives an example to help you try it out.
Thanks for the great information, keep more coming!
Hello,
What you say about this instantiation:
Set swApp = Application.SldWorks ?
Has this alternative any difference from CreateObject() call? (of course, if use it in macro, not in standalone application)
Hi Andrey,
Set “swApp = New Application.SldWorks”, as you probably know, is the way you instantiate the SldWorks.SldWorks class in .NET. It is analagous to the CreateObject( ) method in VBA.