TL;DR —
Application.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 survivesScreenUpdating = False. The catch is the reset: whatever you wrote stays stuck there after the macro ends until you hand the bar back to Excel withApplication.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
= Falsebeats= "" - 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
