Please Note: This article is written for users of the following Microsoft Excel versions: 2007, 2010, 2013, 2016, 2019, Excel in Microsoft 365, and 2021. If you are using an earlier version (Excel 2003 or earlier), this tip may not work for you. For a version of this tip written specifically for earlier versions of Excel, click here: Finding Workbooks Containing Macros.

Finding Workbooks Containing Macros

Written by Allen Wyatt (last updated May 20, 2023)
This tip applies to Excel 2007, 2010, 2013, 2016, 2019, Excel in Microsoft 365, and 2021


5

Richard's company, like many others, uses Excel quite a bit. In fact, they have thousands and thousands of Excel workbooks that they have collected over the years. Richard needs a way to find out which of those workbooks have VBA macros in them, without the need to open and inspect each workbook individually. He wonders if there is an easy way to do this.

One rather simplistic way to find all your workbooks containing macros is to just look for any files that use the XLSM or XLSB extensions. Workbooks that contain macros must be stored in files using these extensions. While not 100% foolproof, it is a good place to start.

You could also use the search capabilities of Windows (outside of Excel) and search for any file that contains the text "End Sub" or "End Function". That will quickly identify any potential candidate workbooks, as any VBA procedure must use one of these two statements at its end. (It won't work with XLSB files, however, as the macro code in those is stored in a binary format.)

If you are using legacy workbooks (those developed using Excel 2003's file format), then you actually need to look inside each of the workbooks. This can be done programmatically, meaning that you could have a macro that opens each workbook in a folder and examines it to see if there are any macros within it.

As an example, you could create a macro that steps through each of the files in a directory and determines if the file is an Excel workbook. It can then open the file and check to see if it has a VBA project within it.

Sub FindMacros()
    Dim sPath As String
    Dim sFile As String
    Dim sFoundFiles As String

    'specify directory to use - must end in "\"
    sPath = "C:\MyData\Excel Data\"

    sFile = Dir(sPath)
    Do While sFile <> ""
        If InStr(sFile, ".xls") > 0 Then
            Workbooks.Open (sPath & sFile)
            If Workbooks(sFile).HasVBProject Then
                sFoundFiles = sFoundFiles & sFile & vbCrLf
            End If
            Workbooks(sFile).Close (False)
        End If
        sFile = Dir     ' Get next filename
    Loop
    If Len(sFoundFiles) = 0 Then
        MsgBox "No workbooks found that contain macros"
    Else
        sFoundFiles = "The following workbooks contain macros:" & _
          vbCrLf & vbCrLf & sFoundFiles
        MsgBox sFoundFiles
    End If
End Sub

This example uses the HasVBProject property (introduced to the Excel object model in Excel 2007) to determine whether the file has any macros or not. When complete, the macro displays a message box that lists those worksheets containing macros.

Note:

If you would like to know how to use the macros described on this page (or on any other page on the ExcelTips sites), I've prepared a special page that includes helpful information. Click here to open that special page in a new browser tab.

ExcelTips is your source for cost-effective Microsoft Excel training. This tip (12466) applies to Microsoft Excel 2007, 2010, 2013, 2016, 2019, Excel in Microsoft 365, and 2021. You can find a version of this tip for the older menu interface of Excel here: Finding Workbooks Containing Macros.

Author Bio

Allen Wyatt

With more than 50 non-fiction books and numerous magazine articles to his credit, Allen Wyatt is an internationally recognized author. He is president of Sharon Parq Associates, a computer and publishing services company. ...

MORE FROM ALLEN

Shading Rows with Conditional Formatting

If you need to shade alternating rows in a data table, you'll want to examine how you can accomplish the task with ...

Discover More

Hiding and Unhiding Columns

Want to hide a column so it doesn't appear in the worksheet? It's easy to do using the formatting capabilities of Excel.

Discover More

Deleting Stubborn Links

Deleting unwanted links in a workbook can be a challenge, particularly if you are not sure how those links got there. ...

Discover More

Comprehensive VBA Guide Visual Basic for Applications (VBA) is the language used for writing macros in all Office programs. This complete guide shows both professionals and novices how to master VBA in order to customize the entire Office suite for their needs. Check out Mastering VBA for Office 2010 today!

More ExcelTips (ribbon)

Enforcing Moving Cells Up

When you design your worksheets, you probably want users to interact with those worksheets in specific ways. What ...

Discover More

Digital Signatures for Macros

The security features built into Excel allow you to digitally sign your macros so that users can rest assured that they ...

Discover More

Recording a Macro

One of the most common ways of creating macros is to use Excel's macro recorder. This tip shows how easy it is to use the ...

Discover More
Subscribe

FREE SERVICE: Get tips like this every week in ExcelTips, a free productivity newsletter. Enter your address and click "Subscribe."

View most recent newsletter.

Comments

If you would like to add an image to your comment (not an avatar, but an image to help in making the point of your comment), include the characters [{fig}] (all 7 characters, in the sequence shown) in your comment text. You’ll be prompted to upload your image when you submit the comment. Maximum image size is 6Mpixels. Images larger than 600px wide or 1000px tall will be reduced. Up to three images may be included in a comment. All images are subject to review. Commenting privileges may be curtailed if inappropriate images are posted.

What is three less than 9?

2023-05-30 04:22:35

sandeep kothari

THANKS J. Woolley.


2023-05-29 10:36:58

J. Woolley

@sandeep kothari
Thank you for your comment. Please replace the following statements
                Workbooks.Open (sPath & sFile), _
                    UpdateLinks:=False, ReadOnly:=True
                bIsVB = ActiveWorkbook.HasVBProject
                ActiveWorkbook.Close SaveChanges:=False
with these statements
                On Error Resume Next
                    bIsVB = Workbooks(sFile).HasVBProject
                    If Err <> 0 Then
                        Err.Clear
                        Workbooks.Open (sPath & sFile), _
                            UpdateLinks:=False, ReadOnly:=True
                        If Err = 0 Then
                            bIsVB = ActiveWorkbook.HasVBProject
                            ActiveWorkbook.Close SaveChanges:=False
                        End If
                    End If
                On Error GoTo 0
This avoids an error if sFile is already open or if it fails to open.


2023-05-28 21:21:30

sandeep kothari

Hi Woolley
Tried your macro on an open excel file (.xlsx) but didn't work. got error message, asking me to debug following codeline:
"Workbooks.Open (sPath & sFile), UpdateLinks:=False, ReadOnly:=True".
Pl chk what seems to have gone wrong.


2023-05-27 11:36:46

J. Woolley

Re. my previous comment, the Tip's macro overlooks file types .XLS, .XLSM, and .XLSB unless
    If InStr(sFile, ".xls") > 0 Then
is changed to
    If InStr(sFile, ".xls", vbTextCompare) > 0 Then
or the module includes Option Compare Text; the default is Binary, which is case sensitive.


2023-05-23 17:19:13

J. Woolley

This Tip's macro has several issues:
+ Tries to open files like Book1.xls.whatever
+ Possibly tries to open and close itself or Personal.xlsb
+ Overlooks these Excel file types: .xlt, .xltm, .xla, .xlam, .XLS, .XLS*
+ Permits annoying screen updates
+ Ignores possible workbook recalc, auto macro, or external link problems
+ Ignores MsgBox limits (about 25 lines or 1,024 characters)
Here is an improved version (which assumes Personal.xlsb, *.xla, and *.xlam always include VBA):

Sub FindMacros2()
    Const MyName As String = "FindMacros2"
    Const Header As String = " files with VBA in active workbook's folder:"
    Const MaxNbr As Integer = 25, MaxLen As Integer = 800
    Dim oldCM As Variant, oldAS As Variant, bIsVB As Boolean, bNext As Boolean
    Dim sThis As String, sPath As String, sFile As String
    Dim sLow As String, sExt As String, sMsg As String
    Dim sList As String, sPart As String, nList As Integer, nPart As Integer
    sThis = ThisWorkbook.Name
    With Application
        .ScreenUpdating = False
        oldCM = .Calculation
        .Calculation = xlCalculationManual
        oldAS = .AutomationSecurity
        .AutomationSecurity = msoAutomationSecurityForceDisable
        .EnableEvents = False
        sPath = ActiveWorkbook.Path & .PathSeparator
    End With
    ChDir sPath
    sFile = Dir("*.xl*")
    Do While sFile <> ""
        sLow = LCase(sFile)
        sExt = Mid(sLow, InStrRev(sLow, ".xl"))
        If Len(sExt) < 6 Then
            bIsVB = (sFile = sThis) Or (sLow = "personal.xlsb") _
                Or (sExt = ".xla") Or (sExt = ".xlam")
            If Not bIsVB Then
                Workbooks.Open (sPath & sFile), _
                    UpdateLinks:=False, ReadOnly:=True
                bIsVB = ActiveWorkbook.HasVBProject
                ActiveWorkbook.Close SaveChanges:=False
            End If
            If bIsVB Then
                nList = nList + 1
                sList = sList & vbLf & sFile 'complete list
                nPart = nPart + 1
                sPart = sPart & vbLf & sFile 'partial list
            End If
            If nPart = MaxNbr Or Len(sPart) > MaxLen Then
                sMsg = IIf(bNext, "Next ", "First ") & nPart & Header & sPart
                If MsgBox(sMsg, vbOKCancel, MyName) = vbCancel Then Exit Sub
                bNext = True
                nPart = 0
                sPart = ""
            End If
        End If
        sFile = Dir
    Loop
    With Application
        .EnableEvents = True
        .AutomationSecurity = oldAS
        .Calculation = oldCM
        .ScreenUpdating = True
    End With
    If nPart = 0 And (Not bNext) Then
        MsgBox "No files with VBA in active workbook's folder", , MyName
    ElseIf nPart > 0 Then
        MsgBox (IIf(bNext, "Last ", "") & nPart & Header & sPart), , MyName
    End If
    'consider copying complete sList to worksheet, document, or clipboard
End Sub


This Site

Got a version of Excel that uses the ribbon interface (Excel 2007 or later)? This site is for you! If you use an earlier version of Excel, visit our ExcelTips site focusing on the menu interface.

Newest Tips
Subscribe

FREE SERVICE: Get tips like this every week in ExcelTips, a free productivity newsletter. Enter your address and click "Subscribe."

(Your e-mail address is not shared with anyone, ever.)

View the most recent newsletter.