Set nothing excel vba

 

Доброго времени суток!  

  Прошу описать применение функцию «Set» на доступном языке :)  

  Особенно интересует когда обязательно объявлять:  
Set «Переменная» = Nothing  
а когда нет.  

  Спасибо заранее!  

  P.S. буду рад любому Вашему ответу, даже короткому ;)

 

Для переменных текстового, числового и логического типов SET не применяется.  
(применяется оператор LET, который можно не писать)  
Let a = «текст»: a=»текст2″: x = 5.25  

  Для ОБЪЕКТОВ необходимо использовать оператор SET  
set a = worksheets(1): set x = range(«a2:d4»)

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

Всегда желательно в конце процедуры:  
Set «Переменная» = Nothing  
Это принудительно очистит память.

Я сам — дурнее всякого примера! …

 

И вообще, вас что, на Гугле забанили?  

  По VBA есть куча справочников — в каждом описано различие между SET и LET  

  Цитата:  

  В VBA существует два основных типа инструкций присваивания Let и  
Set. Инструкция Let используется в том случае, когда требуется присвоить  
значение выражения переменной или свойству. Её структура имеет следующий  
вид:  
      [Let] имя переменной = выражение
      Значение выражения может быть присвоено только в том случае, когда  
типы переменной и выражения совместимы. Например, нельзя присвоить  
строковой переменной значение выражения, являющегося числовым.  

        Инструкция Set присваивает ссылку на объект переменной или свойству  
объекта. При этом переменной присваивается выражение или значение,  
возвращаемое функцией. Структура инструкции Set имеет следующий вид:  
    Set переменная = [New] выражение | Nothing
    New — необязательный элемент. Это главное слово используется при  
описании для создания нового неявного экземпляра объекта. Если переменная  
содержит ссылку на объект, то при новом присвоении эта ссылка  
освобождается.  
    Выражение — обязательный элемент, представляющий выражение,  
состоящее из имени объекта, переменной соответствующего типа, функции  
или метода, которые возвращают объект того же типа.  
    Nothing — необязательный элемент, который разрывает связь элемента  
переменная с каким-либо определённым объектом. При этом переменная  
получает значение Nothing.

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

ИМХО, если переменная определена в процедуре (локальная), то время её жизни ограничено процедурой и по окончании процедуры (Exit Sub) все локальные переменные «умирают» и освобождают память. Поэтому Set «Переменная» = Nothing для локальных переменных делать не обязательно (конечно, если сама процедура не жутко жадная в смысле пожирания памяти)

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

The_Prist

Пользователь

Сообщений: 14182
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

{quote}{login=Alex_ST}{date=10.06.2010 11:29}{thema=}{post}Поэтому Set «Переменная» = Nothing для локальных переменных делать не обязательно (конечно, если сама процедура не жутко жадная в смысле пожирания памяти){/post}{/quote}Позвольте не согласиться. VBA редактор не такой уж продвинутый, как может показаться и он своими силами высвобождает память не всегда корректно. Он по идее должен все выгрузить, но такое происходит далеко не всегда. Лично я предпочитаю в большинстве случаев именно принудительно высвобождать память от подобных переменных, что и Вам советую.

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

{quote}{login=Alex_ST}{date=10.06.2010 11:29}{thema=}{post}ИМХО, если переменная определена в процедуре (локальная), то время её жизни ограничено процедурой и по окончании процедуры (Exit Sub) все локальные переменные «умирают» и освобождают память. Поэтому Set «Переменная» = Nothing для локальных переменных делать не обязательно (конечно, если сама процедура не жутко жадная в смысле пожирания памяти){/post}{/quote}  
Алекс, я согласен с Вами, но считается хорошим тоном в прогаммировании такие переменные убивать после объявления.  
Это так же как с оператором Goto. Вроде и работает как надо, но не рекомендуют(и тон плохой). Сам никогда не использую:-) Если уж приспичило, то Gosub-Return. С уважением, Сергей.

Я сам — дурнее всякого примера! …

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

Ну вот, за Димой разве успеешь…. Могу только дополнить — не только в ВБА. ВБ5, ВБ6 тоже грешили этим. И сами разработчики рекомендовали делать ТАК явно.

Я сам — дурнее всякого примера! …

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

По поводу «правил хорошего тона» при программировании абсолютно с вами согласен. Это как ржавчина на кузове автомобиля: на скорость не влияет, но и самому смотреть противно, и похвастаться перед другими как-то стыдно…  
Я сам всегда использую явное определение переменных через Dim (Option Explicit у меня ставится по умолчанию)и «убиение» по мере отпадания в них нужды переменных, установленных через Set.  
А уж про комментарии и говорить нечего! Без них и на свою-то программу через месяц будешь долго смотреть и «чесать репу» а что там, как и зачем? А уж про чужие программы и говорить нечего. Некоторые гуру форума, к сожалению иногда грешат примерами без комментариев. Я, если эти примеры кладу к себе в «копилку», то всегда прописываю в макросах что это за модуль, кем написан и откуда взят (ссылка на пост).

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

EducatedFool, спасибо Вам за ответы, но зачем иронизировать или Вы не заметили «…на доступном языке»?!  

  Спасибо Вам, Алексей, Дмитрий и Сергей!  

  P.S. теперь все понятно и просто.

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

Алекс, я покраснел прочитав:  «к сожалению иногда грешат примерами без комментариев.» Правда, неудобно. Но я так и читаю чужой код. Не глядя на комменты. Самоучка — и так привык. С Вами абсолютно согласен(только вчера azam-у объяснял полезность комментов), но себя, боюсь, уже не исправлю:-( Я на этом форуме мнооооогому пытаюсь научиться. В первой строке списка доброта Юрий М, его умение общаться, не обижая других. Мне бы так. Ладно, что-то я совсем расчувствовался(это из мультика, не подумайте).

Я сам — дурнее всякого примера! …

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

зря вы на goto ополчились   :)  иногда без него никак..  

  коммменты, да, ленюсь писать, каюсь :)

 

The_Prist

Пользователь

Сообщений: 14182
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

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

  Вывод: не брезгуйте этим оператором — он бывает весьма полезен и не вреден в умеренных количествах.

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

The_Prist

Пользователь

Сообщений: 14182
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

Мне лично комменты писать откровенно лень. Прописывать комменты бывает намного дольше, чем сами коды. Для себя я пишу с комментами, а в форум — лень….  

  P.S. Исправляться не собираюсь. Пока, во всяком случае.

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

{quote}{login=слэн}{date=10.06.2010 12:52}{thema=}{post}зря вы на goto ополчились   :)  иногда без него никак..  
коммменты, да, ленюсь писать, каюсь :){/post}{/quote}  
Хоть один случай бы увидеть, когда никак. Видимо я один понимаю вредность этого оператора.  
Ну —  

http://khpi-iip.mipk.kharkiv.edu/library/extent/dijkstra/pp/ewd215.html  

почитайте(прям сейчас нашел, не умею, как Дима, доходчиво объяснять)

Я сам — дурнее всякого примера! …

 

Hugo

Пользователь

Сообщений: 23250
Регистрация: 22.12.2012

Но что-то есть в этом GoTo… В AutoIt с 3-й версии его вообще убрали, тоже мучался, так я и не понял, как сподручнее обходить, местами вообще придуманный алгоритм менять приходилось…

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

{quote}{login=Hugo}{date=10.06.2010 02:04}{thema=}{post}Но что-то есть в этом GoTo… В AutoIt с 3-й версии его вообще убрали, тоже мучался, так я и не понял, как сподручнее обходить, местами вообще придуманный алгоритм менять приходилось…{/post}{/quote}  
Вопрос структурирования прогаммы. А вообще-то я рад, что привлек к обсуждению таких уважаемых на форуме ребят. С вами уютно!

Я сам — дурнее всякого примера! …

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

вот пример когда никак:  

  on error goto    

    вот пример, когда как, но не красиво и yt’aatrnbdyj^  

    for i=1 to n  
for j=1 to m  
if a(i,j)=0 then goto ext  
next j  
next i  
ext:    

  можно, конечно, функцией оформить, с использованием exit function, но на вызов функции тратится время

 

{quote}{login=слэн}{date=10.06.2010 02:12}{thema=}{post}  
вот пример, когда как, но не красиво и yt’aatrnbdyj^{/post}{/quote}  
Согласен. Вот мой пример:  

http://forum.ixbt.com/topic.cgi?id=23:31044

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

Слэн(хочу Вас все же называть с большой буквы), плохой пример. Во всех примерах мэтров программирования goto используется только для определения ошибки, с последующим Exit Sub. То есть goto на выход. И я в жизни не встречал ситуаций, когда нельзя было избежать его. Поначалу(это еще в 2000 где-то), напрягало, помню. Зато сейчас даже в мыслях не бывает. Вот так мозги перестроились. Прсто блок стоит.

Я сам — дурнее всякого примера! …

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

{quote}{login=Казанский}{date=10.06.2010 02:17}{thema=Re: }{post}{quote}{login=слэн}{date=10.06.2010 02:12}{thema=}{post}  
вот пример, когда как, но не красиво и yt’aatrnbdyj^{/post}{/quote}  
Согласен. Вот мой пример:  

http://forum.ixbt.com/topic.cgi?id=23:31044

{/post}{/quote}  
Это пример, когда нельзя?  
Set s = Range(«a:a»).Find(«конь»)  
If Not s Is Nothing Then  
   If s.Offset(0, 1) = «белый» Then  
       answer = «YES»  
   Else  
       GoTo label1  
   End If  
Else  
label1:  
   answer = «NO»  
End If  
Как минимум две строки лишние и одной недостает(Set s = Nothing).

Я сам — дурнее всякого примера! …

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

вообщето алгоритм можно записать так:  

  Sub t()  
anser = «NO»  
Set s = Range(«a:a»).Find(«конь»)  
If s Is Nothing Then Exit Sub  
If s.Offset(0, 1) = «белый» Then answer = «YES»  
End Sub  

  что короче, яснее и быстрее  

    но я уже приводил на форуме множество раз алгоритмы, с использованием on error goto ( и в паре с ним ще и просто goto) — да, можно сделать по-другому, но так быстрее.. зачем же делать хуже, но без goto ?

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

можно еще так:  

  Sub t()  
on error goto ex  
anser = «NO»  
If Range(«a:a»).Find(«конь»).Offset(0, 1) = «белый» Then answer = «YES»  
ex:End Sub

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

Слэн, Вы читаете, что я пишу?  
«Во всех примерах мэтров программирования goto используется только для определения ошибки, с последующим Exit Sub. То есть goto на выход.»  
И как мое утверждение конфликтует с Вашим: «on error goto»? :-)

Я сам — дурнее всякого примера! …

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

В слове anser буква W пропущена, но это уже флуд. Если честно — боюсь, Диме позавчера спать не давали, оффтопили по полной. Чувствую, психанет и начнет стирать все без разбора. А главное по делу! Хотя этот топик флудом не считаю. Мы, как программеры, обсуждаем целесообразность применения оператора goto.

Я сам — дурнее всякого примера! …

 

Эммм…мммм…а хорошая тема получилось :)  

  Спасибо и за «GoTo» ;)

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

Ну, я бы не был так категоричен, утверждая, что обсуждение целесообразности применения оператора goto в топике с названием «Описание применения «Set»» не является оффтопом…  
Бедный топик-стартер уже давно наверное забросил читать эту тему ввиду распухания головы от развёрнутой здесь продвинутыми программистами дискуссии…

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

Да… А топик-стартер-то, оказывается, ещё не спит, а тему-то просматривает…

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

<но я уже приводил на форуме множество раз алгоритмы, с использованием on error goto ( и в паре с ним еще и просто goto)>  

  вот пример из моего решателя балды: (уж поверьте — оптимизировал-оптимизировал :) )  

  Sub fnd(ByVal s$)  
Dim lens&  
lens = Len(s)  
‘If lens < maxw Then Exit Sub  
Dim arr_r, pos&, n&, k&, sr$  
Dim s_n$, s_e$  
If s = «?êî» Then  
   pos = pos  
End If  
On Error Resume Next  

         pos = InStr(1, s, «?»)  
   s_n = Left(s, pos — 1)  
   s_e = Right(s, lens — pos)  
   ReDim arr_r(1 To 16)  
For k = 1 To 33  
   On Error GoTo er1  
   sr = s_n & arr_abc(k) & s_e  
   If cwt(sr) Then:  
   On Error GoTo n1  
   If chad(sr) = 0 Then GoTo nxt1  
n1: n = n + 1  
   If n > UBound(arr_r) Then ReDim Preserve arr_r(1 To n + 16)  
   arr_r(n) = sr  
   If n > UBound(arr_letter) Then ReDim Preserve arr_letter(1 To n + 99)  
   arr_letter(n) = arr_abc(k)  
   Resume nxt1  
er1: Resume nxt1  
nxt1: Next  
   sr = StrReverse(s)  
   pos = Len(s_e)  
   s_n = Left(sr, pos)  
   s_e = Right(sr, lens — pos — 1)  
On Error GoTo er2  
For k = 1 To 33  
   On Error GoTo er2  
   sr = s_n & arr_abc(k) & s_e  
   If cwt(sr) Then:  
   On Error GoTo n2  
   If chad(sr) = 0 Then GoTo nxt2  
n2:  n = n + 1  
   If n > UBound(arr_r) Then ReDim Preserve arr_r(1 To n + 16)  
   arr_r(n) = sr  
   If n > UBound(arr_letter) Then ReDim Preserve arr_letter(1 To n + 99)  
   arr_letter(n) = arr_abc(k)  
   Resume nxt2  
er2: Resume nxt2  
nxt2: Next  
If n = 0 Then Exit Sub  
‘If lens > maxw + 2 Then  
‘    maxw = lens — 2  
‘    k = 7  
‘    Cells(k, 1).Resize(n, 4).Insert Shift:=xlDown  
‘Else  
   k = Cells(Rows.Count, 1).End(xlUp).Row + 1  
‘End If  
Application.EnableEvents = False  
Cells(k, 1).Resize(n) = Application.Transpose(arr_r)  
Cells(k, 3).Resize(n) = Cells(i, j).Address(0, 0)  
Cells(k, 2).Resize(n) = lens  
Cells(k, 4).Resize(n) = Application.Transpose(arr_letter)  
Application.EnableEvents = True  
numn = numn + n  
numv = numv + 66  
End Sub

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

#30

10.06.2010 15:37:39

To Alex_ST: Ну вот. пришел поручик Ржевский и все опошлил:-)  
При чем тут топикстартер… Я не понимаю:-)

Я сам — дурнее всякого примера! …

I always read that it is recommended to set objects to nothing, once I am done with them. But I normally use them only in functions inside forms.

Isn’t the reference lost and memory released when the function scope is left, regardless of setting objects to Nothing?

i.e. is it really necessary to do:

Set db = Nothing
Set record_set = Nothing

user692942's user avatar

user692942

16.2k7 gold badges78 silver badges173 bronze badges

asked Feb 5, 2009 at 17:47

Ramon's user avatar

VB uses a so-called «reference counting» garbage collector.

Basically, the moment a variable goes out of scope, the reference counter on the referenced object is decremented. When you assign the object reference to another variable, the reference counter is incremented.

When the counter reaches zero, the object is ready for garbage collection. The object resources will be released as soon as this happens. A function local variable will most likely reference an object whose reference count never goes higher than 1, so object resources will be released when the function ends.

Setting a variable to Nothing is the way to decrease the the reference counter explicitly.

For example, you read in a file, and set the file object variable to Nothing right after the ReadAll() call. The file handle will be released immediately, you can take your time process its contents.

If you don’t set to Nothing, the file handle might be open longer than absolutely necessary.

If you are not in a «must unblock valuable resource» kind of situation, simply letting the variables go out of scope is okay.

answered Feb 5, 2009 at 18:22

Tomalak's user avatar

TomalakTomalak

330k66 gold badges523 silver badges623 bronze badges

12

Garbage collection is rarely perfect. Even in .NET there are times where you are strongly encouraged to prompt the system to do garbage collection early.

For this reason, I explicitly both close and set to Nothing recordsets when I’m done with them.

answered Feb 5, 2009 at 18:16

BIBD's user avatar

BIBDBIBD

15k25 gold badges85 silver badges137 bronze badges

5

The very last line of the help topic for «Recordset.Close» in the Microsoft DAO help and the Access Developer Reference is this:

«An alternative to the Close method is
to set the value of an object variable
to Nothing (Set dbsTemp = Nothing).»

http://msdn.microsoft.com/en-us/library/bb243098.aspx

With that in mind, this article from the Microsoft Knowledge Base entitled «How to prevent database bloat after you use Data Access Objects (DAO)», tells you that you should explicitly close if you don’t want your databases to bloat. You’ll notice that the article is a little vague about the details; the «Cause» section is unclear, almost to the point of being gibberish.

http://support.microsoft.com/kb/289562

SYMPTOMS: A Microsoft Access database
has begun to bloat (or grow rapidly in
size) after you implement Data Access
Objects (DAO) to open a recordset.

CAUSE: If you do not release a
recordset’s memory each time that you
loop through the recordset code, DAO
may recompile, using more memory and
increasing the size of the database.

MORE INFORMATION: When you create a
Recordset (or a QueryDef) object in
code, explicitly close the object when
you are finished. Microsoft Access
automatically closes Recordset and
QueryDef objects under most
circumstances. However, if you
explicitly close the object in your
code, you can avoid occasional
instances when the object remains
open.

Finally, let me add that I have been working with Access databases for 15 years, and I almost always let my locally declared recordset variables go out of scope without explicitly using the Close method. I have not done any testing on it, but it does not seem to matter.

answered Feb 5, 2009 at 23:39

Shane Miskin's user avatar

Shane MiskinShane Miskin

1,9132 gold badges22 silver badges30 bronze badges

When you are using ASP classic (server-side scripting), it is important to set all objects to nothing when you are through with them, because they do not go out of scope until the [virtual] server is shut down.

For this reason, all MS VB scripting examples always showed objects being closed and set to nothing. So that the script excerpts could be used in environments like ASP classic where the objects did not go out of scope.

There are, rarely, other situations where you wish to code long-running processes where the objects do not go out of scope, and you find yourself running out of physical memory if you do not explicitly release objects.

If you find yourself coding ASP classic, or running processes in global scope for some other reason, then yes, you should explicitly release objects.

answered Aug 9, 2016 at 12:36

david's user avatar

daviddavid

2,4061 gold badge19 silver badges33 bronze badges

References are supposed to be cleaned up when the variable goes out of scope. Presumably this has improved with later versions of the software, but it was at one time not reliable. I believe that it remains a good practice to explicitly set variables to «Nothing.»

answered Feb 5, 2009 at 17:57

John Mo's user avatar

John MoJohn Mo

1,32610 silver badges14 bronze badges

I usually always put this at the end of my procedures, or call a «CloseRecordSet» sub with it in if I’m using module level ones:

Private Sub Rawr()
On Error GoTo ErrorHandler

    'Procedural Code Here.

    ExitPoint:
        'Closes and Destroys RecordSet Objects.
        If Not Recset Is Nothing Then
            If Recset.State = 1 Then
                Recset.Close
                Conn.Close
            End If
            Set Recset = Nothing
            Set Conn = Nothing
        End If
        Exit Sub

    ErrorHandler:
        'Error Handling / Reporting Here.
        Resume ExitPoint
End Sub

That way however the procedure ends, (be it normally or due to an error) the objects are cleaned up and resources are free.

Doing it that way is quite safe in that it you can just slap it in and it will only do what is necessary in regards to closing, or destroying the recordset / connection object, incase it has already been closed (due to a runtime error or just closing it early as ya should, this just makes sure).

Its really not much hassle and its always best to clean up your objects when you’re finished with them to free up resources immediately regardless of what happens in the program.

answered May 26, 2010 at 15:15

BobT's user avatar

3

Try this

If Not IsEmpty(vMyVariant) Then
    Erase vMyVariant
    vMyVariant = Empty
End If

answered Jan 24, 2013 at 7:51

user2006617's user avatar

Содержание

  1. Is there a need to set Objects to Nothing
  2. 7 Answers 7
  3. When should an Excel VBA variable be killed or set to Nothing?
  4. 3 Answers 3
  5. VBA: Set variable to «Empty» or «Missing»? Handling multiple optional arguments?
  6. 4 Answers 4
  7. VBA: Conditional — Is Nothing
  8. 3 Answers 3
  9. Do nothing in vba
  10. 8 Answers 8
  11. Related
  12. Hot Network Questions
  13. Subscribe to RSS

Is there a need to set Objects to Nothing

I always read that it is recommended to set objects to nothing, once I am done with them. But I normally use them only in functions inside forms.

Isn’t the reference lost and memory released when the function scope is left, regardless of setting objects to Nothing?

i.e. is it really necessary to do:

7 Answers 7

VB uses a so-called «reference counting» garbage collector.

Basically, the moment a variable goes out of scope, the reference counter on the referenced object is decremented. When you assign the object reference to another variable, the reference counter is incremented.

When the counter reaches zero, the object is ready for garbage collection. The object resources will be released as soon as this happens. A function local variable will most likely reference an object whose reference count never goes higher than 1, so object resources will be released when the function ends.

Setting a variable to Nothing is the way to decrease the the reference counter explicitly.

For example, you read in a file, and set the file object variable to Nothing right after the ReadAll() call. The file handle will be released immediately, you can take your time process its contents.

If you don’t set to Nothing , the file handle might be open longer than absolutely necessary.

If you are not in a «must unblock valuable resource» kind of situation, simply letting the variables go out of scope is okay.

Garbage collection is rarely perfect. Even in .NET there are times where you are strongly encouraged to prompt the system to do garbage collection early.

For this reason, I explicitly both close and set to Nothing recordsets when I’m done with them.

The very last line of the help topic for «Recordset.Close» in the Microsoft DAO help and the Access Developer Reference is this:

«An alternative to the Close method is to set the value of an object variable to Nothing (Set dbsTemp = Nothing).»

With that in mind, this article from the Microsoft Knowledge Base entitled «How to prevent database bloat after you use Data Access Objects (DAO)», tells you that you should explicitly close if you don’t want your databases to bloat. You’ll notice that the article is a little vague about the details; the «Cause» section is unclear, almost to the point of being gibberish.

SYMPTOMS: A Microsoft Access database has begun to bloat (or grow rapidly in size) after you implement Data Access Objects (DAO) to open a recordset.

CAUSE: If you do not release a recordset’s memory each time that you loop through the recordset code, DAO may recompile, using more memory and increasing the size of the database.

MORE INFORMATION: When you create a Recordset (or a QueryDef) object in code, explicitly close the object when you are finished. Microsoft Access automatically closes Recordset and QueryDef objects under most circumstances. However, if you explicitly close the object in your code, you can avoid occasional instances when the object remains open.

Finally, let me add that I have been working with Access databases for 15 years, and I almost always let my locally declared recordset variables go out of scope without explicitly using the Close method. I have not done any testing on it, but it does not seem to matter.

Источник

When should an Excel VBA variable be killed or set to Nothing?

I’ve been teaching myself Excel VBA over the last two years, and I have the idea that it is sometimes appropriate to dispose of variables at the end of a code segment. For example, I’ve seen it done in this bit adapted from Ron de Bruin’s code for transferring Excel to HTML:

I’ve done some searching on this and found very little beyond how to do it, and in one forum post a statement that no local variables need to be cleared, since they cease to exist at End Sub . I’m guessing, based on the code above, that may not be true at End Function , or in other circumstances I haven’t encountered.

So my question boils down to this:

  • Is there somewhere on the web that explains the when and why for variable cleanup, and I just have not found it?

And if not can someone here please explain.

  • When is variable cleanup for Excel VBA necessary and when it is not?
  • And more specifically. Are there specific variable uses (public variables? Function-defined variables?) that remain loaded in memory for longer than subs do, and therefor could cause trouble if I don’t clean up after myself?

3 Answers 3

VB6/VBA uses deterministic approach to destoying objects. Each object stores number of references to itself. When the number reaches zero, the object is destroyed.

Object variables are guaranteed to be cleaned (set to Nothing ) when they go out of scope, this decrements the reference counters in their respective objects. No manual action required.

There are only two cases when you want an explicit cleanup:

When you want an object to be destroyed before its variable goes out of scope (e.g., your procedure is going to take long time to execute, and the object holds a resource, so you want to destroy the object as soon as possible to release the resource).

When you have a circular reference between two or more objects.

If objectA stores a references to objectB , and objectB stores a reference to objectA , the two objects will never get destroyed unless you brake the chain by explicitly setting objectA.ReferenceToB = Nothing or objectB.ReferenceToA = Nothing .

The code snippet you show is wrong. No manual cleanup is required. It is even harmful to do a manual cleanup, as it gives you a false sense of more correct code.

If you have a variable at a class level, it will be cleaned/destroyed when the class instance is destructed. You can destroy it earlier if you want (see item 1. ).

If you have a variable at a module level, it will be cleaned/destroyed when your program exits (or, in case of VBA, when the VBA project is reset). You can destroy it earlier if you want (see item 1. ).

Access level of a variable (public vs. private) does not affect its life time.

Источник

VBA: Set variable to «Empty» or «Missing»? Handling multiple optional arguments?

Is it possible, or desirable, to set objects/data to an «Empty» or «Missing» variant? I want to be able to conditionally pass optional arguments to a function. Sometimes I want to use an optional argument, sometimes I don’t.

