The Range.SpecialCells method can be used to return a Range object meeting certain criteria. The type of criteria is specified using an xlCellType constant.
One of those constants (xlCellTypeBlanks) is described as referring to "Empty cells" with no further elaboration .
Does anyone know what definition of "Empty" this method uses? Does it include cells with no values/formulas but various other features (data validation, normal formatting, conditional formatting, etc)?
That type includes the subset of cells in a range that contain neither constants nor formulas. Say starting with an empty sheet we put something in A1 and A10 and then run:
Sub ExtraSpecial()
Set r = Range("A:A").SpecialCells(xlCellTypeBlanks)
MsgBox r.Count
End Sub
we get:
Formatting and Comments are not included. Also note that all the "empty" cells below A10 are also ignored.
The definition does indeed contain the idea of having nothing in the cell, ie it excludes any cell that contains either:
But it also excludes any cell that's not within the range going from A1 to the last used cell of the sheet (which can be identified programmatically through ws.cells.specialCells(xlCellTypeLastCell)
, or by using the keyboard Ctrl+End
).
So if the sheet contains data down to cell C10 (ie Ctrl+End
brings the focus to cell C10), then running Range("D:D").specialCells(xlCellTypeBlanks)
will fail.
NB The range A1 to LastCellUsed
can sometimes be different from the used range
. That would happen if some rows at the top and/or some columns at on the left never contained any data.
On the other hand, cells that fit the empty definition above will be properly identified no matter any of the followings:
A bit beside the main subject, let me ask a tricky question related to how the term BLANK might be defined within Excel:
CountA
and CountBlank
? Well, if a cell contains '
(which will be displayed as a blank cell), both CountA
and CountBlank
will return the value 1 when applied to that cell. My guess is that technically, it does contain something, though it is displayed as a blank cell. This strange feature has been discussed here .
Sub ZeroLengthString()
Dim i As Long
Dim ws As Worksheet
Set ws = ActiveSheet
ws.Range("A2").Value = ""
ws.Range("A3").Value = Replace("a", "a", "")
ws.Range("A4").Value = """"
ws.Range("A6").Value = "'"
ws.Range("A7").Formula= "=if(1=2/2,"","")"
ws.Range("B1").Value = "CountA"
ws.Range("C1").Value = "CountBlank"
ws.Range("B2:B7").FormulaR1C1 = "=CountA(RC[-1])"
ws.Range("C2:C7").FormulaR1C1 = "=CountBlank(RC[-2])"
For i = 2 To 7
Debug.Print "CountA(A" & i & ") = " & Application.WorksheetFunction.CountA(ws.Range("A" & i))
Debug.Print "CountBlank(A" & i & ") = " & Application.WorksheetFunction.CountBlank(ws.Range("A" & i))
Next i
End Sub
In this example, both lines 6 & 7 will return 1 for both CountA and CountBlank.
So the term Blank doesn't appear to be defined a unique way within Excel: it varies from tool to tool.
Papalew's response noted that "xlCellTypeBlanks" excludes any cells not within a specific version of the "used range" that's calculated in the same way as the special cell type "xlCellTypeLastCell". Through testing I've discovered that "xlCellTypeLastCell" returns the last cell of the "UsedRange" property as of the last time the property was calculated .
In other words, adding a line that references "UsedRange" will actually change the behavior of the SpecialCells methods. This is such unusual/unexpected behavior that I figured I'd add an answer documenting it.
Sub lastCellExample()
Dim ws As Worksheet
Set ws = Sheets.Add
ws.Range("A1").Value = "x"
ws.Range("A5").Value = "x"
ws.Range("A10").Value = "x"
'Initially the "UsedRange" and calculated used range are identical
Debug.Print ws.UsedRange.Address
'$A$1:$A$10
Debug.Print ws.Range(ws.Range("A1"), _
ws.Cells.SpecialCells(xlCellTypeLastCell)).Address
'$A$1:$A$10
Debug.Print ws.Cells.SpecialCells(xlCellTypeBlanks).Address
'$A$2:$A$4,$A$6:$A$9
'After deleting a value, "UsedRange" is recalculated, but the last cell is not...
ws.Range("A10").Clear
Debug.Print ws.Range(ws.Range("A1"), _
ws.Cells.SpecialCells(xlCellTypeLastCell)).Address
'$A$1:$A$10
Debug.Print ws.Cells.SpecialCells(xlCellTypeBlanks).Address
'$A$2:$A$4,$A$6:$A$10
Debug.Print ws.UsedRange.Address
'$A$1:$A$5
'...until you try again after referencing "UsedRange"
Debug.Print ws.Range(ws.Range("A1"), _
ws.Cells.SpecialCells(xlCellTypeLastCell)).Address
'$A$1:$A$5
Debug.Print ws.Cells.SpecialCells(xlCellTypeBlanks).Address
'$A$2:$A$4
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.