Call a Module from a UserForm Command Button in Excel

VBA & macros · Updated November 3, 2026

Call a Module from a UserForm Command Button in Excel

To call a VBA procedure in a standard module from an Excel UserForm command button, put the button’s Click event procedure in the UserForm code module and call a Public Sub in the standard module by its procedure name. For example, the button handler can run RefreshReport; the module name itself is not part of the call.

How the button-to-module connection works

A UserForm and a standard module serve different purposes. The UserForm contains the interface, such as text boxes, combo boxes, and command buttons. Its code module holds event procedures that respond to actions on that form. A standard module holds reusable procedures and functions that can be called from forms and other VBA code.

When someone clicks a command button, Excel runs that button’s Click event procedure. The event procedure can then call a public procedure in a standard module. This keeps the interface-specific response separate from the work the application needs to do. For instance, the Click event can read a selected value from a form and pass it to a procedure that updates a worksheet.

The basic arrangement is:

  • A command button on a UserForm has a name, such as cmdRefresh.
  • The UserForm code module has an event procedure named cmdRefresh_Click.
  • A standard module contains a procedure declared Public Sub RefreshReport().
  • The event procedure calls RefreshReport.

The event procedure is usually private to the form, while the procedure called from it must be accessible to that form. For a normal standard-module procedure, use Public or omit the access modifier, since a procedure in a standard module is public by default unless declared Private.

Set up the form, button, and procedure

In Excel for Microsoft 365 on Windows, open the Visual Basic Editor with Alt+F11. If the Developer tab is not visible, enable it from File > Options > Customize Ribbon. In the editor, choose Insert > UserForm to create a form, then add a CommandButton from the Toolbox. Select the button and use the Properties window to give its (Name) property a meaningful value such as cmdRefresh. The Caption property controls the text users see on the button.

Next, create the standard module with Insert > Module. A name such as modReportActions makes its purpose clear. Add the public procedure there. To create the button event, double-click the button on the form; the editor normally creates the Click event stub for that control. Put the call inside that event procedure.

These are the two code locations. The first procedure belongs in the standard module; the second belongs in the UserForm’s code module:

Option Explicit

Public Sub RefreshReport()
    ' Update a simple example on the Report worksheet.
    Dim ws As Worksheet

    Set ws = ThisWorkbook.Worksheets("Report")
    ws.Range("A1").Value = "Updated"
    ws.Range("B1").Value = Now
End Sub
Option Explicit

Private Sub cmdRefresh_Click()
    ' Run the reusable procedure when the button is clicked.
    RefreshReport
End Sub

This example expects a worksheet named Report. Change that worksheet name or the actions in the procedure to suit the workbook. Before running a macro, save a copy of the workbook: VBA changes cannot be undone with Ctrl+Z.

Call the procedure by its name, not the module name

A frequent point of confusion is whether the call should include the standard module’s name. If the module is named modReportActions and the procedure is named RefreshReport, the usual call is simply RefreshReport. You do not write modReportActions.RefreshReport for a procedure in a standard module.

The name in the event procedure must match the button’s (Name) property. If the button is still named CommandButton1, its event procedure is normally CommandButton1_Click. Changing the button’s visible Caption does not rename the control or its event; changing its (Name) property does. If you rename a control after creating code, confirm that the event procedure still corresponds to the control.

For a procedure with no arguments, either of these styles is valid:

  • RefreshReport
  • Call RefreshReport

When using the Call keyword with arguments, put the arguments in parentheses. Without Call, pass arguments without wrapping the entire argument list in parentheses. Choose one style and use it consistently to make the code easier to read.

Pass values from the UserForm

A button can pass values entered or selected on the form to a module procedure. This is useful when the module should perform work without depending directly on the form’s controls. For example, a form might let the user choose a report category, while the standard module receives that category as an argument.

In the standard module, declare the expected argument in the procedure’s signature. In the form’s Click event, read the control’s value and pass it in. The following illustrative procedure displays a selected item; it assumes the form has a combo box named cboItems and a button named cmdShow.

Public Sub ShowSelection(ByVal itemName As String)
    ' Display the value supplied by the form.
    MsgBox "Selected: " & itemName
End Sub
Private Sub cmdShow_Click()
    ' Convert the combo box value to text and pass it to the module.
    ShowSelection CStr(Me.cboItems.Value)
End Sub

Using an argument makes the procedure easier to reuse: another form or a different event can call it with a different value. It also makes the dependency explicit. If the control can be empty, validate the value before calling the procedure or make the procedure handle an empty string. For more than one input, define a clear argument for each value rather than having the module reach into a particular form to retrieve controls.

Choose where the code belongs

Put code in the UserForm module when it is specifically about that form’s interface: checking whether a text box is blank, enabling a button, or responding to a button click. Put general workbook operations in a standard module when they may be useful from more than one place. A procedure that writes a report, validates a set of inputs, or exports data is often a good candidate for a standard module.

