Excel Name.RefersToRange: як перевірити, якщо об'єкт Name відноситься до діапазону?


3

Про документацію Microsoft йдеться RefersToRange :

Якщо об'єкт Name не відноситься до діапазону (наприклад, якщо він посилається   до константи або формули), це властивість виходить з ладу.

Я намагаюся переглядати всі названі діапазони на робочому аркуші.

Private Sub Something()

    Dim namedRanges As names
    Set namedRanges = ActiveSheet.names

    Dim targetSheet As Worksheet
    Set targetSheet = Sheet1
    targetSheet.Cells.Clear

    Dim i As Integer
    For i = 1 To namedRanges.count
        targetSheet.Cells(i, 2).Value = namedRanges(i).Name
        targetSheet.Cells(i, 3).Value = namedRanges(i).RefersToRange.Address
    Next


End Sub

У вищезазначеному мій код буде невдалим, якщо будь-який NamedRange не посилається на діапазон. Як я можу перевірити, чи відноситься об'єкт Name до діапазону, щоб мій код не вийшов з ладу?

UPDATE

Я знайшов hack щоб зробити це але я віддаю перевагу більш чистий шлях. Я перевіряю, чи містить рядок значення іменного діапазону знак долара, який непрямо повідомляє мені, чи містить він значення адреси (який буде діапазон):

For i = 1 To namedRanges.count
    targetSheet.Cells(i, 2).Value = namedRanges(i).Name
    If InStr(namedRanges(i).Value, "$") > 0 Then
        targetSheet.Cells(i, 3).Value = namedRanges(i).RefersToRange.Address
    End If
Next

Це не завжди працює. Допустимі діапазони не повинні мати знаків "$", тобто =OFFSET(NameRange,0,0) може мати дійсний діапазон, і відносна назва діапазону '= A1' також діє без $.
brettdj

Відповіді:


1

Це те, що перевіряє, чи існує допустима перетинання в використовуваному діапазоні цікавого аркуша з назвою діапазону

Застереження: Це припускає, що ваш usedrange охоплює ваші потенційні назви діапазону. Яку думку, це безпечне припущення

Також ви не думаю, що ви можете працювати ActiveSheet.Names так, як ви пробували.

Private Sub Something()
    Dim nmRng As Name
    Dim rng1 As Range
    Dim rng2 As Range
    Set rng1 = Sheets(1).UsedRange
    On Error Resume Next
    For Each nmRng In ActiveWorkbook.Names
        Set rng2 = Nothing
        Set rng2 = Intersect(rng1, Range(nmRng))
        If Not rng2 Is Nothing Then Debug.Print nmRng & " " & nmRng.RefersTo.Address
    Next
    On Error GoTo 0
End Sub

Ви можете використовувати ActiveSheet.Names, але, мабуть, маєте рацію, що не обмежує імена поточному аркушу.
User

Чи існує причина, за якою у вашому коді буде відновлено помилку?
User

Так, це означає, що недійсний Intersect випробування не призведуть до помилки коду.
brettdj

1

EDIT: Я змінив обробку помилок, щоб пропустити константи Не те, що я виступаю за цей підхід для більшості проблем, але ви можете використовувати

on error goto "label"

який виглядатиме приблизно так

Private Sub Something()

Dim namedRanges As names
Set namedRanges = ActiveSheet.names

Dim targetSheet As Worksheet
Set targetSheet = Sheet1
targetSheet.Cells.Clear

Dim i As Integer

'skip the errors
on error goto skipName
'set start of data range
Row = 2
For i = 1 To namedRanges.count

    targetSheet.Cells(Row, 3).Value = namedRanges(i).RefersToRange.Address
    targetSheet.Cells(Row, 2).Value = namedRanges(i).Name
Row = Row + 1
skipName:
Next

'reinstate normal error trapping
on error goto 0

End Sub

Обробка помилок тепер буде пропускати список імен, коли Referstorange не вдасться.


Спасибі, але так, я не хочу, щоб перерахувати постійні або імена формул.
User

Я змінив код вище, щоб він більше не друкував постійних імен.
Pynner
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.