To keep an Excel VBA UserForm above other windows on Windows, call the Windows API function SetWindowPos with the HWND_TOPMOST option when the form activates. This makes the form a topmost window; it can remain visible over Excel and other ordinary application windows, but it does not guarantee that it will cover every other topmost window.
What “on top” means in Excel
Excel UserForms do not have a built-in VBA property that means “always stay above every other window.” A form may appear in front when it opens, then move behind Excel or another application after the user changes windows. This is especially noticeable with modeless forms, which let the user continue working in the workbook while the form remains open.
Windows manages which windows appear in front using a z-order. A topmost window belongs to a special group that Windows keeps above non-topmost windows. The API call in this article changes the UserForm’s position in that z-order; it does not pin the form to a screen location, prevent it from being minimized, or make it impossible for the user to switch to another app.
How the Windows API approach works
The code first uses FindWindow to get the Windows handle for the UserForm. It searches by the form’s window class and caption. Then SetWindowPos marks that window as topmost. The flags SWP_NOMOVE and SWP_NOSIZE tell Windows to leave the form’s position and dimensions unchanged; SWP_NOACTIVATE avoids forcing it to take focus as part of the change.
In the example, ThunderDFrame is the class name commonly used for VBA UserForms, and Me.Caption supplies the form’s title. Because the lookup uses the caption, give the form a distinctive caption if other open forms could have the same one. The code checks whether the handle was found before calling the positioning API.
Code to keep the UserForm on top
In the Visual Basic Editor, open the code module for the specific UserForm and add this code. It is written for Excel for Microsoft 365 on Windows with VBA7, whether Office is 32-bit or 64-bit. Keep the API declarations at the top of the form module, before its event procedures.
Option Explicit
' Windows API declarations for VBA7 on 32-bit or 64-bit Office.
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function SetWindowPos Lib "user32" _
(ByVal hWnd As LongPtr, ByVal hWndInsertAfter As LongPtr, _
ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal uFlags As Long) As Long
Private Const HWND_TOPMOST As Long = -1
Private Const HWND_NOTOPMOST As Long = -2
Private Const SWP_NOSIZE As Long = &H1
Private Const SWP_NOMOVE As Long = &H2
Private Const SWP_NOACTIVATE As Long = &H10
Private Sub UserForm_Activate()
SetFormTopMost True
End Sub
Private Sub SetFormTopMost(ByVal makeTopMost As Boolean)
Dim hForm As LongPtr
Dim insertAfter As Long
hForm = FindWindow("ThunderDFrame", Me.Caption)
If hForm = 0 Then Exit Sub
If makeTopMost Then
insertAfter = HWND_TOPMOST
Else
insertAfter = HWND_NOTOPMOST
End If
' Change z-order without moving, resizing, or activating the form.
Call SetWindowPos(hForm, insertAfter, 0, 0, 0, 0, _
SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOACTIVATE)
End Sub
The activation event runs when the form becomes active, so it reapplies the topmost setting if the form is activated again. The helper procedure also makes it possible to remove the setting by calling SetFormTopMost False from another procedure in the same form module. The return value from SetWindowPos is not needed for this basic example, but it can be checked if you want to add error reporting.
How to add and run the code
- Save a backup copy of the workbook before running a macro. VBA macros cannot be undone with Ctrl+Z.
- Save the working file as an Excel Macro-Enabled Workbook (
.xlsm) if it is not already in that format. - Press Alt+F11 on Windows to open the Visual Basic Editor. In Project Explorer, find the workbook and double-click the UserForm you want to keep on top.
- Paste the declarations and procedures into that form’s code module. Set the form’s Caption in the Properties window to a clear, distinctive title.
- Run the form from your existing macro, or use the editor’s Run command while the form’s startup procedure is selected. Switch to another window to check whether it stays above ordinary windows.
Alt+F11 is the Windows shortcut for opening the Visual Basic Editor. Excel for Mac has its own Visual Basic Editor and VBA support, but the Windows user32 API calls shown here do not work on Mac. Excel for the web does not run VBA macros, so this technique is limited to desktop Excel on Windows.
Modal and modeless forms
A modal UserForm, usually shown with vbModal, blocks interaction with the rest of Excel until it is dismissed. That makes it behave as a task dialog, but it does not turn the form into a Windows topmost window. A modeless form, shown with vbModeless, allows the user to select cells and work in Excel while the form stays open. Modeless forms are often where the topmost API call is most useful.
Topmost status and modality solve different problems. Use a modal form when the user must complete or cancel a task before returning to the workbook. Use a modeless form when the form should remain available during normal workbook work. The API can keep either type above ordinary windows, but it does not change whether Excel is blocked or whether the user can interact with the sheet.
Limitations and common problems
- The form is not found: If
FindWindowreturns zero, the code exits without changing the z-order. Check that the form’s caption matches the caption being used and that the class name is correct for the environment. A duplicate caption can make the lookup select the wrong form. - The form still goes behind another window: Topmost windows can appear above ordinary windows, but Windows can place another topmost window above yours. The setting is not exclusive ownership of the screen.
- The code will not compile on Mac:
user32is a Windows library. This code is specifically for Windows and should not be treated as portable VBA. - The declaration reports an error: The sample uses
PtrSafeandLongPtr, which are appropriate for VBA7 in current Microsoft 365 desktop Office. Much older Office versions with pre-VBA7 VBA require different declarations; do not simply removePtrSafefrom a 64-bit declaration. - The form is topmost but inconvenient: A form can cover menus or content in other applications. Keep it compact, allow users to close it, and use topmost behavior only when it supports the task.
Windows policies, virtual desktops, full-screen applications, and other software can also affect what is visible. If the form seems to disappear, first check whether it was closed, minimized, or moved to another display before changing the API code.
How to stop the form being topmost
Windows removes the topmost status when SetWindowPos is called with HWND_NOTOPMOST. The helper in the sample already supports this: call SetFormTopMost False from a button click, a menu action, or another suitable event in the form. For example, a button named cmdNormal could run that call in its click event. The form remains open; it simply returns to the ordinary window group.
You can also omit the activation event if you only want to set topmost status once, such as immediately after showing the form. If you retain the activation event, it will set the form topmost again whenever the form is activated, so use the “normal” action only if your design accounts for that behavior.
Alternatives and when to use them
If the requirement is only to keep a small panel available while the user works in one workbook, consider whether a modeless form without topmost status is enough. It avoids covering unrelated applications and may be a better fit for a workbook-specific tool. A worksheet dashboard, task pane, or controls placed directly on a sheet can be more discoverable and do not require manipulating window z-order.
For an interface that must stay above other Windows applications, the API approach is the direct option for a VBA UserForm. There is no cross-platform UserForm property that provides the same always-on-top behavior. If the workbook must run on both Windows and Mac, keep the core workflow independent of this Windows-only feature and provide a practical Mac-specific interface instead.
Frequently Asked Questions
Can Excel VBA keep a UserForm on top of all other applications?
It can mark the form as topmost using Windows API calls, keeping it above ordinary windows. Other topmost windows may still appear above it, so “always on top” is not an absolute guarantee.
Does this work with a modeless UserForm?
Yes. The code can be used with a modeless form, and this is a common reason to keep a form visible while working in Excel. Topmost status does not itself make a form modeless; that depends on how the form is shown.
Can I keep a VBA UserForm on top on a Mac?
Not with the Windows user32 declarations in this example. Mac Excel supports VBA, but it does not provide these Windows API functions; Excel for the web does not run VBA macros at all.
Why does FindWindow return zero?
The class name or caption may not match the actual form window, or the form may not yet be available when the lookup runs. Check the caption, use a unique title, and confirm that the form is active when the code executes.
Will the setting survive after I close Excel?
No. The code changes the current form window’s z-order while it exists. It does not permanently change Excel or Windows settings, and a newly created form needs the code to apply topmost status again.
Related
- Excel Not Responding and Won’t Close? Try These Fixes
- Excel Named Ranges List: Find, View, and Manage Defined Names
- Excel Named Range Shortcut: Create, Edit, and Use Names
Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.
More in VBA & macros
- VBA Excel Send Email Without Outlook?Yes. In Excel for Microsoft 365 on Windows, a VBA macro can send email without Outlook by connecting…
- Excel Macro Step Into: How to Debug VBA Line by LineIn Excel VBA, Step Into runs a macro one statement at a time and enters any procedure or…
- VBA Code Workbook Open: How to Run Macros at StartupTo run VBA when an Excel workbook opens, put a Workbook_Open event procedure in that workbook’s ThisWorkbook code…
- VBA Array: Find a Value and Get Its Index in ExcelTo find a value in a VBA array and get its index, loop from LBound to UBound and…
- Excel VBA File Path of an Open WorkbookIn Excel VBA, use ActiveWorkbook.Path to get the folder of the workbook currently active in Excel, or ThisWorkbook.Path…
- Excel VBA: Create a Word Document from a TemplateTo create a Word document from an Excel VBA macro on Windows, use Word’s automation object to open…
Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources
Spotted an error in this guide? Let us know.