测试VBA中是否存在范围

时间:2012-09-26 23:20:51

标签: excel vba range offset

我的excel ss中有一个动态定义的命名区域,它根据开始日期和结束日期从表中获取数据

=OFFSET(Time!$A$1,IFERROR(MATCH(Date_Range_Start,AllDates,0)-1,MATCH(Date_Range_Start,AllDates)),1,MATCH(Date_Range_End,AllDates)-IFERROR(MATCH(Date_Range_Start,AllDates,0)-1,MATCH(Date_Range_Start,AllDates)),4)

但是如果日期范围在表中没有数据,则范围不存在(或者某些东西,idk)。如何在VBA中编写代码来测试该范围是否存在?

我尝试了类似

的内容
If Not Range("DateRangeData") Is Nothing Then

但我得到“运行时错误1004,对象'_Global'的方法'范围'失败。”

4 个答案:

答案 0 :(得分:24)

这是一个函数,我敲了回来判断是否存在命名范围。它可能会帮助你。

Function RangeExists(R As String) As Boolean
    Dim Test As Range
    On Error Resume Next
    Set Test = ActiveSheet.Range(R)
    RangeExists = Err.Number = 0
End Function

答案 1 :(得分:15)

您可以在使用范围之前复制VBA中的匹配进行计数,也可以使用错误处理:

On Error Resume Next

Debug.Print range("DateRangeData").Rows.Count

If Err = 1004 Then
    MsgBox "Range Empty"
    Exit Sub
Else
    MsgBox "Range full"
End If

Err.Clear
On Error GoTo 0

答案 2 :(得分:2)

这是另一种方法。它具有获取容器和要测试的名称的优势。这意味着您可以测试表格名称或工作簿名称。

像这样:

If NamedRangeExists(ActiveSheet.Names, "Date") Then
    ...
Else
...
End If

If NamedRangeExists(ActiveWorkbook.Names, "Date") Then
   ...
Else
   ...
End If

Public Function NamedRangeExists(ByRef Container As Object, item As String) As Boolean


Dim obj As Object
Dim value As Variant

On Error GoTo NamedRangeExistsError:

    value = Container(item)
    If Not InStr(1, CStr(value), "#REF!") > 0 Then
        NamedRangeExists = True
    End If
    Exit Function

Exit Function

NamedRangeExistsError:
    NamedRangeExists = False
End Function

答案 3 :(得分:1)

根据您正在进行的应用程序,最好考虑使用Dictionary。当你想检查某些东西是否存在时,它们特别有用。 举个例子:

Dim dictNames as Scripting.Dictionary

Sub CheckRangeWithDictionary()

    Dim nm As Name

    'Initially, check whether names dictionary has already been created
    If Not dictNames Is Nothing Then
        'if so, dictNames is set to nothing
        Set dictNames = Nothing
    End If

    'Set to new dictionary and set compare mode to text
    Set dictNames = New Scripting.Dictionary
    dictNames.CompareMode = TextCompare

    'For each Named Range
    For Each nm In ThisWorkbook.Names
        'Check if it refers to an existing cell (bad references point to "#REF!" errors)
        If Not (Strings.Right(nm.RefersTo, 5) = "#REF!") Then
            'Only in that case, create a Dictionary entry
            'The key will be the name of the range and the item will be the address, worksheet included
            dictNames(nm.Name) = nm.RefersTo
        End If
    Next

    'You now have a dictionary of valid named ranges that can be checked

End Sub

在主程序中,您需要做的就是在使用范围

之前进行存在检查
Sub CopyRange_MyRange()

    CheckRangeWithDictionary

    If dictNames.exists("MyRange") then
        Sheets(1).Range("MyRange").Copy
    end if

End Sub

虽然加载字典可能看起来要长一些,但处理和搜索的速度非常快。检查是否存在引用有效地址的任何命名范围变得更加简单,而不在此简单应用程序中使用错误处理程序。

请注意,在工作表级别而不是工作簿级别使用名称时,必须使用更精细的密钥来保证唯一性。从创建字典的方式来看,如果重复键,则会覆盖项目值。通过使用相同的 Exists 方法作为密钥创建语句中的检查,可以避免这种情况。如果您需要有关如何使用词典的良好参考,请使用此one

祝你好运!