2006.03.16 08:25 PM
Determine if an Excel Range Is Empty in VBA
One obvious candidate for determining whether all of the cells of a Range are empty is the COUNTBLANK function, which is accessed in VBA using the global Excel object's WorksheetFunction class. You can wrap it in a function like this:
Function RangeIsEmpty(ByVal SourceRange As Range) As Boolean RangeIsEmpty = (WorksheetFunction.CountBlank(SourceRange) = SourceRange.Count) End Function
Pretty simple. However, COUNTBLANK includes cells having formulas that return empty strings (e.g., =""), which may not be what you want. If what you really want is empty empty, as in no formulas, constants, errors - nothing, then a better choice is probably the COUNTA function:
Function RangeIsEmpty(ByVal SourceRange As Range) As Boolean RangeIsEmpty = (WorksheetFunction.CountA(SourceRange) = 0) End Function
Alternatively, you might be tempted to use the SpecialCells method of the Range object, passing it xlCellTypeBlanks for the Type parameter. If you do, though, you'll have to take care to deal with some of SpecialCells' special behaviors (at least in Excel 2003, I haven't looked back at 2002/XP or 2000 to test any of this).
The most important thing to know about SpecialCells is that it doesn't consider (or return) any cells exceeding the bottom right corner of the UsedRange of the worksheet containing the source Range against which SpecialCells is executed. Got it?
Here's a worksheet containing just one constant value in cell C3:

And here's what we get if we call SpecialCells looking for blanks using the entire worksheet as the source Range:
?ActiveSheet.Cells.SpecialCells(xlCellTypeBlanks).Address $A$1:$C$2,$A$3:$B$3
Instead of returning a Range representing the entire sheet, less cell C3, the resulting Range has been trimmed by SpecialCells to the worksheet's last used row and column. This trimming also takes place if the source Range overlaps the bottom and/or right boundary of the UsedRange:
?ActiveSheet.Range("C1:D3").SpecialCells(xlCellTypeBlanks).Address $C$1:$C$2
Notice how SpecialCells trimmed the results on the right boundary at column C even though cells D1:D3 were explicitly included in the source Range.
It's probably not accurate to say SpecialCells "trims" the results. More likely it never actually considers cells that fall below or to the right of the UsedRange.
Here's another thing. SpecialCells ignores any source Range consisting of only one cell. When executing SpecialCells on a Range having only one cell, it will instead consider all of the cells falling within the boundary marked by the bottom right cell of the source Range sheet's UsedRange:
?ActiveSheet.Range("A1").SpecialCells(xlCellTypeBlanks).Address $A$1:$C$2,$A$3:$B$3
Finally, if SpecialCells fails to find any cells that match the specified Type and Value criteria, it does not just return Nothing, like Intersect, it raises error 1004: No cells were found.
Add all this up, toss in some arbitrary source Ranges having multiple overlapping Areas, and it gets just a little bit tricky to write a function using SpecialCells to determine whether Ranges are indeed empty empty. Tricky ain't impossible, though, so here's one way to get it done:
Function RangeIsEmpty(ByVal SourceRange As Range) As Boolean Dim SpecialUsedRange As Range Dim OverlappingRange As Range Dim OverlappingRangeArea As Range Dim EmptyCellsRange As Range Set SpecialUsedRange = SourceRange.Worksheet.Range("A1", SourceRange.SpecialCells(xlCellTypeLastCell)) Set OverlappingRange = Intersect(SourceRange, SpecialUsedRange) If OverlappingRange Is Nothing Then RangeIsEmpty = True Exit Function End If If OverlappingRange.Count = 1 Then RangeIsEmpty = IsEmpty(OverlappingRange.Value) Exit Function End If For Each OverlappingRangeArea In OverlappingRange.Areas If OverlappingRangeArea.Count = 1 Then If Not IsEmpty(OverlappingRange.Value) Then Exit Function End If Else On Error Resume Next Set EmptyCellsRange = OverlappingRangeArea.SpecialCells(xlCellTypeBlanks) On Error GoTo 0 If Not EmptyCellsRange Is Nothing Then If EmptyCellsRange.Count <> OverlappingRangeArea.Count Then Exit Function End If Set EmptyCellsRange = Nothing End If End If Next OverlappingRangeArea RangeIsEmpty = True End Function
Personally, I'm going to stick with COUNTA.
Comments
Another SpecialCells issue from Ron de Bruin:
http://www.rondebruin.nl/specialcells.htm
ewbi.develops | 2006.03.23 09:57 AM
Actually, I'm going to stick with FormulaArray, check it out:
http://www.dailydoseofexcel.com/archives/2006/04/11/testing-for-empty-cells-ii/
ewbi.develops | 2006.04.11 04:50 PM
Oops, maybe not. See the comment about FormulaArray, single quotes, and empty string values from fzz on 4/14. I confirmed it in Excel 2003. Drag.
ewbi.develops | 2006.04.14 06:26 PM
Thanks for the on error and is nothing trick! I was looking for a way to handle the case where specialcells finds nothing.
Constantin | 2009.04.26 03:03 PM
Post a Comment
TrackBack
TrackBack URL: http://www.typepad.com/services/trackback/6a00d8341c7bd453ef00d8347dbe0d53ef
Listed below are links to weblogs that reference Determine if an Excel Range Is Empty in VBA: