🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA StatusBar in Excel — Show Macro Progress Without a UserForm (and the Message That Gets Stuck Forever)

|

VBA StatusBar in Excel — Show Macro Progress Without a UserForm (and the Message That Gets Stuck Forever)

TL;DRApplication.StatusBar = "..." writes your own text into the bar along the bottom-left of the Excel window. It is the lightest possible progress indicator — one line, no UserForm, no flicker, and it survives ScreenUpdating = False. The catch is the reset: whatever you wrote stays stuck there after the macro ends until you hand the bar back to Excel with Application.StatusBar = False (not an empty string). Restore it in an error handler so a crash does not leave a stale message pinned to the window:

Sub LongJob()
    Application.ScreenUpdating = False
    On Error GoTo CleanExit
    Dim i As Long, n As Long
    n = 10000
    For i = 1 To n
        ' ... do work on row i ...
        If i Mod 250 = 0 Then
            Application.StatusBar = "Processing " & i & " of " & n & " (" & Int(i / n * 100) & "%)"
        End If
    Next i
CleanExit:
    Application.StatusBar = False        ' hand the bar back to Excel - do NOT leave it as ""
    Application.ScreenUpdating = True
End Sub

When a macro runs for more than a second or two, the user's first question is "is this thing still alive?" The status bar answers it for the price of one line. This guide is built on one idea — the status bar is on loan: you write to it, and you must give it back. Excel will not reclaim it on its own, so the entire difference between a professional progress indicator and a window with a frozen "Processing 73%..." baked into it is a single reset line.

What you'll learn

  • The mental model — the status bar is Excel's, you borrow it and must return it
  • The write-and-reset pattern, and why = False beats = ""
  • The progress-percent idiom that answers "how much longer?"
  • Why the text does not update in a tight loop — and where DoEvents fits
  • When the one-liner is enough and when a real UserForm progress bar earns its keep
  • How it pairs with ScreenUpdating and the CleanExit restore

The mental model: the bar belongs to Excel

By default, the strip at the bottom-left of the window is Excel's to manage. It shows "Ready," or "Calculating," or the sum of your selected cells. When you assign a string to Application.StatusBar, you take that space over — Excel stops posting its own messages there and displays yours instead. From that moment, the bar is yours until you give it back.

Giving it back is one line: Application.StatusBar = False. That does not just clear the text — it returns control to Excel, so the bar resumes showing "Ready" and friends. This is the single fact that trips everyone up, so it is worth stating plainly:

Application.StatusBar = "Working..."   ' you now own the bar
Application.StatusBar = False          ' you give it back; Excel manages it again

Why False, not an empty string

The instinct when you are done is to clear the message: Application.StatusBar = "". That looks clean, and it is wrong. An empty string is still your message — a blank one. Excel keeps deferring to you, so the bar sits empty and never goes back to showing "Ready" or the selection sum. It is the same bug as leaving stale text, just harder to notice because the symptom is a suspiciously silent status bar rather than a visible frozen message.

Application.StatusBar = False is the only assignment that says "I am done, take it back." Make it a reflex: the line that turns the status bar on has a matching = False in the CleanExit handler, exactly like ScreenUpdating = True does.

The progress-percent idiom

The reason people search for a "VBA progress bar" is almost always this: a loop that runs long enough that the user needs to see it moving. The status bar does that with no extra UI:

Dim i As Long, n As Long
n = UBound(data)
For i = 1 To n
    ' ... work ...
    If i Mod 100 = 0 Then
        Application.StatusBar = "Row " & i & " of " & n & " - " & Format(i / n, "0%")
    End If
Next i

Two details make it feel right. First, update on an interval (i Mod 100 = 0), not every iteration — writing the status bar 10,000 times is itself slow and the user cannot read numbers flying by that fast. Second, show progress out of a total (i of n, a percent), not just a spinner, so the user can estimate how much longer. That is the difference between "something is happening" and "you are two-thirds done."

Why the text does not update — and where DoEvents fits

Here is the trap that sends people to the forums: you set Application.StatusBar in a loop and the text never changes on screen — it shows the first value and freezes, even though your code is clearly reassigning it. The status bar, like everything else, only repaints when Excel gets a moment to process its message queue. A tight VBA loop never yields that moment, so the paint never happens.

The fix is DoEvents — it hands control back to Excel briefly so the bar actually redraws:

If i Mod 100 = 0 Then
    Application.StatusBar = "Row " & i & " of " & n
    DoEvents                      ' let Excel repaint the bar
End If

Use it on the same interval as the update, not every iteration — DoEvents has its own costs and re-entrancy risks. And note this is the one place where the status bar behaves better than a UserForm under ScreenUpdating = False: the status bar updates fine with screen updating off, whereas a UserForm progress bar needs an explicit .Repaint.

When the one-liner is enough — and when it is not

For the large majority of macros, Application.StatusBar is the right progress indicator, and reaching for a UserForm is over-engineering. It is one line, it does not steal focus, it does not flicker, and it coexists with ScreenUpdating = False. Prefer it by default.

A UserForm progress bar earns its extra code only when you specifically need something the status bar cannot give: a graphical filling bar, a cancel button, a multi-line breakdown, or branding in a dialog the user cannot miss. Those are real needs sometimes — but they are the exception, and they come with focus, repaint, and modality headaches the status bar sidesteps entirely. Note too that Application.DisplayStatusBar must be True for the bar to be visible at all; if a previous macro or setting hid it, your text will be written but not shown.

How ExcelMaster helps

A good progress indicator is one line to write and one line to reset, plus the judgment to update on an interval, add DoEvents only where the bar needs to repaint, and restore with = False in an error handler so a crash does not pin a stale message to the window. Miss the reset and you ship a workbook that says "Processing 47%..." forever.

ExcelMaster wires this up for you. Ask it to "show progress while this runs across 50,000 rows," and it writes the percent to the status bar on a sensible interval, pairs it with DoEvents so it actually moves, and resets the bar with Application.StatusBar = False in the same CleanExit restore as ScreenUpdating — so you get a progress indicator that behaves and cleans up after itself.

Frequently asked questions

How do I show a progress bar in Excel VBA?

The lightest way is Application.StatusBar = "...", which writes your text into the bar at the bottom-left of the window — no UserForm required. Update it on an interval inside your loop (for example If i Mod 100 = 0 Then), show progress as "row i of n" or a percent, and reset it with Application.StatusBar = False when you finish. A graphical UserForm progress bar is only worth the extra code when you need a filling bar or a cancel button.

How do I reset Application.StatusBar in VBA?

Set Application.StatusBar = False. That returns control of the bar to Excel so it shows "Ready" and its own messages again. Do not use Application.StatusBar = "" — an empty string is still your message, so Excel keeps deferring to you and the bar stays blank instead of resuming normal behavior.

Why does my status bar text not update while the macro runs?

Because a tight VBA loop never lets Excel process its message queue, so the bar never repaints. Add DoEvents right after you set the text (on the same interval as the update) to give Excel a moment to redraw it. Unlike a UserForm progress bar, the status bar does update correctly with ScreenUpdating = False.

Does the status bar work with ScreenUpdating turned off?

Yes. Application.StatusBar updates even when Application.ScreenUpdating = False, which is one reason it is a better default than a UserForm progress bar for long macros. You may still need DoEvents for the text to repaint inside a tight loop. Also make sure Application.DisplayStatusBar is True, or the bar is hidden and your text will not show.

StatusBar vs a UserForm progress bar — which should I use?

Use Application.StatusBar for almost everything: it is one line, no flicker, no focus stealing, and it survives ScreenUpdating = False. Build a UserForm progress bar only when you specifically need a graphical filling bar, a cancel button, or a multi-line status the single-line bar cannot show.

Tested in

Tested in: Excel 365 (Windows 11), VBA 7.1 — last verified 2026-08-18.

Related guides: VBA DoEvents · VBA DisplayAlerts · VBA ScreenUpdating · VBA On Error · VBA MsgBox