Welcome to MSDN Blogs Sign in | Join | Help

Defrosting your code

One of our team members recently noticed an issue with Excel VBA code running on Windows Vista (it is something that happens on WindowsXP too, it is just more pronounced on Windows Vista), so I thought I would write it up.  While it is not the sort of issue that the Excel team can easily address, it is something worth mentioning to all the VBA developers out there, in part to see how people might be handling this situation already.

The behaviour in question is how Excel behaves when VBA code runs for more than ~5 seconds uninterrupted – for example, you are running some sort of loop that takes longer than 5 seconds to finish.  On WindowsXP, after 5 seconds or so, if the user starts clicking on the application to see if anything is happening, they will see a “Not Responding” show up in the title bar (which is a subtle enough change that many people do not even notice).  (Note – the circumstances around “Not Responding” appearing can be a bit more complicated than that, but I wont go into it, because it doesn’t really matter in the context of this discussion.)


The behaviour on Windows Vista is the same, with one exception – the Windows folks have done work to make it more apparent to the user when an application is “not responding”.  Specifically, they have a behaviour called “frosting”, which means that when the user starts clicking around the window, the whole window gets this semi-transparent look (which those of you in northern climes will recognize as frost) to really clue the user into the fact something abnormal is up.  (Again, there is more to it than this, and the code controlling when an app is considered not responding has changed between Windows XP and Windows Vista, but I wont go into the details for the purposes of this discussion.)


(Click to enlarge)

While this can be helpful in some cases, it probably isn’t the idea behaviour when it is code executing behind your workbook, since the user may decide to end-task on the code, which isn’t really what you want.

Because this behaviour stems from the fact that Office is not able to send messages to the OS when macros are running, the simplest work around is include a DoEvents call in your code to allow message processing when it is executing loops that may go on for a while – that prevents the frost (and “Not Responding in the title bar).

Assuming that makes sense, let’s have some audience participation time … do people run into this already?  If so, what sort of workaround have you used?

Published Friday, June 30, 2006 8:13 AM by David Gainer
Filed under:

Comments

# re: Defrosting your code

Friday, June 30, 2006 1:52 PM by Anonymous
Why doesn't Excel just disable most of it's UI and run the macros on a separate thread, instead of running them in the main thread like it's 1987 again? Multithreading has been in Windows for 13 years now..

# re: Defrosting your code

Friday, June 30, 2006 2:25 PM by Mike Rosenblum
Hmmm, I've not faced this myself. A macro taking more than 5 seconds should probably have a progress bar, and therefore 'DoEvents' is pretty much a necessity...

But as for a solution, I tend to agree with 'Anonymous' here.

Although Excel cannot control what happens while VBA is running, it does control all the entry points when a Macro is run (unless it's a cross-process call). So I would think that a subtle "VBA Progress Bar" within the Status Bar could show that a VBA Macro is running, similar to the progress bar that runs when 'File > Save' is called. It should probably kick in after about a 1 second delay (so that fast macros are ignored) and be a "running lights" form of progress bar because there would be no way for Excel to know the percent of progress while the Macro is running.

Having a progress bar implies a second thread branching off for every VBA call, so I'm not sure about the performance implications of this; but I would think that it is VBA that should run in the "separate thread" while the main application thread runs under a form of 'Application.Interactive = False', if you will. That is, user interaction is blocked while the VBA code is running, but the application window is still responsive to repaint events and the like.

Just thinking out loud, anyway...

# re: Defrosting your code

Friday, June 30, 2006 4:20 PM by A User
I often display a VBA form in such situations, with or without progress bar, so that users understand they are waiting on a process. They do not expect the spreadsheet UI to respond behind an application modal form.

I imagine many users' first reaction to frosting will be to assume "something abnormal is up" rather than "busy or waiting" which makes it all the more important to provide some status or mode indication. If the VBA form frosts up however, its message would be undermined.

Sometimes I turn on ScreenUpdating periodically and force a Repaint so the user can see that something is happening. Of course this only works if something displayable is happening.

# re: Defrosting your code

Friday, June 30, 2006 4:41 PM by Air_Cooled_Nut
I rarely have macros running for long times (relatively speaking).  On the occations that I do, I liberally populate the Status Bar with messages or progressive dots or messages on a simple form (no buttons) so the end user knows something is happening -- it also helps me during any debugging ;-)  I feel such information/hand holding is the job of the macro developer and failure to do so indicative of poor end user considerations.

