ApplePie
ApplePie

Reputation: 8942

Range.SpecialCells with varying results

This is another weird one.

I have this code which takes data from one sheet using filters and is using the Range.SpecialCells() method to find the appropriate rows to copy and paste. However, if I used Rows().SpecialCells() or if I used the row property of the range returned by SpecialCells the count of rows is wrong. Here's what I mean:

With Worksheets("ret-" & sNumRet)
    .EnableAutoFilter = True
    .AutoFilter.Range.AutoFilter Field:=3, Criteria1:=sSection
    iLast = Range("C1").End(xlDown).Row
    numRows = .Range("B2:B" & iLast).SpecialCells(xlCellTypeVisible).Cells.Count
End With

This code yields around 8k rows which is a number that makes sense.

With Worksheets("ret-" & sNumRet)
    .EnableAutoFilter = True
    .AutoFilter.Range.AutoFilter Field:=3, Criteria1:=sSection
    iLast = Range("C1").End(xlDown).Row
    numRows = .Rows("2:" & iLast).SpecialCells(xlCellTypeVisible).Rows.Count
End With

Yields 4 as a result.

With Worksheets("ret-" & sNumRet)
    .EnableAutoFilter = True
    .AutoFilter.Range.AutoFilter Field:=3, Criteria1:=sSection
    iLast = Range("C1").End(xlDown).Row
    numRows = .Range("B2:B" & iLast).SpecialCells(xlCellTypeVisible).Rows.Count
End With

Also yields 4 as a result. Both of those are of course wrong. I have 45k rows of data and I can see that at least a few thousands are displayed using the filter. Is there some difference of meaning I am missing between those statements ? I would expect them to be almost equivalent in the context here.

Thanks !

Upvotes: 3

Views: 1009

Answers (1)

Doug Glancy
Doug Glancy

Reputation: 27478

This doesn't really have to do with SpecialCells, rather how Excel counts rows. Rows.Count returns counts for each contiguous Area in the range being counted. For example, in the Immediate window:

? range("a2:a3,a5:a7").cells.Count

returns 5

? range("2:3,5:7").rows.Count

returns 2

? range("2:3,5:7").areas(1).rows.Count

returns 2

? range("2:3,5:7").areas(2).rows.Count

returns 3

As you can see, if you don't specify an area the first one is returned.

To get an answer for all areas loop through them:

Sub CountRows()
Dim i As Long
Dim RowTotal As Long

With ActiveSheet.Range("2:3,5:7")
    For i = 1 To .Areas.Count
        RowTotal = RowTotal + .Areas(i).Rows.Count
    Next i
End With
Debug.Print RowTotal
End Sub

Upvotes: 6

Related Questions