In Python, you could easily pass through whichever optional arguments you wanted by using **kwdargs to unpack a dictionary or list into your function arguments. Is there something similar (or a way to hack it in VBA) so you can pass in Empty/Missing optional arguments?

In particular, I’m trying to use Application.Run with an arbitrary number of arguments.

EDIT:

I’m basically trying to do this:

Because the number of arguments changes for each function call, what is the acceptable way to make sure the right number of inputs are input into Application.Run?

The equivalent Python code would be

4 Answers 4

in VBA you use ParamArray to enter option inputs to functions.

There are two ways in which a routine can change the number of arguments that has to be provided to it:

  • declare some of the trailing arguments as Optional
  • declare the last argument as ParamArray

A single routine can use either or both.

An Optional parameter may have a strict type (e.g. Optional s As String ), but then it will be impossible to detect whether it was passed. If you don’t pass a value for such argument, the correct flavour of «blank» will be used, which is indistinguishable from passing that blank value manually.
So, having Public Sub Bob(Optional S As String) , you cannot detect from inside of Bob whether it was called as Bob or as Bob vbNullString .
An optional parameter may have a default value, which suffers from the same problem. So, having Public Sub Bob(Optional S As String = «Default Value») , you cannot detect if Bob was called as Bob or as Bob «Default Value» .

To be able to truly detect whether an optional parameter was passed, they have to be typed as Variant . Then a special function, IsMissing , can be used inside the routine to detect if a parameter was passed.

ParamArray can only be the last argument, and it allows an infinite* number of arguments to be passed starting from this position. All these arguments arrive packed in a single Variant array (no option for static typing here).

The IsMissing function does not work on the ParamArray argument (always returns False). The way to know how many arguments were passed is to compare UBound(args) with LBound(args) . Note that this only tells you how many argument «slots» were used, but some of them can be in fact missing!

Note that you cannot pass «missing» value for the trailing arguments of the ParamArray , i.e. this is illegal:

However, you can work around this using the trick described below.

An interesting use case that you touch in your question is preparing an array of all arguments in advance, passing it to the function, filling all the arguments «placeholders», but still expecting the function to detect that some of the arguments are missing (not passed).

Normally this is not possible, because if anything is passed (even «blank» values, such as Empty , Null , Nothing of vbNullString ), then it still counts as passed, and IsMissing() will return False .

Fortunately, the special Missing value is nothing but a specially constructed Variant , and even without knowing how to construct that value manually, we can trick the compiler to give it away:

Now, we can work around the inability to pass «missing» to the trailing «slots» of ParamArray :

Note, however, that this workaround will only work if you call BobArray directly. If you use Application.Run , it will not work because the Run method will discard any trailing «missing» arguments before passing them onto the called routine:

Further to @GSerg’s very comprehensive answer (I don’t have enough reputation just to comment), the ‘special’ value assigned to a Missing argument has the ‘appearance’ of being an Error value — it converts to «Error 448» (Named argument not found) using CStr() , and responds to IsError() as TRUE . However, an attempt to preset the argument using CvErr(448) before passing to a procedure (in the hope that it will be recognised as Missing) fails, perhaps because the value is ‘not quite’ the same as the Error value in some way.

@GSerg suggested a method of ‘recording’ the value actually passed by the compiler when an argument is missing and using that to preset a dummy argument prior to passing to the procedure needing to be fooled. This method, indeed, does work and I have simply extended @GSerg’s function to replace his error message (if it is inadvertently called with an argument) by a recursive call without an argument which ensures a successful outcome either way. Usage is simply to preset the dummy variable(s) before passing to a procedure (where it/they will then be treated as missing): Dummy_Var = Missing() .

Источник

VBA: Conditional — Is Nothing

There is an If condition in a VBA application as seen below:

When the code is run in debug mode, I found that the If condition returns a true even when My_Object has «No Variables».

Could somebody please explain this? I want My_Object.Compute to be executed only when My_Object exists.

3 Answers 3

Based on your comment to Issun:

Thanks for the explanation. In my case, The object is declared and created prior to the If condition. So, How do I use If condition to check for ? In other words, I do not want to execute My_Object.Compute if My_Object has

You need to check one of the properties of the object. Without telling us what the object is, we cannot help you.

I did test several common objects and found that an instantiated Collection with no items added shows in the watch window. If your object is indeed a collection, you can check for the condition using the .Count property:

It is also worth noting that if you declare any object As New then the Is Nothing check becomes useless. The reason is that when you declare an object As New then it gets created automatically when it is first called, even if the first time you call it is to see if it exists!

This does not seem to be the cause of your specific problem. But, since others may find this question through a Google search, I wanted to include it because it is a common beginner mistake.

Источник

Do nothing in vba

Is there an equivalent to python «pass» in VBA to simply do nothing in the code?

I get an error here that pass is not defined. Thanks.

8 Answers 8

just remove pass and re run the code. VBA will be happy to accept that I believe

Don’t include any statements:

Just leave it blank. You can also use a Select statement, it’s easier to read.

Write code that does what it says, and says what it does.

That’s all you need. An instruction that means «here’s some useless code» does not exist in VBA.

You want comments that say why, not what — a comment that says ‘do nothing is the exact opposite of that. Don’t write no-op code, it’s pure noise.

Assuming Python’s pass works like C#’s continue statement and skips to the next iteration, then the VBA equivalent is the one and only legitimate use of a GoTo jump:

This code shows an IF test that keeps searching unless it gets a match.

I coded in COBOL for many years and the equivalent ‘do nothing’ statement is NEXT SENTENCE .

In VBA, I find myself creating a dummy variable (sometimes a global) dim dummy as integer and then when I need that ‘do nothing’ action in an If..Then..Else I put in a line of code: dummy = 0 .

This is actually a legit question. I want to run a debug routine that stops when a certain critical value is, say, 8, i.e., set break point at x = 8 and then step through line by line. So the following construct is useful:

  • Since you can’t put a break point on a comment, an actual statement is needed.
  • You also can’t put a break point on the Case statements because that gets executed every time.

Obviously anything here is OK e.g., x=x , but it would be nice to have something formal like pass .

But I’ve been using x=x .

Most languages have a «null» or «empty» statement like Python’s pass . These statements have evolved because they are practically useful, and in some grammars, necessary. For example, as others have suggested, null statements can serve as side-effect free anchors for a debugger.

Note that if your use case is to set a conditional breakpoint, you may find Stop more useful, as in:

