12

このような開始日と終了日に基づいてテーブルからデータを取得するExcelssに動的に定義された名前付き範囲があります

=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'のメソッド'Range'が失敗しました」というメッセージが表示されます。

4

5 に答える 5

32

これは、名前付き範囲が存在するかどうかを返すためにノックアップした関数です。それはあなたを助けるかもしれません。

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
于 2013-10-04T10:52:26.600 に答える
17

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
于 2012-09-26T23:39:07.153 に答える
3

これは別のアプローチです。テストするコンテナと名前を取得できるという利点があります。つまり、たとえば、シート名またはワークブック名​​のいずれかをテストできます。

このような:

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
于 2014-02-07T17:07:06.783 に答える
1

実行しているアプリケーションによっては、辞書の使用を検討することをお勧めします。何かが存在するかどうかを確認したい場合に特に便利です。この例を見てください:

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メソッドを使用することで回避できます。辞書の使い方についての良いリファレンスが必要な場合は、これを使用してください

幸運を!

于 2017-02-22T04:32:01.710 に答える
0

これは古い投稿ですが、評価された回答のいずれにもname、ワークブックまたはワークシートにが存在するかどうかをテストするための動的なソリューションはありません。以下のこの関数はそれを達成します:

Function pg_Any_Name(thename As String) As Boolean
Dim n As Name, t As String
   
   For Each n In ThisWorkbook.Names
      t = Mid(n.Name, InStr(1, n.Name, "!", vbTextCompare) + 1, 999)

      If UCase(thename) = UCase(t) Then
         pg_Any_Name = True
         Exit Function
      End If
   Next n

End Function

OPには動的に定義された範囲があるため、これはこの特定の質問では機能しなかったことに注意してください。この質問は、常に数式として存在するため、名前が有効な範囲であるかどうかをテストするというタイトルがより正確になります。問題は、それが有効な範囲であるかどうかでした。ワークブックとシートの両方をチェックするソリューションでこの質問に対処するには...この関数は機能します:name

Function PG_Range_Name(thename As String) As Boolean
Dim n As Name, t As String
  
   For Each n In ThisWorkbook.Names
      t = Mid(n.Name, InStr(1, n.Name, "!", vbTextCompare) + 1, 999)
      
      If UCase(thename) = UCase(t) Then
         On Error Resume Next
         PG_Range_Name = n.RefersToRange.Columns.Count > 0
         Exit Function
      End If
   Next n

End Function
于 2021-11-30T02:07:49.403 に答える