2016-11-08 3 views
1

Я пытаюсь удалить все Named Ranges в своей книге Excel, хранить их в коллекции и после удаления повторно привязать их к моей книге.Повторная привязка именных диапазонов в VBA

Мой код выглядит следующим образом

Sub ResetNamedRanges() 
    Dim rName As Excel.Name 
    Dim cName As Excel.Name 
    Dim rangedNames As Excel.names 
    Dim collNames As New Collection 

    Set rangedNames = ThisWorkbook.names 

    For Each rName In rangedNames 
     collNames.Add rName 
     rName.Delete 
    Next 

    For Each cName In collNames 
     names.Add cName.Name, cName.RefersTo, cName.Visible, cName.MacroType, cName.ShortcutKey, cName.Category, cName.NameLocal, cName.RefersToLocal, cName.CategoryLocal, cName.RefersToR1C1, cName.RefersToR1C1Local 
    Next 
End Sub 

Но это не работает. Уверенный, что я что-то пропустил.

+0

Ваш цикл переменной для перехода через '' rangedNames' является rName', но вместо того, чтобы вы ссылки 'item' ?? Зачем?? Ваша переменная цикла для перехода через 'collNames' является' cName', но вместо этого вы ссылаетесь на 'names' ?? Зачем?? Исправьте свои ссылки на переменную цикла – tigeravatar

+0

@tigeravatar Sry Typo ... – Smartis

+1

Вы сохраняете коллекцию (?) 'NameArray' и восстанавливаете из коллекции' collNames', которая должна работать. –

ответ

1

Используйте Dictionary и возьмите соответствующие свойства.

Ваш метод сбора данных невозможен по причинам, изложенным в комментариях выше: Метод .Delete удаляет любую ссылку на объект Name, который вы помещаете в коллекцию. Ваша коллекция будет заполнена сломанными ссылками, и вы не сможете восстановить имена из сломанных/недопустимых ссылок на объекты.

Option Explicit

Sub foo() 
Dim rName As Name 
Dim dictNames As Object 

Set dictNames = CreateObject("Scripting.Dictionary") 

For Each rName In Names 
     'We're going to use a dict for the properties, also: 
     dictNames.Add rName.Name, Nothing 
     Set dictNames(rName.Name) = CreateObject("Scripting.Dictionary") 
     With dictNames(rName.Name) 
      ' Not my favorite way to do this, but some properties undefined will raise an error 
      ' you can work a better way to do this if you prefer 
      On Error Resume Next 
      .Add "RefersTo", rName.RefersTo 
      .Add "Visible", rName.Visible 
      .Add "MacroType", rName.MacroType 
      .Add "ShortcutKey", rName.ShortcutKey 
      .Add "Category", rName.Category 
      .Add "NameLocal", rName.NameLocal 
      .Add "RefersToLocal", rName.RefersToLocal 
      .Add "CategoryLocal", rName.CategoryLocal 
      .Add "RefersToR1C1", rName.RefersToR1C1 
      .Add "RefersToR1C1Local", rName.RefersToR1C1Local 
      On Error GoTo 0 
     End With 
     rName.Delete 
    Next 

Dim itm 
For Each itm In dictNames 
    Set rName = Names.Add(itm, dictNames(itm)("RefersTo")) 
    On Error Resume Next 
    'rName.RefersTo = itm("RefersTo") 
    rName.Visible = itm("Visible") 
    rName.MacroType = itm("MacroType") 
    rName.ShortcutKey = itm("ShortCutKey") 
    rName.Category = itm("Category") 
    rName.NameLocal = itm("NameLocal") 
    rName.RefersToLocal = itm("RefersToLocal") 
    rName.CategoryLocal = itm("CategoryLocal") 
    rName.RefersToR1C1 = itm("RefersToR1C1") 
    rName.RefersToR1C1Local = itm("RefersToR1C1Local") 
    On Error GoTo 0 
Next 
End Sub 
+0

Это сработало! Спасибо! – Smartis

+1

Рад, что это сработало, хотя мне любопытно узнать, что вы имели в виду под «сломанными» именованными диапазонами (и, кстати, я не уверен, почему * этот * подход мог бы «исправить» их ...). Если это сработало, подумайте о том, чтобы принять ответ :) –

Смежные вопросы