Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding all cells that have been filled with any color and highlighting corresponding column headers in excel vba

My problem:

I've made a large (2,000 line) macro that runs on our company's template and fixes some common issues and highlights other issues we have prior to importing. The template file always has 150 columns and is in most instances 15,000+ rows (sometimes even over 30,000). The macro works well, highlighting all the cells that contain errors according to our data rules, but with a file with so many columns and rows I thought it'd be convenient to add a snippet to my macro that would have it find all of the cells that have been highlighted and then highlight the column headers of the columns that contain those highlighted cells.

Methods I've found while searching for a solution:

  • SpecialCellsxlCellTypeAllFormatConditions only works for conditional formatting, so that isn't a plausible method for my situation

  • Rick Rothstein's UDF from here

    Sub FindYellowCells()
      Dim YellowCell As Range, FirstAddress As String
      Const IndicatorColumn As String = "AK"
      Columns(IndicatorColumn).ClearContents
      '   The next code line sets the search for Yellow color... the next line after it (commented out) searches
      '   for the ColorIndex 6 (which is usually yellow), so use whichever code line is applicable to your situation
      Application.FindFormat.Interior.Color = vbYellow
      'Application.FindFormat.Interior.ColorIndex = 6
      Set YellowCell = Cells.Find("*", After:=Cells(Rows.Count, Columns.Count), SearchFormat:=True)
      If Not YellowCell Is Nothing Then
        FirstAddress = YellowCell.Address
        Do
          Cells(YellowCell.Row, IndicatorColumn).Value = "X"
          Set YellowCell = Cells.Find("*", After:=YellowCell, SearchFormat:=True)
          If YellowCell Is Nothing Then Exit Do
        Loop While FirstAddress <> YellowCell.Address
      End If
    End Sub
    

    This would be perfect with a few tweaks, except our files can have multiple colorfills. Since our template is so large I've learned that it takes quite some time to run one instance of Find to find just one colorfill in the UsedRange.

  • Using filtering, maybe cycling through all the columns and checking each if they contain any cell that has any colorfill. Would that be any faster though?

So, my question:

  1. How could I accomplish finding all columns that contain any colorfilled cells? More specifically, what would be the most efficient (fastest) way to achieve this?
like image 600
CaffeinatedMike Avatar asked Dec 06 '25 10:12

CaffeinatedMike


1 Answers

The most performant solution would be to search using recursion by half-interval. It takes less than 5 seconds to tag the columns from a worksheet with 150 columns and 30000 rows.

The code to search for a specific color:

Sub TagColumns()
  Dim headers As Range, body As Range, col As Long, found As Boolean

  ' define the columns for the headers and body
  Set headers = ActiveSheet.UsedRange.Rows(1).Columns
  Set body = ActiveSheet.UsedRange.Offset(1).Columns

  ' iterate each column
  For col = 1 To headers.Count

    ' search for the yellow color in the column of the body
    found = HasColor(body(col), vbYellow)

    ' set the header to red if found, green otherwise
    headers(col).Interior.color = IIf(found, vbRed, vbGreen)
  Next

End Sub

Public Function HasColor(rg As Range, color As Long) As Boolean
  If rg.DisplayFormat.Interior.color = color Then
    HasColor = True
  ElseIf VBA.IsNull(rg.DisplayFormat.Interior.colorIndex) Then
    ' The color index is null so there is more than one color in the range
    Dim midrow&
    midrow = rg.Rows.Count \ 2
    If HasColor(rg.Resize(midrow), color) Then
      HasColor = True
    ElseIf HasColor(rg.Resize(rg.Rows.Count - midrow).Offset(midrow), color) Then
      HasColor = True
    End If
  End If
End Function

And to search for any color:

Sub TagColumns()
  Dim headers As Range, body As Range, col As Long, found As Boolean

  ' define the columns for the headers and body
  Set headers = ActiveSheet.UsedRange.Rows(1).Columns
  Set body = ActiveSheet.UsedRange.Offset(1).Columns

  ' iterate each column
  For col = 1 To headers.Count

    ' search for any color in the column of the body
    found = VBA.IsNull(body(col).DisplayFormat.Interior.ColorIndex)

    ' set the header to red if found, green otherwise
    headers(col).Interior.color = IIf(found, vbRed, vbGreen)
  Next

End Sub
like image 126
Florent B. Avatar answered Dec 07 '25 23:12

Florent B.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!