Excel does not (yet) provide facilities for sorting or filtering a range of cells by the colour of the cells, or for counting the instances of a particular colour. It is not difficult, but it does require some hand-crafting.

The generally suggested method of solving this problem is to write a UDF that returns the ColorIndex of a nominated cell, and add a 'helper' range to return the ColorIndex values of the original range. This can be used for both counting and sorting.

This page contains a fully generic UDF to return the colorindex of an array of cells, either the cell's interior colour or its text colour, and shows hoe to deploy that UDF to achieve the above aims. It is structured in the following sections:

Counting Coloured Cells
Summing Coloured Cells
Sorting Coloured Cells
Filtering Coloured Cells
Colour Constants
Constraints
Code Sample(s)
References

If applying any of the techniques described here, it is necessary to copy all of the VBA code below to a standard code module in your workbook, so that the worksheet functions can utilise the Colorindex function.

Counting Coloured Cells

Counting coloured cells, either cell colour or font colour, is easily achieved with the function presented here. One of the major benefits of this routine is that it can utilise standard worksheet functions for summing the colours, without the need for a 'helper' column.

The function has been specifically designed to return an array of colorindex values that can be used in standard worksheet functions, such as SUM. In reality, it is best served by the SUMPRODUCT function to count the instances of a particular colour, using the following technique(s).

=SUMPRODUCT(--(ColorIndex(A1:A100)=3))
counts all red cells (background color) within the range A1:A100

or
=SUMPRODUCT(--(ColorIndex(A1:A100,TRUE)=3))
counts all cells with red text within the range A1:A100

To get the colorindex of a specific cell, simply use
=ColorIndex(A1)

As well as counting all cells with a particular colorindex value, it is possible to use the colour of a cell as the comparison, like this
=SUMPRODUCT(--(ColorIndex(A1:A100)=ColorIndex(A1)))

Summing Coloured Cells

As well as counting the number of cells that meet a particular criteria, there may be a requirement to sum by colour. This could be summing the values of the range of coloured cells, or a range associated with the range of coloured cells.

This is simply achieved by extending the SUMPRODUCT function to include the range of cells to be summed. As an example, assuming that the values are also in A1:A100, the following formula will sum all of the cells in that range that are red
=SUMPRODUCT(--(ColorIndex(A1:A100)=3),A1:A100)

Similarly, to sum the cells with red text, use
=SUMPRODUCT(--(ColorIndex(A1:A100,TRUE)=3),A1:A100)

To sum a separate range based upon coloured cells in A1:A100, use
=SUMPRODUCT(--(ColorIndex(A1:A100)=3),B1:B100)

And to use the colour of a cell as the comparison, like this
=SUMPRODUCT(--(ColorIndex(A1:A100)=ColorIndex(A1)),B1:B100)

Sorting Coloured Cells

In addition, the function can be used to sort a range by its colour. Simply add a 'helper' range next to the original range of coloured cells, and use the ColorIndex function to determine the original cell colour. So, if the cells to be sorted are in A2:A100, add this formula to B2
=ColorIndex(A2)

and copy this formula down to B100. Column B will then contain the set of colorindex values, and the sort is effected on the combined range (and any other appropriate columns/rows), using the newly added 'helper' range as the key range.

If column B already contains key data, then you can use any free column, or insert a new column in front of column B, it can be deleted after the sort.

Custom orders can be managed, but these would have to be defined using the appropriate colorindex, there are no implicit colour names, such as Red or Blue, that can be used.

Filtering Coloured Cells

Filtering coloured cells is very similar to sorting coloured cells. Again, if the cells to be sorted are in A2:A100, add this formula to B2
=ColorIndex(A2)

and copy this formula down to B100. Column B will then contain the set of colorindex values, and the the filter is applied to the helper column.

If column B already contains key data, then you can use any free column, or insert a new column in front of column B, it can be deleted after the sort.

Constraints

There are s couple of major shortcomings with the techniques described here.

The first shortcoming is that change a cell's colour or the text colour does not trigger the Excel calculate event. This is not a shortcoming of the UDF, but of Excel's calculation event, but what this means that any formula that uses the Colorindex UDF to calculate a cell's colour will not update should that cell's colour change. Thus, if a number of cells are being summed, the SUMPRODUCT formula will give the result, but as soon as one or more cells change colour, then the result is incorrect. To overcome this, you need to force a sheet calculate. What I do in applications that use this technique is to create a button(s) to set the colour(s), and within the code attached to the button(s), I do a manual sheet calculate.

The second shortcoming is that this technique at present does not cater for cells that are coloured due to conditional formatting.

Colour Constants

Another 'shortcoming' within Excel is a lack of pre-defined colour constants. If these were available, it would be possible to use a more descriptive formula such as
=IF(ColorIndex(A1)=ciRed,"Warning!","")

One way to achieve this would be to use workbook names, creating names for the colours with a value of the colorindex. For instance, goto Insert>Name>Define...., add the name of ciRed, and a RefersTo value of 3. ciRed will then be available to your formulae.

Code Sample(s)



'---------------------------------------------------------------------
' ColorIndex Function
'---------------------------------------------------------------------
' Function:    Returns the colorindex of the supplied range
' Synopsis:    Initially, gets a colorindex value for black and white
'              from the activeworkbook colour palette
'              Then works through each cell in  the supplied range and
'              determines the colorindex, and adds to array
'              Finishes by returning acumulated array
' Variations:  Determines cell colour (interior) or text colour (font)
'              Default is cell colour
' Constraints: Does not count colours set by conditional formatting
'---------------------------------------------------------------------
' Author:      Bob Phillips
'              Additions for ranges suggested by Harlan Grove
'---------------------------------------------------------------------


'---------------------------------------------------------------------
Function ColorIndex(rng As Range, _
                    Optional text As Boolean = False) As Variant
'---------------------------------------------------------------------
Dim cell As Range, row As Range
Dim i As Long, j As Long
Dim iWhite As Long, iBlack As Long
Dim aryColours As Variant

    If rng.Areas.Count > 1 Then
        ColorIndex = CVErr(xlErrValue)
        Exit Function
    End If

    iWhite = WhiteColorindex(rng.Worksheet.Parent)
    iBlack = BlackColorindex(rng.Worksheet.Parent)

    If rng.Cells.Count = 1 Then
        If text Then
            aryColours = DecodeColorIndex(rng, True, iBlack)
        Else
            aryColours = DecodeColorIndex(rng, False, iWhite)
        End If

    Else
        aryColours = rng.Value
        i = 0

        For Each row In rng.Rows
            i = i + 1
            j = 0

            For Each cell In row.Cells
                j = j + 1

                If text Then
                    aryColours(i, j) = _
                      DecodeColorIndex(cell,True,iBlack)
                Else
                    aryColours(i, j) = _
                      DecodeColorIndex(cell,False,iWhite)
                End If

            Next cell

        Next row

    End If

    ColorIndex = aryColours

End Function

'---------------------------------------------------------------------
Private Function WhiteColorindex(oWB As Workbook)
'---------------------------------------------------------------------
Dim iPalette As Long
    WhiteColorindex = 0
    For iPalette = 1 To 56
        If oWB.Colors(iPalette) = &HFFFFFF Then
            WhiteColorindex = iPalette
            Exit Function
        End If
    Next iPalette
End Function

'---------------------------------------------------------------------
Private Function BlackColorindex(oWB As Workbook)
'---------------------------------------------------------------------
Dim iPalette As Long
    BlackColorindex = 0
    For iPalette = 1 To 56
        If oWB.Colors(iPalette) = &H0 Then
            BlackColorindex = iPalette
            Exit Function
        End If
    Next iPalette
End Function

'---------------------------------------------------------------------
Private Function DecodeColorIndex(rng As Range, _
                                  text As Boolean, _
                                  idx As Long)
'---------------------------------------------------------------------
Dim iColor As Long
    If text Then
        iColor = rng.font.ColorIndex
    Else
        iColor = rng.Interior.ColorIndex
    End If
    If iColor < 0 Then
        iColor = idx
    End If
    DecodeColorIndex = iColor
End Function

'---------------------------------------------------------------------
' End of ColorIndex Function
'---------------------------------------------------------------------
				


References

The technique described above is best used in conjunction with the SUMPRODUCT function. Details of how this function works, specifically in the way described here, can be found on the page.

Sorting by colour - Special Sort Add-In