Possible to use user defined functions within array formula?

fender242

New Member
Joined
Mar 3, 2014
Messages
2
I created the following user defined function:

Function FontColor(r As Range) As Integer
FontColor = r.Font.ColorIndex
End Function

Now I need to count only the rows that have "cat" in column A as well as red font in column B:

[TABLE="width: 128"]
<tbody>[TR]
[TD="class: xl65"]A[/TD]
[TD="class: xl65, width: 64"]B[/TD]
[/TR]
[TR]
[TD="class: xl63"]dog[/TD]
[TD="class: xl63"]8[/TD]
[/TR]
[TR]
[TD="class: xl63"]cat[/TD]
[TD="class: xl64"]9[/TD]
[/TR]
[TR]
[TD="class: xl63"]shoe[/TD]
[TD="class: xl63"]6[/TD]
[/TR]
[TR]
[TD="class: xl63"]cat[/TD]
[TD="class: xl64"]9[/TD]
[/TR]
[TR]
[TD="class: xl63"]shoe[/TD]
[TD="class: xl63"]42[/TD]
[/TR]
[TR]
[TD="class: xl63"]dog[/TD]
[TD="class: xl63"]8[/TD]
[/TR]
[TR]
[TD="class: xl63"]cat[/TD]
[TD="class: xl63"]7[/TD]
[/TR]
</tbody>[/TABLE]

The formula I'm using is this:

{=COUNT(IF(A:A="cat",IF(fontcolor(B:B)=3,B:B)))}

This tells excel to count the rows in column B, only when the left column is "cat" and the right column has a red font. But it's not working. I get the answer "0". However if I replace the user defined formula with a "built-in" one like this:

{=COUNT(IF(A:A="cat",IF(SQRT(B:B)=3,B:B)))}

The formula works well, I get the answer "2". This tells me that somehow user-defined functions don't work within array formulas, OR they need to be modified to work within array formulas.

Any suggestions, or comments?
 

Excel Facts

What is the shortcut key for Format Selection?
Ctrl+1 (the number one) will open the Format dialog for whatever is selected.
Your UDF needs to allow for each cell in the range, e.g.

Code:
Function FontColor(rng As Range) As Variant
    
    Dim lColor() As Long
    Dim r As Long, c As Long
    
    ReDim lColor(1 To rng.Rows.Count, 1 To rng.Columns.Count)
    
    For r = 1 To UBound(lColor, 1)
        For c = 1 To UBound(lColor, 2)
            lColor(r, c) = rng(r, c).Font.ColorIndex
        Next c
    Next r
    
    FontColor = lColor
    
End Function

Then, for example:

{=SUM((A1:A10="cat")*(FontColor(B1:B10)=3))} will return 2 as required.
 
Upvote 0
You may have noticed that I dodged using whole column references in the previous example:

1. Because generally they are not good practice, and also

2. Because I couldn't get them to work :oops: (using Excel 2013).

I've since fiddled around and discovered that there's a limit of 65,536 on the number of rows the UDF can return, i.e. equal to the maximum number of rows in Excel 2003.

I've encountered a similar issue before, e.g. try the following code in Excel 2007 or later:

Code:
Dim lWorksOK As Long, lTypeMismatchError As Long

lWorksOK = Application.Count([Row(1:65536)])
lTypeMismatchError = Application.Count([Row(1:65537)])

It appears that Excel sometimes still carries forward the old row limit of 65,536 when checking upper bounds. To me, that's a bug, albeit minor.
 
Upvote 0
Thanks for that! That was very helpful. I tried to apply your code to conditionally formatted cells using Interior.ColorIndex, but I guess different code is needed for that (available on the CPearson site). I was referencing the whole column because I'm using a very large number of rows, however I took your advice, and limited the # of rows referenced to within a few hundred of what I'm using (to make room for additions later), and it seems to be calculating faster. Cheers!
 
Upvote 0
Thanks for the feedback!

... limited the # of rows referenced to within a few hundred of what I'm using (to make room for additions later)

You might want to check out dynamic range referencing. There are plenty of useful posts on the Forum.

The risk otherwise is that months or years down the track, someone discovers that their spreadsheet has been producing incorrect results, because sums are calculated using a hard-coded limit of 10,000 rows (say).

If, for example, you want to pick up column A, you know that the data starts in A10, and that all data fields will be non-blank, you can define your range:

Dim rng As Range

Set rng = Range("A10", Range("A10").End(xlDown))
 
Upvote 0

Forum statistics

Threads
1,223,227
Messages
6,170,848
Members
452,361
Latest member
d3ad3y3

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