2015-04-09 4 views
0

Я использую несколько именованных диапазонов, расположенных в разных листах. Мне нужно читать и записывать эти диапазоны во многих ситуациях на протяжении всего кода VBA.Сохранение ссылки диапазона в глобальной переменной

Так что мой вопрос: Каков правильный способ хранения этих ссылок диапазона в глобальных переменных для быстрого доступа? Или есть лучший способ?

Я попытался декларирование глобальные переменные:

Public WS_BOARD As Worksheet 
Public RNG_BOARD As Range 

и инициализирует их на Workbook_Open:

Private Sub Workbook_Open() 
    Set WS_BOARD = Worksheets("BOARD") 
    Set RNG_BOARD = WS_BOARD.Range("NR_BOARD") 
End Sub 

Это работает нормально, за исключением того, если мой код разбивает эти глобальные переменные сбрасываются в Nothing и не может быть используется в дальнейшем (т. е. в обработчиках событий рабочего листа).

Конечно, я всегда могу использовать что-то вроде

Worksheets("BOARD").Range("NR_BOARD") 

везде в моем коде, но я думаю, что это повлияет на производительность, потому что, очевидно, необходимо для поиска объектов с использованием имен строк, не говоря уже о его быть не DRY.

ответ

0

Один из способов - «загрузить» их один раз в память, а затем передать их в качестве аргументов в другие субтитры/функции.
Passing Variables By Reference And By Value

Во-вторых, вы можете объявить их в качестве модуля область видимости переменных (что-то вроде публики, но только в модуле вы объявляете их).
Scope of variables in Visual Basic for Applications

В-третьих, свой путь.
Scope of variables in Visual Basic for Applications

0

Каждый рабочий лист имеет свойство Name (заголовок вкладки) и свойство CodeName. Если вы используете CodeName в своем коде, вам не нужна переменная. Как и пользовательская форма, кодовое имя листа автоматически создается при его использовании. Выберите рабочий лист под своим проектом в Project Explorer (Ctrl + R), перейдите в Propeties (F4) и измените (Name) на проклятое имя_кода. Explorer Project покажет лист как

wshDataEntry (Data Entry) 

если вы сделали Кодовое wshDataEntry и язычок сказал Data Entry.

Для диапазонов я использовал определенные имена в электронной таблице. Это похоже на глобальную переменную, которая никогда не выходит за рамки. Если у вас есть, скажем, и ячейка процентной ставки, которую вы должны прочитать в различной процедуре, назовите ее Interest_Rate. Затем в верхней части каждой процедуры, где вам это нужно

Set rInterest = wshDataEntry.Range(gsNMINTEREST) 

где gsNMINTEREST глобальная строковая переменная холдинг «Interest_Rate». Если ячейка когда-либо перемещается, вам нужно только переместить именованный диапазон для работы кода. Если вы измените имя на «LiborPlusFour», вам нужно обновить глобальную переменную. Довольно сухая.

Да, есть небольшое повышение производительности, что делает VBA каждый раз именованным диапазоном.Я бы не стал беспокоиться об этом, если вы не вычислили проблему с производительностью и не определили ее как перетаскивание.

Один из способов сохранения глобальных переменных (конечно, я очень разумно их использую) в области - это процедура инициализации.

Public Sub Initialize() 

    If gclsApp Is Nothing Then 
     Set gclsApp = New CApp 
     'do some other setup 
    End If 

End Sub 

Затем я вызываю процедуру Initialize в верхней части любого модуля, в котором я нуждаюсь. Если это не ничего, то он не сбрасывает переменную. Я не уверен, что последствия производительности для «Ничего» и просто поиск именованного диапазона.

0

Глобальные переменные, как правило, не очень хорошая идея. В некоторых случаях они необходимы, но это не один из этих случаев.

Я не думаю, что вам следует беспокоиться о влиянии производительности на несколько диапазонов по их имени строки. У меня есть листы с сотнями названных диапазонов, и у меня никогда не было , что это негативно отразилось на производительности.

У вас есть конкретные доказательства того, что это замедляет ваш код? Если нет, то не теряйте время, беспокоясь об этом.

Я часто делаю это, чтобы определить диапазоны:

Type RangesType 
    board As Range 
    plank As Range 
    wood As Range 
End Type 

Function GetRanges() As RangesType 
    With GetRanges 
     Set .board = Range("board") 
     Set .plank = Range("plank") 
     Set .wood = Range("wood") 
    End With 
End Function 

Затем я использую их, как это:

Sub something() 
    Dim rngs As RangesType: rngs = GetRanges 

    rngs.board = "My favourite board" 
    rngs.wood = "Chestnut" 
    'etc. 

End Sub 

Да, диапазоны будут получать извлекался своим именем несколько раз, если у вас есть много подводных лодок, и Нет, это вряд ли окажет заметное влияние на производительность.