parry
MrExcel MVP
- Joined
- Aug 20, 2002
- Messages
- 3,355
Hi all, Im just wanting some feedback on an approach to a solution. Many people ask about doing calculations on cells based upon cell format. You can use the old Excel4 macro functions but I wanted to develop my own UDF.
What I have come up with is a function to return a range based upon a desired format. By returning a range you can then use this with any other function such as Sum, Average etc.
The following function called FormatRng has 3 arguments...
Argument 1 = Range to look at
Argument 2 = A single cell to compare against the first argument
Argument 3 = A number representing the type of comparison required. The numbers are:
0 = Compare Interior Colour
1 = Compare Bold Font
2 = Compare Italics
3 = Compare Font Size
4 = Compare Font Colour
5 = Compare Font Name (Arial, Times New Roman etc)
6 = Compare Underline
Example:
I want sum the cells that are bold. The target range is A1:A10 and I have a criteria cell of B1. First you bold cell B1 then enter the following formula into a cell.
=SUM(formatrng(A1:A10,B1,1))
If there are no cells that match cell B1 for a bold font then a #Value error is returned. If you wish to do the opposite of this (ie Sum cells that arent bold, you use the same formula but remove the bold from cell B1. So I am effectively using the comparison cell as a true/false except in the case of colours where it returns cells that match the colour (including no colour).
Does any one have thoughts on this approach and if it can be done a better way? Ideally you wouldnt need the 3rd argument but that would mean checking many criteria and would probably slow things down to an unacceptable level.
What I have come up with is a function to return a range based upon a desired format. By returning a range you can then use this with any other function such as Sum, Average etc.
The following function called FormatRng has 3 arguments...
Argument 1 = Range to look at
Argument 2 = A single cell to compare against the first argument
Argument 3 = A number representing the type of comparison required. The numbers are:
0 = Compare Interior Colour
1 = Compare Bold Font
2 = Compare Italics
3 = Compare Font Size
4 = Compare Font Colour
5 = Compare Font Name (Arial, Times New Roman etc)
6 = Compare Underline
Example:
I want sum the cells that are bold. The target range is A1:A10 and I have a criteria cell of B1. First you bold cell B1 then enter the following formula into a cell.
=SUM(formatrng(A1:A10,B1,1))
If there are no cells that match cell B1 for a bold font then a #Value error is returned. If you wish to do the opposite of this (ie Sum cells that arent bold, you use the same formula but remove the bold from cell B1. So I am effectively using the comparison cell as a true/false except in the case of colours where it returns cells that match the colour (including no colour).
Does any one have thoughts on this approach and if it can be done a better way? Ideally you wouldnt need the 3rd argument but that would mean checking many criteria and would probably slow things down to an unacceptable level.
Code:
Public Function FormatRng(Target As Range, Criteria As Range, i As Integer) As Range
Dim c As Range, Rng As Range
If Criteria.Cells.Count <> 1 Then Exit Function
Application.Volatile
Select Case i
Case 0 'Interior Colour
For Each c In Target
If c.Interior.ColorIndex = Criteria.Interior.ColorIndex Then
If Rng Is Nothing Then
Set Rng = c
Else
Set Rng = Union(Rng, c)
End If
End If
Next c
Case 1 'Font = Bold
For Each c In Target
If c.Font.Bold = Criteria.Font.Bold Then
If Rng Is Nothing Then
Set Rng = c
Else
Set Rng = Union(Rng, c)
End If
End If
Next c
Case 2 'Font = Italics
For Each c In Target
If c.Font.Italic = Criteria.Font.Italic Then
If Rng Is Nothing Then
Set Rng = c
Else
Set Rng = Union(Rng, c)
End If
End If
Next c
Case 3 'Font Size
For Each c In Target
If c.Font.Size = Criteria.Font.Size Then
If Rng Is Nothing Then
Set Rng = c
Else
Set Rng = Union(Rng, c)
End If
End If
Next c
Case 4 'Font Colour
For Each c In Target
If c.Font.ColorIndex = Criteria.Font.ColorIndex Then
If Rng Is Nothing Then
Set Rng = c
Else
Set Rng = Union(Rng, c)
End If
End If
Next c
Case 5 'Font Name
For Each c In Target
If c.Font.Name = Criteria.Font.Name Then
If Rng Is Nothing Then
Set Rng = c
Else
Set Rng = Union(Rng, c)
End If
End If
Next c
Case 6 'Font Underline
For Each c In Target
If c.Font.Underline = Criteria.Font.Underline Then
If Rng Is Nothing Then
Set Rng = c
Else
Set Rng = Union(Rng, c)
End If
End If
Next c
End Select
Set FormatRng = Rng
End Function