Count If with Non-Consecutive Range

cart0250

Active Member
Joined
Jun 24, 2006
Messages
290
Office Version
  1. 2016
Platform
  1. Windows
Hello,

This counts the number of instances of X* within range M10:M16 and returns the value into cell M8.

Instead of M10:M16, can a non-consecutive range be used here? Such as (M10:M11, M13:M14, M16:M17).

VBA Code:
Range("M8").Value = Application.WorksheetFunction.CountIf(Range("M10:M16"), "X*")
 

Excel Facts

Format cells as currency
Select range and press Ctrl+Shift+4 to format cells as currency. (Shift 4 is the $ sign).
Could be:
VBA Code:
Range("M8").Value = Application.WorksheetFunction.CountIf(Range("M10:M11"), "X*") + _
                    Application.WorksheetFunction.CountIf(Range("M13:M14"), "X*") + _
                    Application.WorksheetFunction.CountIf(Range("M16:M17"), "X*")


Or:
VBA Code:
  Dim nCount As Long
  Dim itm As Variant
 
  For Each itm In Array("M10:M11", "M13:M14", "M16:M17")
    nCount = nCount + Application.WorksheetFunction.CountIf(Range(itm), "X*")
  Next
  Range("M8").Value = nCount

Or:
VBA Code:
  Dim c As Range
  Dim nCount As Long
  
  For Each c In Range("M10:M11, M13:M14, M16:M17")
    If UCase(c.Value) Like "X*" Then
      nCount = nCount + 1
    End If
  Next
  Range("M8").Value = nCount

🤓
 
Upvote 0
Solution
Could be:
VBA Code:
Range("M8").Value = Application.WorksheetFunction.CountIf(Range("M10:M11"), "X*") + _
                    Application.WorksheetFunction.CountIf(Range("M13:M14"), "X*") + _
                    Application.WorksheetFunction.CountIf(Range("M16:M17"), "X*")


Or:
VBA Code:
  Dim nCount As Long
  Dim itm As Variant
 
  For Each itm In Array("M10:M11", "M13:M14", "M16:M17")
    nCount = nCount + Application.WorksheetFunction.CountIf(Range(itm), "X*")
  Next
  Range("M8").Value = nCount

Or:
VBA Code:
  Dim c As Range
  Dim nCount As Long
 
  For Each c In Range("M10:M11, M13:M14, M16:M17")
    If UCase(c.Value) Like "X*" Then
      nCount = nCount + 1
    End If
  Next
  Range("M8").Value = nCount

🤓
 
Upvote 0
Non-contiguous range references consist of multiple Areas, so you could also just loop thru the areas. For example, a custom function could be defined something like this:

VBA Code:
Public Function CountIfByArea(reference As Range, criteria As Variant) As Long
    Dim i As Long, j As Long
    For i = 1 To reference.Areas.Count
        j = j + Application.WorksheetFunction.CountIf(reference.Areas(i), criteria)
    Next i
    CountIfByArea = j
End Function

Then, you can use the custom function directly in the worksheet:

Excel Formula:
=CountIfByArea((M10:M11,M13:M14,M16:M17),"X*")

Or, called in VBA:

VBA Code:
Sub Test()
    Range("M8").Value = CountIfByArea(Range("M10:M11,M13:M14,M16:M17"), "X*")
End Sub

Incidentally, for those using a modern version of Excel (Office 365 or 2024), a custom LAMBDA function could also be defined in Name Manager for this task:

Excel Formula:
=LAMBDA(reference,criteria,REDUCE(0,SEQUENCE(AREAS(reference)),LAMBDA(a,v,a+COUNTIF(INDEX(reference,,,v),criteria))))

Cheers!
 
Upvote 0
With a modern version, you could also do this:
Excel Formula:
=COUNTA(LET(a,TOCOL((M10:M11,M13:M14,M16:M17)),FILTER(a,LEFT(a)="X")))
 
Upvote 0
But you could also do this:
Excel Formula:
=SUMPRODUCT(--(MOD(ROW(M10:M17)-ROW(M10),3)<>2),--(LEFT(M10:M17)="X"))
 
Upvote 0
With a modern version, you could also do this:
Excel Formula:
=COUNTA(LET(a,TOCOL((M10:M11,M13:M14,M16:M17)),FILTER(a,LEFT(a)="X")))

Hi Scott,

Regarding this method, COUNTA is not really recommended as a suitable companion for the FILTER function (or any other array functions for that matter), as it is incapable of returning 0. If no matching records are found, the FILTER function returns #CALC! because "Empty arrays are not supported". COUNTA "Counts the number of cells in a range that are not empty", so anything other than a blank cell will be counted as 1, including errors and empty strings ("").

IFERROR(ROWS(...),0) would be an acceptable alternative because ROWS will also return #CALC! when FILTER does not find a match (assuming the [if_empty] argument is omitted). However, for this particular scenario, it might be more appropriate to simply SUM the results of the text comparison, using either a double-negative or the N function to convert Boolean values to 1's and 0's:

Excel Formula:
=SUM(--(LEFT(TOCOL((M10:M11,M13:M14,M16:M17)))="X"))

The COUNTIF lambda function I shared previously was merely a demonstration of how the exact same custom function could be created using LAMBDA instead of VBA. The biggest benefit of a COUNTIF based approach is that it offers basic wildcard functionality (*, ?, ~). The biggest drawback, however, is that it only works with a physical range reference. ;)

Kind regards.
 
Upvote 0
I do like that SUM approach.

Yes, I was just trying to come up with a formula based approach too. I had used COUNTA before, but didn't realize the 0 result problem. Thanks
 
Upvote 0

Forum statistics

Threads
1,225,135
Messages
6,183,066
Members
453,147
Latest member
Lacey D

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