Hi All,
I've discovered recently that DoEvents doesn't yield to all events - for instance, OLEDBConnection objects do not update whilst VBA code is running when their state has been changed during a .Calculate call made from VBA, even if followed by a DoEvents loop. Aside from using scheduled firing of code (OnTime, SetTimer) - which is suitable some of the time, but not always - are there any APIs anyone can think of that would allow me to manually yield execution totally, and resume mid-procedure - something which would have a similar effect as:
But a bit less horrible. This approach will almost certainly work, but for a variety of reasons there's a fair chance I might have two of these running asynchronously, and that could get very messy very quickly. I can think of a few hacks to separate them (arrays of UDTs containing a GUID and the boolean, for instance, and an optional strGUID argument for ReCalc) but they feel like hacks. Does anyone know of any better approach than this?
I should also point out, I haven't actually tried Application.OnTime Now; I'm using Application.OnTime Now + CDate("00:00:01"), which obviously is a much longer pause. I'm not 100% certain that scheduling immediate execution will yield enough, though, so completely different approaches would be better.
Thanks in advance,
Toby
EDIT: Formatting
I've discovered recently that DoEvents doesn't yield to all events - for instance, OLEDBConnection objects do not update whilst VBA code is running when their state has been changed during a .Calculate call made from VBA, even if followed by a DoEvents loop. Aside from using scheduled firing of code (OnTime, SetTimer) - which is suitable some of the time, but not always - are there any APIs anyone can think of that would allow me to manually yield execution totally, and resume mid-procedure - something which would have a similar effect as:
Code:
Private mblnTotalYieldInProcess As Boolean
Public Sub ReCalc()
If mblnTotalYieldInProcess Then Goto AfterYield
<... Preceding actions here ...>
blnInitialState = oCN.OLEDBConnection.Refreshing
mblnTotalYieldInProcess = True
Application.OnTime Now, "ReCalc"
Exit Sub
AfterYield:
mblnTotalYieldInProcess = False
blnFinalState = oCN.OLEDBConnection.Refreshing
<... Rest of code here ...>
End Sub
But a bit less horrible. This approach will almost certainly work, but for a variety of reasons there's a fair chance I might have two of these running asynchronously, and that could get very messy very quickly. I can think of a few hacks to separate them (arrays of UDTs containing a GUID and the boolean, for instance, and an optional strGUID argument for ReCalc) but they feel like hacks. Does anyone know of any better approach than this?
I should also point out, I haven't actually tried Application.OnTime Now; I'm using Application.OnTime Now + CDate("00:00:01"), which obviously is a much longer pause. I'm not 100% certain that scheduling immediate execution will yield enough, though, so completely different approaches would be better.
Thanks in advance,
Toby
EDIT: Formatting