VBA for getting a list of all formulas not in a table, and only the first row of a table

trishcollins

Board Regular
Joined
Jan 7, 2006
Messages
71
Okay, so I have working on VBA code to extract ALL formulas from a single cell if not in a table, and only the first row of formulas in any table (since all the remaining rows are the same formula). Initially, I had code working to extract ALL formulas, then modified it as follows. Given that I found this code on the Internet, and modified for my needs, I am somehow doing something wrong. The first thing, it is not creating the "Formula List
worksheet. The second thing is stops at the first instance of "dic.Add ws.Name & "!" & Cell.Address(0, 0), "'" & Cell.Formula", when following the correct IF THEN ELSE path, for a cell that is not in a table. Any ideas what I am doing wrong?

VBA Code:
Sub ListFormulas()
Dim ws As Worksheet
Dim FormulaCells As Range: Dim Cell As Range
Dim FormulaSheet As Worksheet
Dim lRow As Long
Dim dic As Object
Dim vFormulas As Variant: Dim vFormulas1 As Variant
Dim EquivRange As Range, r As Range
Dim lo As ListObject
Dim nFirstRow As Long, nLastRow As Long
Dim TableName As ListObject

Application.ScreenUpdating = False
lRow = 2
Set dic = CreateObject("Scripting.Dictionary")
Set dic1 = CreateObject("Scripting.Dictionary")
MsgBox ("Worksheet Created")
For Each ws In ActiveWorkbook.Worksheets
    If ws.Name <> "Formula list" And ws.Name <> "Formulas" And ws.Name <> "Data Validation List" Then 'don't include these worksheets
        ' Create a Range object for all formula cells
        On Error Resume Next
        Set FormulaCells = ws.UsedRange.SpecialCells(xlFormulas)
        On Error GoTo 0
        ' Exit if no formulas are found
        If Not FormulaCells Is Nothing Then 'Check to see if there is a formula in the cell
            If ActiveCell.ListObject Is Nothing Then  'Check to see if this cell is in a table and if not, get the formula
                Set FormulaCells = ws.UsedRange.SpecialCells(xlFormulas)
                    dic.Add ws.Name & "!" & Cell.Address(0, 0), "'" & Cell.Formula
                    dic1.Add ws.Name & "!" & Cell.Address(0, 0), Cell.Value
            Else
                Set TableName = ActiveCell.ListObjects.Name 'Get the name of the table of the current cell
                Set EquivRange = ws.ListObjects(TableName).DataBodyRange.Rows(
 

Excel Facts

Which Excel functions can ignore hidden rows?
The SUBTOTAL and AGGREGATE functions ignore hidden rows. AGGREGATE can also exclude error cells and more.
The second thing is stops at the first instance of "dic.Add ws.Name & "!" & Cell.Address(0, 0), "'" & Cell.Formula"
I assume you mean the code stops with an error message? Because your code hasn't set a value for Cell.

The first thing, it is not creating the "Formula List
Your code is referring to ActiveCell, which is static. You'll need to loop through FormulaCells, along these lines:

VBA Code:
If Not FormulaCells Is Nothing Then
    For Each r In FormulaCells
        If r.ListObject Is Nothing Then
            dic.Add ws.Name & "!" & r.Address(0, 0), "'" & r.Formula
            dic1.Add ws.Name & "!" & r.Address(0, 0), r.Value
        Else
            ......
 
Upvote 0
I assume you mean the code stops with an error message? Because your code hasn't set a value for Cell.


Your code is referring to ActiveCell, which is static. You'll need to loop through FormulaCells, along these lines:

VBA Code:
If Not FormulaCells Is Nothing Then
    For Each r In FormulaCells
        If r.ListObject Is Nothing Then
            dic.Add ws.Name & "!" & r.Address(0, 0), "'" & r.Formula
            dic1.Add ws.Name & "!" & r.Address(0, 0), r.Value
        Else
            ......
What is "r" defined as?
 
Upvote 0
Stephen is in Australia and unlikley to be online this late.
Dim r as Range
specifically a cell in FormulaCells as you loop through all the cells that make up FormulaCells.
Just saw your latest post and it sounds like you just worked that out.
 
Upvote 0
Okay, now I am stuck on this code. If the range is part of a named table, I want the range to be changed to just the first row and only report on cells with formulas. If is picking up the table name no problem. The TableRange (dim as Range), which is supposed to set the new range to just the first row of a table, is not picking up anything, and it's then failing. Any suggestions?

VBA Code:
            If Not ws.UsedRange.ListObject Is Nothing Then
                TableName = ws.UsedRange.ListObject.Name
[I][B]                Set TableRange = ws.ListObjects(TableName).DataBodyRange.Rows(1)[/B][/I]
[B][I]                Set FormulaCells = TableRange.SpecialCells(xlFormulas)[/I][/B]
                For Each r In Range(FormulaCells)
                    dic.Add ws.Name & "!" & r.Address(0, 0), "'" & r.Formula
                    dic1.Add ws.Name & "!" & r.Address(0, 0), r.Value
                Next r
            End If

Trish ;)
 
