First of all. Why not implement the functionality in the add-in instead of calling the macro? That would solve it... (tested that idea on VBA Macro, did not work out at that well.)
Second, for what reason did you go for a add-in? By a quick look it seems that you only have the event listening there. As I tried to help you in a previous post, you can do this just by using macro if you like. I still think it is good to not mix add-in and macros. I would think it was somehow ok if it was due to maintenance of parts of the code since macros can easily be edited by anyone).
Did some testing this evening... tried to use the "not-that-good-idea" sleep function but it actually makes the complete SolidWorks to sleep (sleep from add-in makes macro sleep). Tried also to have other actions as triggers to continue the VB add-in. I had it to look for a file that the macro creates, but that did not work out either. The idea I tried was to have a loop looking for that file in the add-in event. Once the file exist I thougt it would be Ok to let the process go.
I also played around more on the macro side, tried to just run macro with the event and implemented all of the code into the event function. It still fails.
So with my narrow knowledge I can not get this work.
To test with I have used a macro I created to save tif images from the drawing that is open. But what ever I do it fails. I keep getting blank (white) tif images. I also tried to have the Close function to be canceled once triggered, but it seems not to work. So it seems that the event is living its own life once triggered...
So I end up recommending that you make a separate icon/pane/menu or something to trigger your macro / function. And in that macro / function you could add the close of the document.
I will follow this thread and see if some skilled one can help you out. I'm most interested to see if this is possible.
runMacro is obsolete, has RunMacro2 same behavior?
I did some sampling and it does not work for the RunMacro2. I have tested to add the SaveAs method in the event it self and still getting similar error as Darren describes.
Which when I'm doing sampling is a white tif file instead of a tif file that looks like the drawing.
Here is the VBA code I used when I tried to save a TIF file when the drawing closes. (Do not worry, swapp is defined...)
Private Function swDrawing_DestroyNotify2(ByVal DestroyType As Long) As Long Dim lErrors As Long Dim lWarnings As Long Dim retval As Boolean Dim swmodel As SldWorks.ModelDoc2 Set swmodel = swapp.ActiveDoc retval = swmodel.Extension.SaveAs("C:\maketransparent\test.tif", swSaveAsCurrentVersion, swSaveAsOptions_Silent, Nothing, lErrors, lWarnings) MsgBox "retVal: " & retval & vbNewLine & "Errors: " & lErrors & vbNewLine & "Warnings: " & lWarnings End Function
This gives me just a blank (white) TIF. But if I run the code in a regular way by press run I get a working TIF.
It seems to me that the DestroyNotify2 event is not waiting for the SaveAs to complete the output.
Came across this thread searching for something else.
I did not open your text file attachment, but I just glanced at the code above, and maybe try the following to see if that works.
Assuming the SaveAs command is going to return a value of True, you could create a DoEvents loop that allows the command to process until that condition is met.
I use DoEvents loops like this all the time when I need to wait for a call to a COM object to complete.
You can optionally add a timeout timer, which will prevent a never ending loop.
Private Function swDrawing_DestroyNotify2(ByVal DestroyType As Long) As Long Dim lErrors As Long Dim lWarnings As Long Dim retVal As Boolean Dim swmodel As SldWorks.ModelDoc2 Set swmodel = swapp.ActiveDoc retVal = swmodel.Extension.SaveAs("C:\maketransparent\test.tif", swSaveAsCurrentVersion, swSaveAsOptions_Silent, Nothing, lErrors, lWarnings) while retVal=false DoEvents wend MsgBox "retVal: " & retval & vbNewLine & "Errors: " & lErrors & vbNewLine & "Warnings: " & lWarnings End Function
Very interesting input! Will try to check it out when I got the chance.
A little reference: Definition of DoEvents in Visual Basic for Applications
If you want to add a timer, you can do so like:
Sub FOO() Dim dateTime As Date Dim blnReturn As Boolean Dim objX As Object Set objX = CreateObject("WIDGET") 'initialize instance of some object dateTime = DateAdd("s", 30, Now()) 'set timeout value as 30 seconds from now blnReturn = objX.ReturnTrueMethod 'call some method that will return a value of true Do While blnReturn = False 'checks condition before executing If Now() > dateTime Then 'check if we've exceeded the timeout value MsgBox "Timed out", vbOKOnly + vbCritical 'alert the user Exit Do End If DoEvents 'allow the ObjX.ReturnTrueMethod more time to complete Loop End Sub