# re: Defrosting your code

Friday, June 30, 2006 4:53 PM by Sam Rad
I either use DoEvents or turn off screen updating for these situations, or both.  Also, I'll likely display a phat progress bar or some hot animation on the screen to give an indication that my code is running.

# re: Defrosting your code

Friday, June 30, 2006 5:38 PM by Francis
The second picture is, apropos, a fine example of why it is a bad idea for applications (instead of Windows) to draw the title bar. (Look at the Office menu.)

# re: Defrosting your code

Friday, June 30, 2006 6:39 PM by Jim Rech
Never been an issue for me, Dave, meaning no one has ever mentioned this to me.

But, as others have said, keeping users informed about what's going on (or at least that something is going on) is probably key.  Even if it's just via the status bar.

# re: Defrosting your code

Friday, June 30, 2006 9:27 PM by Alan Barasch
We hit this issue in Excel 2002 on XP SP2 a few months ago.

Have a procedure that grinds for 20 minutes. Added some Do Events and a progress counter to the Status Bar that updates every 1000 iterations -- basically slowing things down.

# re: Defrosting your code

Saturday, July 01, 2006 3:15 AM by Oliver Townshend
Wouldn't it be simpler to say "Press Ctrl-Break to pause non-responding Macro"?

# re: Defrosting your code

Saturday, July 01, 2006 6:42 AM by Mike Staunton
Does this affect just macros or will it freeze for all my user-defined functions - if so, I'll retrofit Windows 2000!

# re: Defrosting your code

Saturday, July 01, 2006 6:52 AM by Hazz
If a macro runs more than a few seconds then a progress indicator is de rigueur. A windows form progress meter and DoEvents is what I generally use. It's such a standard solution to such a common situation, I wouldn't be surprised if it became a single line of code soon :-)

# re: Defrosting your code

Monday, July 03, 2006 10:37 AM by Tianwei
Never noticed, but again I always put up a form notifying users something on the background is running.

# re: Charting

Monday, July 03, 2006 9:19 PM by S R
Maybe this can be part of the wishlist for charting:
if there are, say, 3 time series of data that needs to be charted as line graph, so the x axis is time or date and y axis is the value of the variables, now after the chart has been created one can see the value at any point in a particular series by hoovering the mouse over a partcular point in the graph of that time series(tool tip). It will be nice to have a feature where if one hoovers the mouse anywhere in the graph it automatically shows all the Y axis values for all 3 timeseries for that particular value of x-axis in either 3 different tool tips or in a combined tool tip. The reason for it is in financial data analysis we come across situations where we have to plot spreads or returns of multiple securities in one graph and also have the flexibility of seeing the values of all of them at a particular time visually without cluttering the whole graph with labels and values.

# re: Defrosting your code

Tuesday, July 04, 2006 6:34 AM by Paul Morriss
Like the others, I let the users know what's going on. However, if Excel can respond to Ctrl-Break then can't it respond to other events? I think the problem should be fixed in Excel, not in our macros!

# re: Defrosting your code

Tuesday, July 04, 2006 9:40 AM by John Greenan
We use a wrapper to write to the status bar and increment at a sensible interval to add a "." to code - for example:
"Gathering FIX message details"
"Gathering FIX message details."
"Gathering FIX message details.."
"Gathering FIX message details..."

You need to wrap up the call to application.statusbar in an error handler and trap for RTE 50290 and ensure that you always write less than 250 characters, but it's just a simple matter of courtesy to your user to inform them that the spreadsheet is busy doing some number crunching.

I am not a fan of getting people to automatically run DoEvents though - it's a bit crappy and does seem to be error prone.

# re: Defrosting your code

Friday, July 07, 2006 8:09 AM by Sam
"One of our team members recently noticed an issue with Excel VBA code running on Windows Vista ..."
"Recently noticed" ...wow... becuase this has been hapening since Excel 97.... prior to that Excel 95 would just crash...

What do we do..We wait.... for Excel 2017 when this will get fixed

It also happens in Outlook 2007 when doing a Send / receive - syncronising folders (on a slow connection) or a large download


What do we do....We just build non value added stuff like progress bar and incremental satus bar....so forth in to our code....

"Runnig a macro " instead of "Not responding" appearing would be a big help


New Comments to this post are disabled
 
Page view tracker