Fixing “Cannot run the macro… The macro may not be available in this workbook.”

The error alert “Cannot run the macro ‘WorkbookName.xlsm!MacroName’. The macro may not be available in this workbook or all macros may be disabled” occurs when Excel cannot locate or execute the requested procedure. This typically points to a broken button assignment, disabled Trust Center macro settings, an incorrect file extension, or scoping conflicts inside the VBA project.

Quick Answer

Check your file format and macro name first. Save the workbook as an Excel Macro-Enabled Workbook (.xlsm or .xlsb). Then right-click the button or shape calling the code, choose Assign Macro, and reselect the specific procedure from the list to update any broken workbook-name prefixes.


The Core Causes of Macro Availability Errors

When you click an object, button, or shortcut to trigger a macro, Excel resolves the target using a specific hierarchy:
[WorkbookName.xlsm]!ModuleName.ProcedureName

If any element of that path changes—such as renaming the workbook, saving it as a standard .xlsx file, changing a module name, or moving the file across security zones—Excel cannot resolve the pointer and generates the dialog.


Step-by-Step Diagnostic and Resolution Process

                      "Cannot run the macro" Error
                                   │
                   Is the file saved as .xlsx?
                                  ╱ ╲
                            YES  ╱   ╲  NO
                                ╱     ╲
             VBA code was stripped     Check Trust Center Settings:
             at save. Restore from     Are macros blocked/disabled?
             backup as .xlsm/.xlsb.              ╱ ╲
                                           YES  ╱   ╲  NO
                                               ╱     ╲
                          Enable Trusted Location     Inspect Macro Assignment:
                          or unblock file properties  Does button point to an old
                                                      or renamed workbook?

Step 1: Confirm File Format and Code Preservation

Standard Excel workbooks (.xlsx) cannot store VBA code. If a macro-enabled workbook is accidentally saved as a .xlsx file, Excel permanently strips the VBA project.

  1. Inspect the file extension in the title bar or file explorer.
  2. If it is .xlsx, press Alt + F11 to open the VBA Editor. If the project contains no code modules, the macros were stripped when saving. You must restore the file from a backup and use Save As > Excel Macro-Enabled Workbook (*.xlsm).
  3. If the file is already a .xlsm or .xlsb, proceed to Step 2. If the file opens with corruption warnings, see Fixing “Excel found unreadable content” in .xlsm files.

Step 2: Clear Hardcoded Workbook References on Shapes and Buttons

When you assign a macro to a button in Budget_v1.xlsm, Excel frequently stores the reference as 'Budget_v1.xlsm'!RunCalculations. If you later use Save As to create Budget_v2.xlsm, the button inside the new file still points to Budget_v1.xlsm. When Budget_v1.xlsm is closed or moved, Excel displays the “macro may not be available” error.

  • The Fix:
    1. Right-click the button or shape and select Assign Macro.
    2. Review the Macro name field. If it contains a workbook prefix (such as 'OldWorkbook.xlsm'!MyMacro), delete the prefix or select the macro directly from the list below.
    3. Change the Macros in dropdown to This Workbook.
    4. Select your target subroutine and click OK.

Step 3: Check Procedure Scoping and Arguments

A macro cannot be assigned directly to an Excel UI control if it is private or requires input parameters:

  • Private Procedures: If the subroutine begins with Private Sub MyMacro(), Excel hides it from the worksheet interface. Change Private Sub to Public Sub (or simply Sub MyMacro()).
  • Argument Requirements: Subroutines that require parameters (for example, Sub CalculateData(RowCount As Long)) cannot be invoked directly from a button or shortcut. They must be wrapped in a parameterless procedure: ' Uncallable from button Sub CalculateData(RowCount As Long) ' ... logic ... End Sub ' Callable wrapper Sub RunCalculateData() CalculateData 500 End Sub
  • Location in Object Modules: Macros intended for standard worksheet buttons should live in standard modules (Insert > Module). If you place a procedure inside ThisWorkbook or a sheet module (Sheet1), Excel requires you to prefix the call with the object name (for example, Sheet1.MyMacro). Moving the code to a standard module resolves the issue.

What to Check If Scoping and Assignments Are Correct

If the assignment is valid and the file format is .xlsm, the issue usually stems from security policies or compile breaks:

Check 1: Macro Security and the Windows Mark of the Web

Files downloaded from the internet, email, or SharePoint are blocked by Windows by default.

Check 2: Naming Ambiguities and Collisions

If a standard module has the exact same name as a procedure inside it, Excel’s execution parser can fail to differentiate them.

Check 3: Project Compilation Failures

If the VBA project contains syntax errors or uncompiled references, Excel may fail silently when attempting to execute a call.

  1. Open the VBA Editor (Alt + F11).
  2. Go to the top menu and click Debug > Compile VBAProject.
  3. Fix any highlighted syntax errors or missing references. Enforcing variable checks with “Variable not defined”: Why you must use Option Explicit will prevent hidden runtime failures before they break macro availability.

If the macro initiates execution but immediately crashes with a generic failure dialog, your code is triggering Runtime Error 1004: Application-defined or Object-defined error (The Catch-all), which points to an invalid worksheet action rather than a missing macro.