Overview

Excel VBA Development

When working with multiple workbooks or inherited codebases, getting a quick inventory of all VBA procedures is invaluable. This macro scans every open workbook and lists every Sub, Function, and Property procedure with its component, type, scope, and name.

The companion function fn_Get_VBA_Code goes further, letting you retrieve the full source code of any procedure as a string directly from a worksheet formula, making VBA code itself queryable from the spreadsheet.

How It Works

The VBA Code

Public Sub List_VBA_With_Code()
    Dim Wks_Out As Worksheet
    On Error Resume Next
    Set Wks_Out = ActiveWorkbook.Worksheets("VBA_Code_List_014")
    On Error GoTo 0
    
    If Wks_Out Is Nothing Then
        Set Wks_Out = ActiveWorkbook.Worksheets.Add( _
            After:=ActiveWorkbook.Sheets(ActiveWorkbook.Sheets.Count))
        Wks_Out.Name = "VBA_Code_List_014"
    Else
        Wks_Out.Cells.Clear
    End If
    
    Dim Cnt_Row As Long: Cnt_Row = 1
    Wks_Out.Cells(Cnt_Row, 1).Resize(1, 6).Value = _
        Array("Workbook", "Component", "CompType", "ProcType", "Scope", "ProcName")
    Cnt_Row = 2
    
    Dim Wkb_Loop As Workbook
    For Each Wkb_Loop In Application.Workbooks
        Dim Vbp_Proj As Object
        On Error Resume Next
        Set Vbp_Proj = Wkb_Loop.VBProject
        If Err.Number <> 0 Then Err.Clear: GoTo NextWkb
        On Error GoTo 0
        
        Dim Vbc_Cmp As Object
        For Each Vbc_Cmp In Vbp_Proj.VBComponents
            Dim Cmo_Mod As Object: Set Cmo_Mod = Vbc_Cmp.CodeModule
            Dim Num_Lin As Long
            
            For Num_Lin = Cmo_Mod.CountOfDeclarationLines + 1 To Cmo_Mod.CountOfLines
                Dim Enm_Knd As Long
                Dim Str_Nam As String: Str_Nam = Cmo_Mod.ProcOfLine(Num_Lin, Enm_Knd)
                If Len(Str_Nam) = 0 Then GoTo NextLine
                
                Dim Num_Sta As Long: Num_Sta = Cmo_Mod.ProcStartLine(Str_Nam, Enm_Knd)
                If Num_Lin <> Num_Sta Then GoTo NextLine
                
                Wks_Out.Cells(Cnt_Row, 1).Value = Wkb_Loop.Name
                Wks_Out.Cells(Cnt_Row, 2).Value = Vbc_Cmp.Name
                Wks_Out.Cells(Cnt_Row, 3).Value = Vbc_Cmp.Type
                Wks_Out.Cells(Cnt_Row, 4).Value = "Sub/Function"
                Wks_Out.Cells(Cnt_Row, 6).Value = Str_Nam
                Cnt_Row = Cnt_Row + 1
NextLine:
            Next Num_Lin
        Next Vbc_Cmp
NextWkb:
    Next Wkb_Loop
    
    Wks_Out.Columns("A:F").AutoFit
End Sub

Public Function fn_Get_VBA_Code(ByVal Component_Name As String, _
        ByVal Procedure_Name As String) As String
    ' Returns the full source text of a procedure from a VBComponent
    Dim Vbc_Cmp As Object
    On Error Resume Next
    Set Vbc_Cmp = ActiveWorkbook.VBProject.VBComponents(Component_Name)
    On Error GoTo 0
    If Vbc_Cmp Is Nothing Then Exit Function
    
    Dim Cmo_Mod As Object: Set Cmo_Mod = Vbc_Cmp.CodeModule
    Dim Num_Sta As Long, Num_Cnt As Long
    
    On Error Resume Next
    Num_Sta = Cmo_Mod.ProcStartLine(Procedure_Name, 0)
    Num_Cnt = Cmo_Mod.ProcCountLines(Procedure_Name, 0)
    If Err.Number = 0 And Num_Sta > 0 Then
        fn_Get_VBA_Code = Cmo_Mod.Lines(Num_Sta, Num_Cnt)
    End If
    On Error GoTo 0
End Function

Final Thoughts

This inspector turns your VBA codebase into a searchable inventory. Combined with fn_Get_VBA_Code, you can build a self-documenting workbook where the code and its documentation live side by side.