简体   繁体   中英

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 !

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM