excel 删除后标识空“范围”

hmtdttj4  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(132)

我使用范围,有时会删除给定对象中的所有单元格(Range.Cells.Delete
我到处玩了一下,发现了这些:

  • 删除所有单元格后,变量类型仍为Range,变量类型为Is Not Nothing
  • 调用其任何成员会导致错误"需要对象"

下面是我的小分测试它:

Sub test()
    Dim r As Range

    Debug.Print r Is Nothing        ' -> true
    Set r = ActiveSheet.Range("a2")
    Debug.Print TypeName(r)         ' -> Range
    r.Cells.Delete shift:=xlShiftUp
    On Error GoTo ErrHandler
    Debug.Print r Is Nothing        ' -> False
    Debug.Print TypeName(r)         ' -> Range
    Debug.Print r.Address           ' -> "Err: Object required"
    Debug.Print r.Cells.Count       ' -> "Err: Object required"

    Exit Sub
ErrHandler:
    MsgBox "Err: " & Err.Description
    Resume Next
End Sub

我的问题是:如何确定(希望没有错误处理)一个对象是否为空Range
目前为止我找到的最短选项:

Function IsEmptyRange(testRange As Range) As Boolean
    If TypeName(testRange) <> "Range" Then
        IsEmptyRange = False
    Else
        On Error GoTo EmptyRange
        IsEmptyRange = testRange.Cells.Count = 0
        If False Then
EmptyRange:
            Err.Clear
            IsEmptyRange = True
        End If
    End If
End Function
nfs0ujit

nfs0ujit1#

Daily Dose of Excel上有一个有趣的讨论,指向一个类似的堆栈溢出question。DDoE没有给予一个“解决方案”,但讨论是关于“预期行为”的启发。SO帖子(@DougGlancy)有,但它只是你的代码的一个版本(可能稍微好一点,因为不需要If False Then...构造)。
这里的最佳实践是记住在可以的时候将引用变量设置为Nothing

Sub test()
    Dim r As Range

    Debug.Print r Is Nothing        ' -> true
    Set r = ActiveSheet.Range("a2")
    Debug.Print TypeName(r)         ' -> Range
    r.Cells.Delete shift:=xlShiftUp

    Set r = Nothing                 ' -> end of problem

    On Error GoTo ErrHandler

    Debug.Print r Is Nothing        ' -> True

    If Not r Is Nothing Then
        Debug.Print TypeName(r)         ' -> Range
        Debug.Print r.Address           ' -> "Err: Object required"
        Debug.Print r.Cells.Count       ' -> "Err: Object required"
    End If

    Exit Sub
ErrHandler:
    MsgBox "Err: " & Err.Description
    Resume Next
End Sub

现在的趋势可能是让scope来处理清理工作(即,一旦Sub完成,r将超出scope),但最好是自己进行清理。

enxuqcxy

enxuqcxy2#

在我的例子中,我没有任何循环,因此For ... Step -1,正如奈杰尔Heffernan所说,不是一个解决方案。
对于这个问题,正确的解决方案将取决于上下文。这是我的:

Sub test()
    'Mi context: from C2 all the cells are empty
    Dim Rng As Range
    Set Rng = ActiveSheet.Range("A2:B2")
    
    'trim all cells in Rng
    Rng = Application.Trim(Rng.Value)
    
    'I use CountIf instead xlCellTypeBlanks because it
    'would give an error if there are no empty cells
    If WorksheetFunction.CountIf(Rng, "") > 0 Then
        'delete all empty cells in Rng
        Rng.SpecialCells(xlCellTypeBlanks).Delete Shift:=xlToLeft
    End If
        
    'Assign Rng again
    Set Rng = ActiveSheet.Range("A2:B2")
    
    'and check again if all cells are empty
    If WorksheetFunction.CountIf(Rng, "") = Rng.Cells.Count Then
        MsgBox """A2:B2"" range have been deleted"
    Else
            
        'do something

    End If
End Sub

在其他上下文中,可以存储初始值 并在删除该范围内的单元格后,与新分配的Rng进行比较

相关问题