简体   繁体   中英

Range.SpecialCells: What does xlCellTypeBlanks actually represent?

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:

  • a numerical value
  • a date or time value
  • a text string (even an empty one)
  • a formula (even if returning an empty string)
  • an error
  • a boolean value

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:

  • size or colour of font
  • background colour or pattern
  • conditional formatting
  • borders
  • comments
  • or any previous existence of these that would later have been cleared.

A bit beside the main subject, let me ask a tricky question related to how the term BLANK might be defined within Excel:

  • How can a cell return the same value for 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.

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