Hot Network Questions

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.3.20.43331

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

  • #1

Hello all! This is a «best practice» sort of question for you fellow programmers out there.

Is it necessary to always set object variables to Nothing at the end of a procedure?

In a procedure where any sort of object variable is declared, I always make a habit of setting the object to nothing at the end of the procedure. An example:

Code:

Public Sub sampleProcedure()
  Dim wks As Worksheet
  Dim rng As Range
  Dim dct As Scripting.Dictionary

    Set wks = ThisWorkbook.Worksheets("Sheet1")
    Set rng = wks.Range("A1")
    set dct = New Scripting.Dictionary

    '«BRILLIANT AUTOMATION PROGRAMMING HERE»

HANDLER_EXIT:
    Set wks = Nothing
    Set rng = Nothing
    set dct = Nothing

    Exit Sub

HANDLER_ERROR_SOMETHING1:
    '«BRILLIANT ERROR HANDLING HERE»

HANDLER_ERROR_SOMETHING2:
    '«BRILLIANT ERROR HANDLING HERE»

End Sub

I do this to make certain that the memory is being released for that particular variable. Doesn’t matter if it is a range, worksheet, collection, or some wild class object… I always set it to Nothing.

Am I being OCD or is this a valid concern?

Excel Joke

Why can’t spreadsheets drive cars? They crash too often!

  • #2

I think you only need to set variables declared as objects to nothing. This should be done in the reverse order of their setting (ie. the last object set should be the 1st object set to nothing). I’ll see if I can find a link to some real feedback. Also, your 1st error handler should exit sub before the next error handler routine. Dave

  • #3

VBA has its own garbage collector so I’m not really sure you are doing something strictly worthwhile (although it’s good practice for languages where this really matters). At worst it costs you the time to apply a few key strokes :)

shg

shg

MrExcel MVP


  • #4

I think there are some corner cases where it’s necessary when you’ve done something so complicated that VBA’a reference counting fails, but in general, it’s unnecessary defensive programming that clutters your code. Variables of all types are destroyed when they go out of scope.

  • #5

I’m certain that there are situations that warrant such behavior, especially in cases where variable scope may exist outside the procedure. It’s good to know that it isn’t EXPLICITLY necessary, however. I’ll be happy to unclutter my programming.

A fine discussion, thank you all for sharing!

Also, good catch NdNoviceHlp. Fortunately this was fluff I threw up here to visualize my madness. ;)

  • #7

That looked more like support for not setting objects to Nothing because then you avoid the possibility of orphaning them by doing it in the wrong sequence!

  • #8

Interesting. Maybe we could use a bit more learning if anyone else has a preference that they would like to share. I would prefer to ignore the whole business if it were possible. I’m guessing it’s not nb until your wb gets large…. which makes it hard to prove/disprove. Dave

shg

shg

MrExcel MVP


  • #9

I’m certain that there are situations that warrant such behavior, especially in cases where variable scope may exist outside the procedure.

When variables are more broadly scoped, it is frequently for the very reason that you want them to persist.

I’d never say never, but have personally never had occasion to believe it was necessary or appropriate.

  • #10

Generally not necessary. :) If you look at my code you will see I do it anyway with most non-Excel objects, but not because I need to. I think the only exception I know of is DAO objects (and even that may be out of date). VBA is basically very good about «garbage collection» and, well, let’s face it, memory is cheap and plentiful these days.

Excel VBA — Empty, ZLS, Null, Nothing, Missing

————————————

Contents:

Empty

VarType Function

Null

Nothing

Missing

————————————

In excel vba we often refer to an Empty variable, ZLS (zero-length string) or null string or vbNullString, Null value, Missing Argument, or using the Nothing keyword with an object variable. It is important to differentiate and understand these terms and expressions while using them in your vba code. In this section, we will also understand using the VarType Function to determine the subtype of a variable, using the IsEmpty & IsNull Functions to check for Empty & Null values, and using the IsMissing Function to check whether optional arguments have been passed in the procedure or not.

Empty

When you declare a variable in your code using a Dim statement, you are setting aside sufficient memory for the variable (viz. 2 bytes for a Boolean or Integer variable, 4 bytes for a Long variable, and so on), and that the information being stored in the variable has an allowable range (of True or False  for a Boolean variable, a whole number between -32,768 to 32,767  for an Integer variable, a whole number between -2,147,483,648 to 2,147,483,647 for a variable subtype of Long, and so on). You will receive a run-time error if trying to assign a string value to a variable declared as Integer.

While declaring a variable if you do not specify its data type, or if you do not declare a variable at all it will default to Variant data type that can hold any type of data (string, date, time, Boolean, or numeric values) & can automatically convert the values that it contains. However, the disadvantage is that this makes Excel reserve more memory than is required (at least 16 bytes), and could also result in mistyping a variable name and not knowing it viz. you might type rowNumbre instead of rowNumber.

When you run a macro, all variables are initialized to a default value. The initial default value: for a numeric variable is zero; for a variable length string it is a zero-length or empty string («»); a fixed length string is initialized with the ASCII code 0, or Chr(0); an object variable defaults to Nothing; a Variant variable is initialized to Empty. In numeric context, an Empty variable denotes a zero while in a string context an Empty variable is a zero-length string («») . A zero-length string («») is also referred to as a null string. However, it is advised to explicitly specify an initial value for a variable instead of relying on its default initial value.

Empty indicates that no beginning value has been assigned to a Variant variable ie. a variable which has not been initialized. An Empty variable is represented as 0 in a numeric context or a zero-length string («») in a string context. Empty is not the same as Null which indicates that a variable contains no valid data.

The Empty keyword indicates an uninitialized variable value. It is used as a Variant subtype. You can assign the Empty keyword to explicitly set a variable to Empty.

IsEmpty Function

Use the IsEmpty Function to check whether a variable has been initialized. The function returns a Boolean value — returns True for an uninitialized variable or if a variable is explicitly set to Empty, otherwise the function returns False. Syntax: IsEmpty(expression), where expression is a Variant variable which you want to check. See below example(s) where we use this function to check if a variant variable is empty.

Empty, Blank, ZLS (zero-length string), null string & vbNullString