Upvote 0
Try:

VBA Code:
For Each ws In ActiveWorkbook.Worksheets
    If ws.Name <> "Formula list" And ws.Name <> "Formulas" And ws.Name <> "Data Validation List" Then 'don't include these worksheets
        
        ' Create a Range object for all formula cells
        On Error Resume Next
        Set FormulaCells = ws.UsedRange.SpecialCells(xlFormulas)
        On Error GoTo 0
        
        ' Exit if no formulas are found
        If Not FormulaCells Is Nothing Then 'Check to see if there is a formula in the cell
             For Each r In FormulaCells
                If r.ListObject Is Nothing Then
                    dic.Add ws.Name & "!" & r.Address(0, 0), "'" & r.Formula
                    dic1.Add ws.Name & "!" & r.Address(0, 0), r.Value
                Else
                    If r.Row = r.ListObject.DataBodyRange.Row Then
                        dic.Add ws.Name & "!" & r.Address(0, 0), "'" & r.Formula
                        dic1.Add ws.Name & "!" & r.Address(0, 0), r.Value
                    End If
                End If
            Next r
        End If
    End If
Next ws
 
Upvote 0
Solution
For Each ws In ActiveWorkbook.Worksheets If ws.Name <> "Formula list" And ws.Name <> "Formulas" And ws.Name <> "Data Validation List" Then 'don't include these worksheets ' Create a Range object for all formula cells On Error Resume Next Set FormulaCells = ws.UsedRange.SpecialCells(xlFormulas) On Error GoTo 0 ' Exit if no formulas are found If Not FormulaCells Is Nothing Then 'Check to see if there is a formula in the cell For Each r In FormulaCells If r.ListObject Is Nothing Then dic.Add ws.Name & "!" & r.Address(0, 0), "'" & r.Formula dic1.Add ws.Name & "!" & r.Address(0, 0), r.Value Else If r.Row = r.ListObject.DataBodyRange.Row Then dic.Add ws.Name & "!" & r.Address(0, 0), "'" & r.Formula dic1.Add ws.Name & "!" & r.Address(0, 0), r.Value End If End If Next r End If End If Next ws
That worked like a charm. Thanks.
Question, the "If r.Row = r.ListObject.DataBodyRange.Row", is what I am assuming it figures out what row it is in. But I am not sure how it knows it in the first row of the DataBodyRange. Can you explain, so I understand?

Cheers, Trish ;)
 
Upvote 0
Also, I have a couple of info tables, where there are formulas, but they are not repeated. Its it possible to also check to see if the second row is different, and if so, add all the formulas from the specific table as well. I can actually name the tables in the "If statement" as well, but it would be cleaner not to have to list the specific tables.

I have tried this specific code, but I get an error, so not sure what I am doing wrong.

If r.ListObject Is Nothing Or r.ListObject.Name = "Menu" Or r.ListObject.Name = "How_It_Works" Then

Trish ;)
 
Upvote 0
Fixed. I did this instead:

VBA Code:
Sub ListUniqueFormulas()
Dim ws As Worksheet
Dim FormulaCells As Range: Dim Cell As Range
Dim FormulaSheet As Worksheet
Dim lRow As Long
Dim dic As Object
Dim vFormulas As Variant: Dim vFormulas1 As Variant
Dim r As Range
Dim TblName As String

Application.ScreenUpdating = False
lRow = 2
Set dic = CreateObject("Scripting.Dictionary")
Set dic1 = CreateObject("Scripting.Dictionary")
'MsgBox ("Worksheet Created")
For Each ws In ActiveWorkbook.Worksheets
    If ws.Name <> "Formula list" And ws.Name <> "Formulas" And ws.Name <> "Data Validation List" Then 'don't include these worksheets
        
        ' Create a Range object for all formula cells
        On Error Resume Next
        Set FormulaCells = ws.UsedRange.SpecialCells(xlFormulas)
        On Error GoTo 0
        
        ' Exit if no formulas are found
        If Not FormulaCells Is Nothing Then 'Check to see if there is a formula in the cell
             For Each r In FormulaCells
                If r.ListObject Is Nothing Then
                    dic.Add ws.Name & "!" & r.Address(0, 0), "'" & r.Formula
                    dic1.Add ws.Name & "!" & r.Address(0, 0), r.Value
                Else
                                    TblName = r.ListObject.Name
                    If TblName = "Menu" Or TblName = "How_It_Works" Or TblName = "Matrix_Totals" Then
                            dic.Add ws.Name & "!" & Cell.Address(0, 0), Cell.Validation.Formula
                            dic1.Add ws.Name & "!" & Cell.Address(0, 0), Cell.Value
                    Else

  &nbsp
 
Upvote 0

Forum statistics

Threads
1,220,965
Messages
6,157,119
Members
451,398
Latest member
rjsteward

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top