Fixing Links To UDFs in Addins
Pages in this article
- Fix #Name! Errors
- Detecting Workbook Opening
- Processing Newly Opened Workbook
- Handle Workbooks Opened From Explorer
Handle Workbooks Opened From Explorer
The trick I used here is to schedule a macro when the add-in opens, which detects if any workbooks have to be processed. This is done using these lines in the Workbook_Open event of the add-in:
modProcessWBOpen.TimesLooped = 0
'Schedule macro to run after initialisation of Excel has
fully been done.
'Sometimes, the addin hasn't fully been initialised and the
'workbook we want checked is opened BEFORE we have fully
initialised the
'addin.
'This may happen when one double clicks a file in explorer
Application.OnTime Now + TimeValue("00:00:03"),
"CheckIfBookOpened"
I've set this up in such a way, that I count the number of times the routine called "CheckIfBookOpened" is run. After 20 times I suspend looking for new files, assuming there are none. Any new files opened will be handled by the class module.
Here is all the code that belongs to checkIfBookOpened (placed in the same module "modProcessWBOpen"). Note that I have added two module-level variables at the top of that module:
Option Explicit
'Counter to keep score of how many workbooks are open
Dim mlBookCount As Long
'Counter to check how many times we've looped
Private mlTimesLooped As Long
The remainder of the code is:
Sub CheckIfBookOpened()
'-------------------------------------------------------------------------
' Procedure : CheckIfBookOpened
' Company : JKP Application Development Services (c) 2005
' Author : Jan Karel Pieterse
' Created : 6-6-2008
' Purpose : Checks if a new workbook has been opened
(repeatedly until activeworkbook is not nothing)
'-------------------------------------------------------------------------
'First, we check if the number of workbooks has changed
If BookAdded Then
If ActiveWorkbook Is Nothing Then
mlBookCount =
0
'Increment
the loop counter
TimesLooped =
TimesLooped + 1
'May be
needed if Excel is opened from Internet explorer
Application.Visible = True
If
TimesLooped < 20 Then
'We've not yet done this 20 times, schedule another in 1 sec
Application.OnTime Now + TimeValue("00:00:01"), "CheckIfBookOpened"
Else
'We've done this 20 times, do not schedule another
'and reset the counter
TimesLooped = 0
End If
Else
ProcessNewBookOpened ActiveWorkbook
End If
End If
End Sub
Public Property Get TimesLooped() As Long
TimesLooped = mlTimesLooped
End Property
Public Property Let TimesLooped(ByVal lTimesLooped As Long)
mlTimesLooped = lTimesLooped
End Property
Function BookAdded() As Boolean
If mlBookCount <> Workbooks.Count Then
BookAdded = True
CountBooks
End If
End Function
Basically what happens is this:
- When the add-in opens, we count how many workbooks are currently open in Excel
- We schedule the macro CheckIfBookOpened to be run in a couple of seconds, giving Excel (and our addin too!) the opportunity to fully initialise. In the mean time, Excel may also load the file we've double clicked upon.
- CheckIfBookOpened then checks if the number of open workbooks has changed and if so, runs the "ProcessNewBookOpened" routine on the active workbook
or
download the latest source code from github
Conclusion
That's it. A bit convoluted, I agree. The other two options I noted at the start of this article may be simpler for your situation. Should you have an even simpler one, don't hesitate to leave a comment!
Comments
All comments about this page:
Comment by: hymced (22-11-2016 16:50:38) deeplink to this comment
Hello
very interresting article !
just one thing : I can't get the point of the Workbook_BeforeClose and Workbook_Deactivate events on the ThisWorkbook VB component of the add-in ??
Thank you for your answer !
Comment by: Jan Karel Pieterse (22-11-2016 19:19:11) deeplink to this comment
Hi hymced,
Those are there to avoind the add-in loosing the application events when:
- The user quits Excel (now the BeforeClose event fires, shutting down the application event handler)
- Excel asks to save changes and the user cancels the save and hence the quit of Excel
So the code schedules a macro that reinstates the event handler, but when the deactivate event triggers (just before the add-in closes) it unschedules that same event again to avoid the ontime macro forcing the add-in to be opened again.
Clear as mud?
Comment by: hymced (23-11-2016 14:29:30) deeplink to this comment
Yes, after several reading, I do get it ! ^^
Here how I would put your explanation another way round :
These _BeforeClose and _Deactivate events are there to avoid the add-in loosing the application events when the user quits Excel (the BeforeClose event fires, shutting down the application event handler) but then cancels the save asked by Excel if there are changes (and hence the quit of Excel).
Indeed, the code schedules a macro that reinstates the event handler after the _BeforeClose event, but when the _Deactivate event triggers (just before the add-in closes) it unschedules that same event again to avoid the ontime macro forcing the add-in to be opened again.
Slightly different I agree :)
Anyway, thank you for your quick reply ;)
Have a question, comment or suggestion? Then please use this form.
If your question is not directly related to this web page, but rather a more general "How do I do this" Excel question, then I advise you to ask your question here: www.eileenslounge.com.