ZLS means a zero-length string («»), is also referred to as a null string, and has a length of zero (0). For all practical purposes using vbNullString is equivalent to a zero-length string («») because VBA interprets both in a similar manner, though both are actually not the same — a ‘zero length string’ actually means creating a string with no characters, whereas  vbNullString is a constant used for a null pointer meaning that no string is created and is also more efficient or faster to execute than ZLS. You can use «» or vbNullString alternatively in your code and both behave similarly. Note that there is no Blank keyword in vba, but we can refer to ‘blank cells‘ or «empty cells» in Excel spreadsheet. There are Excel worksheet functions for empty cells: (i) the COUNTA function counts the number of cells that are not empty, and also counts or includes a cell with empty text («») — also referrred to as empty string or zero length string — which is not counted as an empty cell; and (ii) the ISBLANK function returns True for an empty cell, and does not treat a zero-length string («») as a blank (empty cell) similarly as in COUNTA. Both the worksheet functions of ISBLANK and COUNTA distinguish between an empty cell and a cell containing a zero-length string (ie. «» as formula result).

VarType Function

Use the VarType Function to determine the subtype of a variable. Syntax: VarType(variable_name). The function returns an Integer indicating the variable’s subtype. The variable_name can be any variable except a user-defined data type (data type defined using the Type statement) variable. Examples of return values are: value 0 (VarType constant — vbEmpty, uninitialized / default), value 1 (VarType constant — vbNull, contains no valid data), value 2 (VarType constant — vbInteger, Integer), value 3 (VarType constant — vbLong, Long Integer), and so on. The VarType constants can be used anywhere in your code in place of the actual values.

Example — Empty variable:

Sub EmptyVar()
‘Empty variable

‘variable var1 has not been declared, hence it is a Variant data type:

‘returns 0, indicating variable subtype Empty:

MsgBox VarType(var1)

‘returns True, indicating variable subtype Empty:

MsgBox IsEmpty(var1)

‘returns False — is an Empty variable, not a Null variable — no beginning value has been assigned to a Variant variable:

MsgBox IsNull(var1)

‘Empty indicates a Variant variable for which you do not explicity specify an initial value, which by default gets initialized in VBA to a value that is represented as both a zero and a zero-length string.

‘returns both messages as below:

If var1 = 0 Then

MsgBox «Empty Variable represented as Zero»

End If

If var1 = «» Then

MsgBox «Empty Variable represented as a Zero-Length (Null) String»

End If

End Sub

Example — Testing for Empty:

Sub EmptyCheck()
‘testing for Empty

Dim var1 As Variant

‘variable not initialized — returns 0, indicating variable subtype Empty:

MsgBox VarType(var1)

‘returns True, indicating variable subtype Empty:

MsgBox IsEmpty(var1)

‘————

‘initialize the variable by specifying a string value:

var1 = «Hello»

‘returns 8, indicating variable subtype String:

MsgBox VarType(var1)

‘returns False, indicating variable is not Empty:

MsgBox IsEmpty(var1)

‘————

‘assign Empty keyword to set variable to Empty:

var1 = Empty

‘returns 0, indicating variable subtype Empty:

MsgBox VarType(var1)

‘returns True, indicating variable is Empty:

MsgBox IsEmpty(var1)

‘————

‘returns True for an empty worksheet cell, otherwise False:

MsgBox IsEmpty(ActiveCell)

End Sub

Example — Initialize a Variant variable:

Sub VarInitialized()
‘initialized variable

Dim var1 As Variant

‘variable has been initialized to a zero-length string («»):

var1 = «»

‘returns False, indicating variable is NOT Empty:

MsgBox IsEmpty(var1)

‘returns 8, indicating variable subtype String:

MsgBox VarType(var1)

‘returns — «Variable value is a Zero-Length String»

If var1 = «» Then

MsgBox «Variable value is a Zero-Length String»

Else

MsgBox «Variable value is NOT a Zero-Length String»

End If

‘returns — «Variable value is NOT Zero»

If var1 = 0 Then

MsgBox «Variable value is Zero»

Else

MsgBox «Variable value is NOT Zero»

End If

End Sub

Example — Check a zero-length string:

Sub CheckZLS()
‘check a zero-length string

Dim var1 As Variant

‘variable not initialized — returns 0, indicating variable subtype Empty — represented both as Zero (0) and a Zero-Length (Null) String:

MsgBox VarType(var1)

‘returns «True» for all If statements below:

If var1 = «» Then

MsgBox «True»

End If

If var1 = vbNullString Then

MsgBox «True»

End If

If Len(var1) = 0 Then

MsgBox «True»

End If

End Sub

Null

In VBA, Null keyword is used to indicate that a variable contains no valid data. A value indicating that a variable contains no valid data. Null is the result — (i) if you explicitly assign Null to a variable, or (ii) if you perform any operation between expressions that contain Null. The Null keyword is used as a Variant subtype ie. only a Variant variable can be Null, and and variable of any other subtype will give an error. Null is not the same as a zero-length string («»), and neither is Null the same as Empty, which indicates that a variable has not yet been initialized.

If you try to get the value of a Null variable or an expression that is Null, you will get an  error of ‘Invalid use of Null’ (Run-time Error 94). You will need to ensure the variable contains a valid value. Refer Image 1.

IsNull Function

The IsNull Function returns a Boolean value — True for an expression that is Null (containing no valid data), or else False for an expression that contains valid data. Syntax: IsNull(expression). The expression argument is a variant that contains a numeric or string value, and is necessary to specify.

Example — Integer variable:

Sub VarInteger()
‘no beginning value assigned to a variable of subtype Integer

Dim intVar As Integer

‘returns False (intVar is not Null & neither is it Empty) — no beginning value has been assigned to a variable of subtype Integer:

MsgBox IsNull(intVar)

‘returns 2, indicating variable subtype Integer:

MsgBox VarType(intVar)

‘returns — «Variable value is Zero» (The initial default value for a numeric variable is zero)

If intVar = 0 Then

MsgBox «Variable value is Zero»

Else

MsgBox «Variable value is NOT Zero»

End If

End Sub

Example — Evaluate Empty / Null variable, use IsNull & VarType vba functions:

Sub EmptyNullVar()
‘evaluate Empty / Null variable, use IsNull & VarType vba functions.

Dim var1 As Variant

‘returns False, var1 is not Null but an Empty variable (no beginning value has been assigned to a Variant variable):

MsgBox IsNull(var1)

‘variable not initialized — returns 0, indicating variable subtype Empty:

MsgBox VarType(var1)

‘returns the message because var1 is an Empty variable:

If var1 = 0 And var1 = vbNullString Then

MsgBox «Empty Variable represented both as Zero (0) and a Zero-Length (Null) String»

End If

‘——————-

‘variable is initialized to a zero-length string («») or vbNullString:

var1 = vbNullString

‘returns False — var1 is not a Null variable:

MsgBox IsNull(var1)

‘returns 8, indicating variable subtype String:

MsgBox VarType(var1)

‘——————-

‘explicitly assigning Null to a variable:

var1 = Null

‘returns True, for a Null variable, containing no valid data:

MsgBox IsNull(var1)

‘returns 1, indicating variable subtype Null:

MsgBox VarType(var1)

‘——————-

‘explicitly assigning valid data to a variable:

var1 = 12

‘returns False, for a variable containing valid data:

MsgBox IsNull(var1)

‘returns 2, indicating variable subtype Integer:

MsgBox VarType(var1)

‘——————-

‘returns False, for an expression containing valid data:

MsgBox IsNull(«Hello»)

End Sub

Example — Check a Null variable:

Sub CheckNull()
‘check a Null variable

‘explicitly assigning Null to a variable:

var1 = Null

‘returns 1, indicating variable subtype Null:

MsgBox VarType(var1)

‘returns the message, indicating variable subtype Null:

If VarType(var1) = vbNull Then

MsgBox «Null variable»

End If

‘an expression containing Null also evaluates to Null:

var2 = Null + 2

‘returns 1, indicating variable subtype Null:

MsgBox VarType(var2)

End Sub

Example — Check worksheet cell for Empty, ZLS, Null:

Sub WorksheetCell_ZLS_Empty_Null()
‘check worksheet cell for Empty, ZLS, Null

Dim var1 As Variant

‘returns True:

MsgBox vbNullString = «»

‘In the case where ActiveCell is Blank:

‘returns True for a Blank cell:

MsgBox ActiveCell.Value = «»

MsgBox ActiveCell.Value = vbNullString

MsgBox ActiveCell.Value = 0

MsgBox IsEmpty(ActiveCell.Value)

‘assign Active Cell value to variable:

var1 = ActiveCell.Value

‘returns True:

MsgBox IsEmpty(var1)

MsgBox var1 = vbNullString

MsgBox var1 = «»

MsgBox var1 = 0

‘returns False:

MsgBox VarType(var1) = vbNull

‘returns 0, indicating variable subtype Empty:

MsgBox VarType(var1)

‘If you enter «» in the Active Cell ie. the active cell contains the value: =«»
‘returns True:

MsgBox ActiveCell.Value = «»

MsgBox ActiveCell.Value = vbNullString

‘returns False:

MsgBox ActiveCell.Value = 0

MsgBox IsEmpty(ActiveCell.Value)

End Sub

Nothing

Assigning the Nothing keyword to an object variable disassociates the variable from an actual object. Nothing is assigned to an object variable by using the Set statement. You can assign the same actual object to multiple object variables in vba code, and this association uses your system resources and memory. The system resources and memory get released only either after you assign Nothing to all object variables using the Set statement which disassociates these variables from the actual object, or when all object variables go out of scope and get destroyed. It is advisable to explicity set all object variables to Nothing at the end of your procedure or even earlier while running your code when you finish using them, and this will release memory allocated to these variables.

Determine if the object variable is initialized — use Is Nothing for objects: To check if an object has been assigned or set, use the Is keyword with Nothing, viz. If object_variable Is Nothing. For objects, you cannot test if an object_variable is equal to something, and using = instead of Is will give an error.

Example — Using the Nothing keyword with an object variable:

Sub ObjNothing()
‘using the Nothing keyword with an object variable

Dim objVar As Object

‘returns True, because you have not yet assigned an actual object to the object variable:

MsgBox objVar Is Nothing

Set objVar = ActiveSheet

‘returns False, because you have assigned an actual object (Sheet) to the object variable:

MsgBox objVar Is Nothing

Set objVar = Nothing

‘returns «Variable not associated with an actual object», because you have disassociated the object variable from an actual object:

If objVar Is Nothing Then

MsgBox «Variable not associated with an actual object»

Else

MsgBox «Actual object is assigned to an Object variable»

End If

End Sub

Missing

Passing Arguments to Procedures: When an external value is to be used by a procedure to perform an action, it is passed to the procedure by variables. These variables which are passed to a procedure are called arguments. An argument is the value supplied by the calling code to a procedure when it is called. When the set of parentheses, after the procedure name in the Sub or Function declaration statement, is empty, it is a case when the procedure does not receive arguments. However, when arguments are passed to a procedure from other procedures, then these are listed or declared between the parentheses.

Optional Arguments: Arguments can be specified as Optional by using the Optional keyword before the argument to its left. When you specify an argument as Optional, all other arguments following that argument to its right must

also be specified as Optional. Note that specifying the Optional keyword makes an argument optional otherwise the argument will be required.

Check if an argument is Missing, using the IsMissing function: The Optional argument should be (though not necessary) declared as Variant data type to enable use of the IsMissing function which works only when used with variables declared as Variant data type. The IsMissing function is used to determine whether the optional argument was passed in the procedure or not and then you can adjust your code accordingly without returning an error. If the Optional argument is not declared as Variant in which case the IsMissing function will not work, the Optional argument will be assigned the default value for its data type which is 0 for numeric data type variables (viz. Integer, Double, etc) and Nothing (a null reference) for String or Object data type variables.

IsMissing function: The IsMissing function is used to check whether optional Variant arguments have been passed in the procedure or not. Syntax: IsMissing(argname). The function returns a Boolean value — True if no value is passed for the optional argument, and False if a value has been passed for the optional argument. If the IsMissing function returns True for an argument, using the missing argument in the code will cause an error, and thus using this function will help in adjusting your code accordingly.

Example of using the IsMissing function to check if an argument is Missing:

Function FullName(strFirstName As String, Optional strSecondName As Variant) As String
‘The declaration of the procedure contains two arguments, the second argument is specified as Optional. Declaring the Optional argument as Variant data type will enable use of the IsMissing function.

‘The IsMissing function is used to determine whether the optional argument was passed in the procedure, and if not, you can adjust your code accordingly without returning an error.

If IsMissing(strSecondName) Then

FullName = strFirstName

Else

FullName = strFirstName & » « & strSecondName

End If

End Function

Sub GetName()

Dim strGivenName As String

strGivenName = InputBox(«Enter Given Name»)

‘specifying only the first argument & omitting the second argument which is optional:

MsgBox FullName(strGivenName)

End Sub

Понравилась статья? Поделить с друзьями:
  • Set macro in excel
  • Service times at the word church
  • Set hyperlink in word
  • Service is just a word
  • Set headers in word