There is no requirement to move every line of a short event into another module. A small button handler can contain its complete action if it is genuinely form-specific. Moving substantial or reusable work into a public procedure can make the form easier to maintain, but splitting code into many tiny procedures without a clear purpose can make a project harder to follow. A practical boundary is to let the event handler collect or validate interface values, then pass the work to a procedure when that work is reusable or substantial.

Also distinguish a standard module from a class module or another UserForm’s code module. A public method in a class or form is generally called through an instance of that object, not as if it were a standard-module procedure. If the target procedure is in a standard module, the direct call described here is the simplest approach.

Common errors and how to fix them

If clicking the button produces an error or nothing appears to happen, check the event, procedure visibility, names, and assumptions in the code. These checks solve many routine problems:

  • The event does not run: Confirm that the event procedure is in the correct UserForm code module and that its name matches the button’s (Name) property. Double-clicking the button in the form designer is a reliable way to open or generate its Click event.
  • “Sub or Function not defined” appears: Check spelling and confirm the target procedure exists in the VBA project. If it is declared Private in a standard module, change it to Public or remove Private so the form can call it.
  • The procedure has arguments: Supply the required arguments in the correct order and compatible types. A procedure that requires a value cannot be called as if it had no arguments.
  • A worksheet or range error occurs: Verify that the worksheet name exists in the workbook referenced by the code and that the range is valid. ThisWorkbook means the workbook containing the VBA code, which may differ from ActiveWorkbook.
  • The button seems to have the wrong event: Changing the Caption only changes visible text. Check the (Name) property and the event procedure name separately.
  • Compilation stops elsewhere: In the Visual Basic Editor, use Debug > Compile VBAProject to identify compile-time issues. The highlighted line may be in a different module from the button handler.

It is useful to add a breakpoint inside the Click event and step through the code with the editor’s debugging controls. That can establish whether the event fires and whether execution reaches the module procedure. Avoid adding a second procedure with the same name in another module, because duplicate or ambiguous names can make code difficult to resolve and maintain.

Test and run the UserForm safely

While editing, you can run the form from the Visual Basic Editor by selecting the UserForm and pressing F5. Click the button and verify the expected result. Test both ordinary input and likely edge cases, such as a blank text box or no selected combo-box item. If the procedure changes worksheet data, test first on a copy or on a small, reversible example.

A finished form is often opened by a separate macro, for example from a worksheet button or a workbook event. That launcher is separate from the command button’s Click event: the launcher displays the form, and the user’s click then triggers the event procedure. Keep the launcher and the form’s action procedure clearly named so it is evident which code opens the interface and which code performs the requested operation.

Macro-enabled workbooks should be saved in a macro-capable format such as .xlsm. Excel’s macro security settings may prevent VBA from running, particularly for files obtained from the internet or an untrusted location. Enable macros only for workbooks whose source you trust; do not lower security settings just to make an unfamiliar file run.

Windows and Mac considerations

The VBA structure—UserForm event procedure calling a public standard-module procedure—is the same on Windows and Mac versions of desktop Excel that support VBA. The main differences are in navigation and available platform features. On Windows, Alt+F11 opens the Visual Basic Editor. On many Mac keyboards, use Option+F11; depending on the keyboard and function-key settings, you may also need Fn. You can use Excel’s Developer tab to open Visual Basic if the shortcut differs.

Excel for the web does not run VBA macros or provide the desktop Visual Basic Editor, so this approach requires desktop Excel. A workbook containing macros may be opened in the browser, but its VBA code will not execute there. Mac and Windows users should also account for platform-specific code or controls in a larger project; a simple procedure that updates worksheet cells is more portable than code that relies on Windows-only APIs or components.

Frequently Asked Questions

Can a UserForm button call a macro in a standard module?
Yes. Put a public procedure in a standard module, then call its procedure name from the command button’s Click event in the UserForm code module.

Do I write the module name before the procedure name?
Usually not for a standard module. Call the public procedure directly, such as RefreshReport. The procedure name—not the standard module name—is what the button handler uses.

Why is my procedure not visible to the UserForm?
It may be declared Private, may be in a different kind of module, or its name may be misspelled. For a direct call from a UserForm to a standard module, make the target a Public Sub and check that it is in the same VBA project.

Can the button pass a value to the module?
Yes. Give the procedure one or more arguments, then pass values from controls in the event handler. Check that the values are present and have compatible types before calling it.

Can this VBA button work in Excel for the web?
No. Excel for the web does not execute VBA. Use desktop Excel to run a UserForm and its command button; web-based automation requires a different approach, such as Office Scripts where appropriate.

Practical takeaway

Keep the button’s Click event in the UserForm module, put reusable work in a standard module, and make the called procedure public. Match the event name to the button’s (Name), pass any required values explicitly, and test the workbook with a saved backup. With those pieces in place, a UserForm button can act as a clear front end for procedures elsewhere in the VBA project.

Related

Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.

More in VBA & macros

Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources

Spotted an error in this guide? Let us know.