Dim as integer excel

Хитрости »

1 Май 2011              225354 просмотров


Что такое переменная и как правильно её объявить?

Переменная — это некий контейнер, в котором VBA хранит данные. Если подробнее, то это как коробочка, в которую Вы можете положить что-то на хранение, а затем по мере необходимости достать. Только в данном случае в переменной мы храним число, строку или иные данные, которые затем можем извлекать из неё и использовать в коде по мере необходимости.

Для чего нужна переменная? Чтобы хранить значение и применить его позже в любой момент. Например, в ячейке А1 записана сумма, а нажатием на кнопку запускается обновление отчета. После обновления отчета сумма в А1 изменится. Необходимо сверить сумму до обновления с суммой после и в зависимости от этого сделать какое-либо действие. Переменная как раз позволит запомнить значение ячейки до того, как она обновится и использовать именно это значение после обновления.


  • Требования к переменным
  • Типы данных, хранимых в переменных
  • Как объявлять переменные
  • Как правильно назвать переменную
  • Пример использования переменных
  • Константы

В качестве имен переменных можно использовать символы букв и числа, но первой в имени переменной всегда должна быть буква. Не допускается использование точки, запятой, пробела и иных знаков препинания, кроме нижнего подчеркивания. Длина имени не должна превышать 254 символов. Так же нельзя использовать в качестве имен для переменных зарезервированные константы редактора VBA(например Sub, Msgbox, ubound, Date и т.п.). Так же для переменных неважен регистр букв.

 
Теперь рассмотрим основные декларированные в VBA

типы данных, которые можно хранить в переменных:

Тип данных Занимает байт в памяти Пределы значений
Byte 1 Целые числа от 0 до 255
Boolean 2 True или False
Integer 2 Целые числа от (-32768) до 32767
Long 4 Целые числа от (-2147483648) до 2147483647
Single 4 От (–3.402823Е+38) до (–1.401298Е-45) и от 1.401298Е-45 до 3.402823Е+38
Double 8 От ±1.79769313486232Е+308 до ±4.94065645841247Е-324
Decimal 12 От ±79228162514264337593543950335 без десятичных знаков до ±7,9228162514264337593543950335 с 28-ю знаками после запятой
Currency 8 От (–922337203685477.5808) до 922337203685477.5807
Date 8 От 01.01.100 до 31.12.9999(не надо путать с датами в Excel — 01.01.1900 до 31.12.9999)
String 10(+длина строки) От 0 до 65400 символов для фиксированных строк и чуть более 2 млрд. для строк переменной длины
Object 4 Любой объект
Array Определяется кол-вом и размером элементов
Variant от 16-ти Любой из встроенных типов данных

Как видно из таблицы больше всего памяти занимает Variant. Притом это если он хранит числовые данные. Если же такая переменная будет хранить данные строкового типа(текст), то размер занимаемой памяти будет измеряться уже начиная с 22 байт + длина строки, хранящейся в переменной. Чем больше памяти занимает переменная, тем дольше она инициализируется в памяти и тем медленнее код будет выполняться. Вот поэтому и важно явно задавать тип данных, хранимых в переменной — это называется объявить переменную.

Тип данных Decimal больше не используется, поэтому объявить переменную данного типа в VBA не получится — подобная попытка приведет к синтаксической ошибке. Для работы с данными типа Decimal переменную необходимо изначально объявить как Variant или вообще без типа (например Dim a), т.к. тип данных Variant используется в VBA по умолчанию и принимает любой тип данных.

Так же переменным можно назначать и другие типы данных, которых нет в таблице выше — это типы, которые поддерживаются объектной моделью приложений, к которым «подключен» VBA. Например, если зайти в VBA из Excel, то библиотека типов объектной модели Excel подключена по умолчанию и для переменных становится доступно множество типов этой объектной модели. Многие из них знакомы всем: Workbook, Worksheet, Range, Cells, Chart и т.д. Т.е. это книги, листы, ячейки, диаграммы. Типов много, почти на каждый объект и коллекцию. Рассматривать здесь все бессмысленно. Могу лишь привести пару строк кода:

Dim rRange as Range 'назначили переменной тип ячейка/диапазон
Set rRange = Range("A1") 'присвоили ссылку на ячейку A1 текущего листа

Про объявление переменных подробно написано чуть ниже.
А более подробно про обращение к диапазонам из VBA можно почитать в этой статье: Как обратиться к диапазону из VBA

как объявлять переменные

На самом деле все очень просто. Это делается при помощи операторов области действия: Dim, Public,Static и оператора присвоения типа As. Самый распространенный оператор — Dim. Его и возьмем в качестве примера. Синтаксис объявления:

[оператор области действия] Имя_переменной As [тип данных]

Очень частая ошибка при объявлении переменных, совершаемая начинающими изучать VBA:

Dim MyVar1, MyVar2, MyVar3 As Integer

Вроде бы исходя из логики всем переменным присвоен тип данных Integer. Но это ошибочное суждение. Тип Integer присвоен только последней переменной, к которой он «привязан» оператором AsMyVar3. Все остальные переменные имеют тип данных Variant. Т.е. если Вы не задаете каждой переменной свой тип хранимых данных явно(т.е. не указываете для неё тип данных через As), то VBA сам присваивает для такой переменной тип данных Variant, т.к. он может хранить любой тип данных. А вот так выглядит правильное присвоение типа данных:

Dim MyVar1 As Integer, MyVar2 As Integer, MyVar3 As Integer

Это и есть объявление переменных. Т.е. сначала идет оператор области действия (Dim, Public,Static), сразу за ним имя переменной, затем оператор As и тип.
Но это не все. Некоторые типы переменным можно присваивать еще короче — даже без оператора As:

Dim MyVar1%, MyVar2%, MyVar3%

Всего шесть типов, которые можно объявить подобным методом:
! — Single
# — Double
$ — String
% — Integer
& — Long
@ — Currency
На что стоит обратить внимание, при объявлении переменных подобным образом: между именем переменной и знаком типа не должно быть пробелов.
Я лично в большинстве статей предпочитаю использовать первый метод, т.е. полное указание типа. Это читабельнее и понятнее. В каких-то проектах могу использовать краткое указание, в общих(разработка в команде) — полное. В своих кодах Вы вправе использовать удобный Вам метод — ошибки не будет.

Теперь разберемся с операторами области действия(Dim, Public и Static):

  • Dim — данный оператор используется для объявления переменной, значение которой будет храниться только в той процедуре, внутри которой данная переменная объявлена. Во время запуска процедуры такая переменная инициализируется в памяти и использовать её значение можно внутри только этой процедуры, а по завершению процедуры переменная выгружается из памяти(обнуляется) и данные по ней теряются. Переменную, объявленную подобным образом еще называют локальной переменной. Однако с помощью данного оператора можно объявить переменную, которая будет доступна в любой процедуре модуля. Необходимо объявить переменную вне процедуры — в области объявлений(читать как первой строкой в модуле, после строк объявлений типа — Option Explicit). Тогда значение переменной будет доступно в любой процедуре лишь того модуля, в котором данная переменная была объявлена. Такие переменные называются переменными уровня модуля. Также для использования переменных во всех процедурах и функциях одного конкретного модуля можно использовать оператор Private. Но он в данном случае ничем не отличается от Dim, а пишется длиннее :) Плюс, Private нельзя использовать внутри процедуры или функции(только в области объявлений), что еще больше сужает её применимость. По сути чаще этот оператор применяется к функциям и процедурам(об этом см.ниже)
  • Static — данный оператор используется для объявления переменной, значение которой предполагается использовать внутри конкретной процедуры, но не теряя значения данной переменной по завершении процедуры. Переменные данного типа обычно используют в качестве накопительных счетчиков. Такая переменная инициализируется в памяти при первом запуске процедуры, в которой она объявлена. По завершении процедуры данные по переменной не выгружаются из памяти, но однако они не доступны в других процедурах. Как только Вы запустите процедуру с этой переменной еще раз — данные по такой переменной будут доступны в том виде, в котором были до завершения процедуры. Выгружается из памяти такая переменная только после закрытия проекта(книги с кодом).
  • Public — данный оператор используется для объявления переменной, значение которой будет доступно в любой процедуре проекта(в обычных модулях, модулях класса, модулях форм, модулях листов и книг). Переменная, объявленная подобным образом, должна быть объявлена вне процедуры — в области объявлений. Такая переменная загружается в память во время загрузки проекта(при открытии книги) и хранит значение до выгрузки проекта(закрытия книги). Использовать её можно в любом модуле и любой процедуре проекта. Важно: объявлять подобным образом переменную необходимо строго в стандартном модуле. Такие переменные называются переменными уровня проекта. В простонародье такие переменные еще называют глобальными(возможно из-за того, что раньше подобные переменные объявлялись при помощи оператора Global, который в настоящее время устарел и не используется).
    Для большего понимания того, где и как объявлять переменные уровня проекта два небольших примера.
    Неправильное объявление

    Option Explicit
     
    Sub main()
    Public MyVariable As String
    MyVariable = "Глобальная переменная"
    'показываем текущее значение переменной
    MsgBox MyVariable
    'пробуем изменить значение переменной
    Call sub_main
    'показываем измененное значение переменной
    MsgBox MyVariable
    End Sub
    'доп.процедура изменения значения переменной
    Sub ChangeMyVariable()
    MyVariable = "Изменили её значение"
    End Sub

    переменные не будут видны во всех модулях всех процедур и функций проекта, потому что:
    1. Оператор Public недопустим внутри процедуры(между Sub и End Sub), поэтому VBA при попытке выполнения такой процедуры обязательно выдаст ошибку — Invalid Attribut in Sub or Function.
    2. Даже если Public заменить на Dim — это уже будет переменная уровня процедуры и для других процедур будет недоступна.
    3. Т.к. объявление неверное — вторая процедура(ChangeMyVariable) ничего не знает о переменной MyVariable и естественно, не сможет изменить именно её.
    Правильное объявление

    'выше глобальных переменных и констант могут быть только декларации:
    Option Explicit     'принудительное объявление переменных
    Option Base 1       'нижняя граница объявляемых массивов начинается с 1
    Option Compare Text 'сравнение текста без учета регистра
    'глобальная переменная - первой строкой, выше всех процедур
    Public MyVariable As String
    'далее процедуры и функции
    Sub main()
        MyVariable = "Глобальная переменная"
        'показываем текущее значение переменной
        MsgBox MyVariable, vbInformation, "www.excel-vba.ru"
        'пробуем изменить значение переменной
        Call ChangeMyVariable
        'показываем измененное значение переменной
        MsgBox MyVariable, vbInformation, "www.excel-vba.ru"
    End Sub
    'доп.процедура изменения значения переменной
    Sub ChangeMyVariable()
        MyVariable = "Изменили её значение"
    End Sub

    Если при этом вместо Public записать Dim, то эта переменная будет доступна из всех функций и процедур того модуля, в котором записана, но недоступна для функций и процедур других модулей.
    Переменные уровня проекта невозможно объявить внутри модулей классов(ClassModule, ЭтаКнига(ThisWorkbook), модулей листов, модулей форм(UserForm) — подробнее про типы модулей: Что такое модуль? Какие бывают модули?)

  • Операторы области действия так же могут применяться и к процедурам. Для процедур доступен еще один оператор области действия — Private. Объявленная подобным образом процедура доступна только из того модуля, в котором записана и такая процедура не видна в диалоговом окне вызова макросов(Alt+F8)
  • 'процедура записана в Module1
    'эта процедура будет доступна для вызова исключительно из процедур в этом же модуле
    'но не будет доступна при вызове из других модулей
    Private Sub PrivateMain()
        MsgBox "Процедура может быть вызвана только из модуля, в котором записана", vbInformation, "www.excel-vba.ru"
    End Sub
    'другая процедура, записанная в этом же модуле
    Sub CallPrivate()
        Call PrivateMain
    End Sub
    'эта процедура записана в другом модуле - Module2
    'при попытке вызова этой процедурой получим ошибку
    ' Sub or Function not defined
    ' потому что процедура PrivateMain объявлена только для Module1
    Sub CallPrivate_FromModule1()
        Call PrivateMain
    End Sub

    При этом, если из Excel нажать сочетание клавиш Alt+F8, то в окне будут доступны только CallPrivate_FromModule1 и CallPrivate. Процедура PrivateMain будет недоступна.

Как правильно назвать переменную:

«Что самое сложное в работе программиста? — выдумывать имена переменным.» :-)А ведь придумать имя переменной тоже не так-то просто. Можно, конечно, давать им имена типа: a, d, f, x, y и т.д.(я сам иногда так делаю, но либо в простых кодах, либо для специального запутывания кода). Но стоит задуматься: а как Вы с ними будете управляться в большом коде? Код строк на 10 еще потерпит такие имена, а вот более крупные проекты — не советовал бы я в них оперировать такими переменными. Вы сами запутаетесь какая переменная как объявлена и какой тип данных может хранить и что за значение ей присвоено. Поэтому лучше всего давать переменным осмысленные имена и следовать соглашению об именовании переменных. Что за соглашение? Все очень просто: перед основным названием переменной ставится префикс, указывающий на тип данных, который мы предполагаем хранить в данной переменной. Про имеющиеся типы данных я уже рассказал выше. А ниже приведена примерная таблица соответствий префиксов типам данных:

Префикс Тип хранимых данных
b Boolean
bt Byte
i Integer
l Long
s Single
d Double
c Currency
dt Date
str String
obj Object
v Variant

Лично я немного для себя её переделал, т.к. некоторые обозначения мне кажутся скудными. Например Double я обозначаю как dbl, а Single как sgl. Это мне кажется более наглядным.

В чем еще плюс явного указания префикса данных. В VBA есть такие операторы как Def, при помощи которых можно указать тип данных по умолчанию для переменных, первая буква имени которых попадает в заданный в операторе диапазон. Например:

DefBool B
Sub test()
    Dim bCheck
End Sub

Автоматически переменной bCheck будет присвоен тип Boolean, т.к. она начинается с буквы b — регистр здесь не имеет значения(впрочем как в VBA в целом). Оператор Def задается в области объявления. Можно задать не одну букву, а целый диапазон букв:

DefBool B-C
Sub test()
    Dim bCheck, cCheck
End Sub

Но я считаю, что одной буквы для одного типа вполне достаточно. Можно задать сразу несколько операторов Def.

DefBool B
DefStr S
Sub test()
    Dim bCheck, sCheck
End Sub

Ниже приведен полный перечень операторов типов и данные, которые задает каждый из них:
DefBool — Задает тип Boolean
DefByte — Задает тип Byte
DefCur — Задает тип Currency
DefDate — Задает тип Date
DefDbl — Задает тип Double
DefInt — Задает тип Integer
DefLng — Задает тип Long
DefObj — Задает тип Object
DefSng — Задает тип Single
DefStr — Задает тип String
DefVar — Задает тип Variant
По умолчанию в VBA применена инструкция DefVar для всех букв(иначе говоря для всех переменных, которым не назначен тип данных явно через оператор As).

Ну и немаловажный момент это непосредственно осмысленное имя переменной. Имя переменной должно примерно отражать то, что в ней будет храниться. Например, Вы создаете отчет и Вам надо объявить две переменные: одна имя листа, другая имя книги. Можно было сделать так: str1, str2. Коротко, здорово. Но если подумать — и как можно понять, какая из этих переменных что хранит? Никак. Надо просматривать код и вспоминать, какой переменной какое значение было присвоено. Не совсем удобно, правда? А если бы Вы задали имена так: strBookName, strSheetName, то вроде как более понятно, что мы в них будем хранить. Это удобно не только вам самим при работе с кодом, но и другим людям, которые, возможно в будущем будут пользоваться Вашим кодом. Им будет удобнее читать код, если он будет оформлен грамотно, а переменные названы осмысленно. И не стоит экономить на длине имени — имя должно быть понятным. Без фанатизма, конечно :-). Хоть VBA и позволяет нам создавать переменные длиной до 254 символов, но читать такую переменную так же неудобно, как и с одним символом. Но здесь уже все зависит от Ваших предпочтений и фантазии.
Небольшое дополнение: лучше привыкать давать названия переменным на латинице(т.е. английский алфавит), т.к. для VBA английский язык «родной» и лучше использовать его.

Небольшой пример использования переменных в кодах:
Sub main()
'объявляем переменные с назначением конкретных типов
'As String - текст
'As Long   - целое число
Dim sAddress As String, sNewAddress As String, sShName As String
Dim lRow As Long
Dim rRange as Range 'назначили переменной тип ячейка/диапазон
 
'присвоили переменной rRange ссылку на текущую выделенную ячейку
Set rRange = Selection
'меняем выделение - выделяем ячейку D9
Range("D9").Select
'назначаем переменной адрес выделенных ячеек
sAddress = Selection.Address
'назначаем переменной lRow значение первой строки выделенной области
lRow = Selection.Row
'показываем сообщение
MsgBox "Адрес выделенной области: " & sAddress, vbInformation, "www.excel-vba.ru"
MsgBox "Номер первой строки: " & lRow, vbInformation, "www.excel-vba.ru"
'назначаем другой переменной значение адреса ячейки A1
sNewAddress = "A1"
'выделяем ячейку, заданную переменной sNewAddres
Range(sNewAddress).Select
MsgBox "Адрес выделенной области: " & sNewAddress, vbInformation, "www.excel-vba.ru"
'выделяем изначально выделенную ячейку, используя переменную rRange
rRange.Select
MsgBox "Адрес выделенной области: " & rRange.Address, vbInformation, "www.excel-vba.ru"
'задаем значение переменной
sShName = "excel-vba"
'переименовываем активный лист на имя, заданное переменной
ActiveSheet.Name = sShName
End Sub

Просмотреть пошагово выполнение данного кода поможет статья: Отлов ошибок и отладка кода VBA
Важно! Назначение значений переменным задается при помощи знака равно(=). Однако, есть небольшой нюанс: для переменных типа Object(а так же других объектных типов(Workbook, Worksheet, Range, Cells, Chart и т.п.)) присвоение идет при помощи ключевого оператора Set:

'присвоили переменной rRange ссылку на текущую выделенную ячейку
Set rRange = Selection

это так же называется присвоением ссылки на объект. Почему именно ссылки? Все просто: при помещении в переменную непосредственно ячейки или диапазона(Set var = Range(«A1») или Set rRange = Selection) нет никакого запоминания самой ячейки. В переменную помещается лишь ссылка на эту ячейку(можете считать, что это как ссылка в формулах) со всеми вытекающими: такое назначение не запоминает свойства ячейки до или после — в переменной хранится ссылка на конкретную ячейку и доступ есть исключительно к свойствам ячейки на текущий момент. Чтобы запомнить для этой ячейки значение, цвет или даже адрес (а так же и другие свойства) до её изменения и применить запомненное даже после изменения/перемещения самой ячейки — необходимо запоминать в переменные именно свойства ячейки:

Sub main()
    Dim val, l_InteriorColor As Long, l_FontColor As Long
    Dim rRange As Range 'назначили переменной тип ячейка/диапазон
 
    'присвоили переменной rRange ссылку на активную ячейку
    Set rRange = ActiveCell
    'запоминаем свойства ячейки
    val = rRange.Value                      'значение
    l_InteriorColor = rRange.Interior.Color 'цвет заливки
    l_FontColor = rRange.Font.Color         'цвет шрифта
    'копируем другую ячейку и вставляем на место активной
    ActiveSheet.Range("D1").Copy rRange
 
    'проверяем, что rRange теперь имеет совершенно другие свойста - как у D1
    MsgBox "Значение rRange: " & rRange.Value & vbNewLine & _
           "Цвет заливки rRange: " & rRange.Interior.Color & vbNewLine & _
           "Цвет шрифта rRange: " & rRange.Font.Color & vbNewLine, vbInformation, "www.excel-vba.ru"
 
    'назначаем свойства из сохраненных в переменных
    rRange.Value = val                      'значение
    rRange.Interior.Color = l_InteriorColor 'цвет заливки
    rRange.Font.Color = l_FontColor         'цвет шрифта
 
    'проверяем, что rRange возвращены параметры до копирования
    MsgBox "Значение rRange: " & rRange.Value & vbNewLine & _
           "Цвет заливки rRange: " & rRange.Interior.Color & vbNewLine & _
           "Цвет шрифта rRange: " & rRange.Font.Color & vbNewLine, vbInformation, "www.excel-vba.ru"
End Sub

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


Константы

Так же есть и иной вид «переменных» — константы. Это такая же переменная, только(как следует из её названия) — она не может быть изменена во время выполнения кода, т.к. является величиной постоянной и значение её назначается только один раз — перед выполнением кода.

Const sMyConst As String = "Имя моей программы"

Константам могут быть назначены данные тех же типов, что и для переменных, за исключением типа Object, т.к. Object это всегда ссылка на объект, который как правило обладает «динамическими»(т.е. обновляющимися) свойствами. А изменение для констант недопустимо.
Для дополнительной области видимости/жизни констант используется только Public. Если область видимости не указана, то константа будет доступна только из того модуля, в котором объявлена. Здесь обращаю внимание на то, что Dim уже не используется, т.к. Dim это идентификатор только для переменных. Пару важных отличий объявления констант от объявления переменных:

  • при объявлении константы необходимо обязательно указывать явно, что это константа ключевым словом Const
  • сразу в момент объявления необходимо назначить константе значение: = «Имя моей программы»

Во всем остальном объявление и применение констант идентично объявлению переменных. Коротко приведу пару примеров.
Если константа объявлена внутри процедуры:

Sub TestConst()
    Const sMyConst As String = "Имя моей программы"
    MsgBox sMyConst 'показываем сообщение с именем программы
End Sub

то она не может быть использована в другой процедуре:

Sub TestConst()
    Const sMyConst As String = "Имя моей программы"
    MsgBox sMyConst 'показываем сообщение с именем программы
End Sub
Sub TestConst2()
    MsgBox sMyConst 'вызовет ошибку Variable not defined
End Sub

Чтобы использовать одну константу во всех процедурах модуля(того, в котором она объявлена), необходимо объявить её в области объявлений:

Const sMyConst As String = "Имя моей программы"
Sub TestConst()
    MsgBox sMyConst 'показываем сообщение с именем программы
End Sub
Sub TestConst2()
    MsgBox sMyConst 'уже не вызовет ошибку Variable not defined
End Sub

Чтобы использовать одну константу во всех процедурах проекта(книги), необходимо объявить её как Public:

Public Const sMyConst As String = "Имя моей программы"
Sub TestConst()
    MsgBox sMyConst 'показываем сообщение с именем программы
End Sub
Sub TestConst2()
    MsgBox sMyConst 'не вызовет ошибку Variable not defined, даже если процедура в другом модуле
End Sub

Подробнее можно прочитать выше — как я уже писал для констант применяются те же правила, что и для переменных.

Также см.:
Variable not defined или что такое Option Explicit и зачем оно нужно?
Что такое модуль? Какие бывают модули?
Что такое макрос и где его искать?
Отлов ошибок и отладка кода VBA


Статья помогла? Поделись ссылкой с друзьями!

  Плейлист   Видеоуроки


Поиск по меткам



Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика

Неявная и явная декларация

Если модуль кода не содержит Option Explicit в верхней части модуля, тогда компилятор автоматически (то есть «неявно») создает переменные для вас, когда вы их используете. Они будут использовать переменную типа Variant .

Public Sub ExampleDeclaration()    

    someVariable = 10                  ' 
    someOtherVariable = "Hello World"
    'Both of these variables are of the Variant type.

End Sub

В приведенном выше коде, если указан параметр Option Explicit , код будет прерываться, потому что ему не нужны необходимые инструкции Dim для someVariable и someOtherVariable .

Option Explicit

Public Sub ExampleDeclaration()   

    Dim someVariable As Long 
    someVariable = 10

    Dim someOtherVariable As String
    someOtherVariable = "Hello World"

End Sub

Рекомендуется использовать Option Explicit в модулях кода, чтобы гарантировать, что вы объявите все переменные.

См. VBA Best Practices, как установить этот параметр по умолчанию.

переменные

Объем

Переменная может быть объявлена ​​(при увеличении уровня видимости):

  • На уровне процедуры, используя ключевое слово Dim в любой процедуре; локальная переменная .
  • На уровне модуля, используя ключевое слово Private в модуле любого типа; частное поле .
  • На уровне экземпляра используйте ключевое слово Friend в модуле любого типа; поле друга .
  • На уровне экземпляра, используя ключевое слово Public в модуле класса любого типа; публичное поле .
  • Глобально, используя ключевое слово Public в стандартном модуле ; глобальная переменная .

Переменные всегда должны быть объявлены с наименьшей возможной областью: предпочитайте передавать параметры процедурам, а не объявлять глобальные переменные.

Дополнительную информацию см. В разделе Модификаторы доступа .


Местные переменные

Используйте ключевое слово Dim чтобы объявить локальную переменную :

Dim identifierName [As Type][, identifierName [As Type], ...]

Параметр [As Type] синтаксиса объявления является необязательным. Когда указано, он устанавливает тип данных переменной, который определяет, сколько памяти будет выделено этой переменной. Это объявляет переменную String :

Dim identifierName As String

Если тип не указан, тип неявно Variant :

Dim identifierName 'As Variant is implicit

Синтаксис VBA также поддерживает объявление нескольких переменных в одном выражении:

Dim someString As String, someVariant, someValue As Long

Обратите внимание, что [As Type] должен быть указан для каждой переменной (кроме «Variant»). Это относительно распространенная ловушка:

Dim integer1, integer2, integer3 As Integer 'Only integer3 is an Integer. 
                                            'The rest are Variant.

Статические переменные

Локальные переменные также могут быть Static . В VBA ключевое слово Static используется для того, чтобы переменная «запомнила» значение, которое она имела, в последний раз, когда была вызвана процедура:

Private Sub DoSomething()
    Static values As Collection
    If values Is Nothing Then
        Set values = New Collection
        values.Add "foo"
        values.Add "bar"
    End If
    DoSomethingElse values
End Sub

Здесь коллекция values объявляется как Static локальная; потому что это переменная объекта , она инициализируется Nothing . Условие, следующее за объявлением, проверяет, была ли ссылка на объект Set раньше — если она выполняется в первый раз, процедура инициализируется. DoSomethingElse может добавлять или удалять элементы, и они все равно будут в коллекции в следующий раз, когда вызывается DoSomething .

альтернатива

Ключевое слово VBA Static легко может быть неправильно понято — особенно опытные программисты, которые обычно работают на других языках. На многих языках static используется для того, чтобы член класса (field, property, method, …) принадлежал типу, а не экземпляру . Код в static контексте не может ссылаться на код в контексте экземпляра . Ключевое слово VBA Static означает что-то совершенно другое.

Часто Static локальный объект может быть также реализован как Private переменная (поле) на уровне модуля, однако это бросает вызов принципу, с помощью которого переменная должна быть объявлена ​​с наименьшей возможной областью; доверяйте своим инстинктам, используйте то, что вы предпочитаете — оба будут работать … но использование Static без понимания того, что он делает, может привести к интересным ошибкам.


Дим против частного

Ключевое слово Dim является законным на уровне процедур и модулей; его использование на уровне модуля эквивалентно использованию ключевого слова Private :

Option Explicit
Dim privateField1 As Long 'same as Private privateField2 as Long
Private privateField2 As Long 'same as Dim privateField2 as Long

Ключевое слово Private доступно только на уровне модуля; это вызывает резервирование Dim для локальных переменных и объявление переменных модуля с помощью Private , особенно с контрастным ключевым словом Public которое должно быть использовано для объявления публичного участника. Также можно использовать Dim везде — то , что имеет значение консистенция:

«Частные поля»

  • DO использовать Private чтобы объявить переменную уровня модуля.
  • DO используйте Dim чтобы объявить локальную переменную.
  • НЕ используйте Dim чтобы объявить переменную уровня модуля.

«Тусклый везде»

  • DO используйте Dim чтобы объявить что-либо частным / местным.
  • НЕ используйте Private чтобы объявить переменную уровня модуля.
  • ИЗБЕГАЙТЕ объявление Public полей. *

* В общем, следует избегать объявления Public или Global полей.


поля

Переменная, объявленная на уровне модуля, в разделе объявлений в верхней части тела модуля является полем . Public поле, объявленное в стандартном модуле, является глобальной переменной :

Public PublicField As Long

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

Чтобы сделать переменную global / public, но только видимую изнутри проекта, используйте модификатор Friend :

Friend FriendField As Long

Это особенно полезно в надстройках, где намерение заключается в том, что другие проекты VBA ссылаются на проект надстройки и могут потреблять открытый API.

Friend FriendField As Long 'public within the project, aka for "friend" code
Public PublicField As Long 'public within and beyond the project

Поля друзей недоступны в стандартных модулях.


Поля экземпляра

Переменная, объявленная на уровне модуля, в разделе объявлений в верхней части тела модуля класса (включая ThisWorkbook , ThisDocument , Worksheet , UserForm и модулях классов ) является полем экземпляра : оно существует только до тех пор, пока существует экземпляр класс вокруг.

'> Class1
Option Explicit
Public PublicField As Long
'> Module1
Option Explicit
Public Sub DoSomething()
    'Class1.PublicField means nothing here
    With New Class1
        .PublicField = 42
    End With
    'Class1.PublicField means nothing here
End Sub

Инкапсулирующие поля

Данные Instance часто хранится Private и дублирован инкапсулируются. Закрытое поле можно открыть с помощью процедуры Property . Чтобы публично публиковать приватную переменную, не предоставляя доступ к записи вызывающему, модуль класса (или стандартный модуль) реализует элемент « Property Get :

Option Explicit
Private encapsulated As Long

Public Property Get SomeValue() As Long
    SomeValue = encapsulated
End Property

Public Sub DoSomething()
    encapsulated = 42
End Sub

Сам класс может изменить инкапсулированное значение, но вызывающий код может получить доступ только к Public членам (и членам Friend , если вызывающий объект находится в одном проекте).

Чтобы разрешить вызывающему абоненту:

  • Инкапсулированное значение , модуль предоставляет элемент Property Let .
  • Ссылка на инкапсулированные объекты , модуль предоставляет член Property Set .

Константы (Const)

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

Вы можете использовать Const только на уровне модуля или процедуры. Это означает, что контекст объявления для переменной должен быть классом, структурой, модулем, процедурой или блоком и не может быть исходным файлом, пространством имен или интерфейсом.

Public Const GLOBAL_CONSTANT As String = "Project Version #1.000.000.001"
Private Const MODULE_CONSTANT As String = "Something relevant to this Module"

Public Sub ExampleDeclaration()    

    Const SOME_CONSTANT As String = "Hello World"
    
    Const PI As Double = 3.141592653

End Sub

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

Public Const GLOBAL_CONSTANT = "Project Version #1.000.000.001" 'Still a string
Public Sub ExampleDeclaration()

    Const SOME_CONSTANT = "Hello World"           'Still a string
    Const DERIVED_CONSTANT = SOME_CONSTANT        'DERIVED_CONSTANT is also a string
    Const VAR_CONSTANT As Variant = SOME_CONSTANT 'VAR_CONSTANT is Variant/String
    
    Const PI = 3.141592653        'Still a double
    Const DERIVED_PI = PI         'DERIVED_PI is also a double
    Const VAR_PI As Variant = PI  'VAR_PI is Variant/Double
    
End Sub

Обратите внимание, что это специфично для констант и в отличие от переменных, где не указано, что тип приводит к типу Variant.

Хотя можно явно объявить константу как String, невозможно объявить константу в виде строки с использованием синтаксиса строки фиксированной ширины

'This is a valid 5 character string constant
Const FOO As String = "ABCDE"

'This is not valid syntax for a 5 character string constant
Const FOO As String * 5 = "ABCDE"

Модификаторы доступа

Dim должна быть зарезервирована для локальных переменных. На уровне модуля предпочитайте явные модификаторы доступа:

  • Private для частных полей, доступ к которым возможен только в том модуле, в котором они объявлены.
  • Public для общедоступных полей и глобальных переменных, к которым может обращаться любой вызывающий код.
  • Friend для переменных, публикуемых в рамках проекта, но недоступных для других проектов VBA, связанных с надстройками (для надстроек)
  • Global также может использоваться для Public полей в стандартных модулях, но является незаконным в модулях классов и в любом случае является устаревшим — вместо этого предпочитайте Public модификатор. Этот модификатор также не является законным для процедур.

Модификаторы доступа применимы как к переменным, так и к процедурам.

Private ModuleVariable As String
Public GlobalVariable As String

Private Sub ModuleProcedure()

    ModuleVariable = "This can only be done from within the same Module"

End Sub

Public Sub GlobalProcedure()

    GlobalVariable = "This can be done from any Module within this Project"

End Sub

Дополнительный модуль

Открытые Sub процедуры в стандартных модулях отображаются как макросы и могут быть прикреплены к элементам управления и сочетания клавиш в документе хоста.

И наоборот, публичные процедуры Function в стандартных модулях отображаются как пользовательские функции (UDF) в хост-приложении.

Указание отдельного модуля Option Private Module в верхней части стандартного модуля не позволяет его членам отображаться как макросы и UDF для приложения-хозяина.

Тип подсказки

Тип подсказки сильно обескуражен. Они существуют и документируются здесь по причинам исторической и обратной совместимости. As [DataType] этого следует использовать синтаксис As [DataType] .

Public Sub ExampleDeclaration()

        Dim someInteger% '% Equivalent to "As Integer"
        Dim someLong&    '& Equivalent to "As Long"
        Dim [email protected] '@ Equivalent to "As Currency"
        Dim someSingle!  '! Equivalent to "As Single"
        Dim someDouble#  '# Equivalent to "As Double"
        Dim someString$  '$ Equivalent to "As String"

        Dim someLongLong^  '^ Equivalent to "As LongLong" in 64-bit VBA hosts
End Sub

Типовые подсказки значительно уменьшают читаемость кода и поощряют венгерскую нотацию, которая также препятствует читаемости:

Dim strFile$
Dim iFile%

Вместо этого, объявляйте переменные ближе к их использованию и называйте вещи тем, что они используются, а не после их типа:

Dim path As String
Dim handle As Integer

Типовые подсказки также могут использоваться в литералах, чтобы обеспечить соблюдение определенного типа. По умолчанию числовой литерал, меньший, чем 32 768, будет интерпретироваться как литерал Integer , но с подсказкой типа вы можете контролировать это:

Dim foo 'implicit Variant
foo = 42& ' foo is now a Long
foo = 42# ' foo is now a Double
Debug.Print TypeName(42!) ' prints "Single"

Типные подсказки обычно не нужны для литералов, потому что они будут назначены переменной, объявленной с явным типом, или неявно преобразуются в соответствующий тип при передаче в качестве параметров. Неявные преобразования можно избежать, используя одну из явных функций преобразования типов:

'Calls procedure DoSomething and passes a literal 42 as a Long using a type hint
DoSomething 42&

'Calls procedure DoSomething and passes a literal 42 explicitly converted to a Long
DoSomething CLng(42)

Строковые возвращаемые встроенные функции

Большинство встроенных функций, которые обрабатывают строки, представлены в двух версиях: свободно напечатанная версия, которая возвращает Variant , и строго типизированную версию (заканчивающуюся на $ ), которая возвращает String . Если вы не назначаете возвращаемое значение для Variant , вы должны предпочесть версию, которая возвращает String противном случае происходит неявное преобразование возвращаемого значения.

Debug.Print Left(foo, 2)  'Left returns a Variant
Debug.Print Left$(foo, 2) 'Left$ returns a String

Эти функции:

  • VBA.Conversion.Error -> VBA.Conversion.Error $
  • VBA.Conversion.Hex -> VBA.Conversion.Hex $
  • VBA.Conversion.Oct -> VBA.Conversion.Oct $
  • VBA.Conversion.Str -> VBA.Conversion.Str $
  • VBA.FileSystem.CurDir -> VBA.FileSystem.CurDir $
  • VBA. [_ HiddenModule] .Input -> VBA. [_ HiddenModule] .Input $
  • VBA. [_ HiddenModule] .InputB -> VBA. [_ HiddenModule] .InputB $
  • VBA.Interaction.Command -> VBA.Interaction.Command $
  • VBA.Interaction.Environ -> VBA.Interaction.Environ $
  • VBA.Strings.Chr -> VBA.Strings.Chr $
  • VBA.Strings.ChrB -> VBA.Strings.ChrB $
  • VBA.Strings.ChrW -> VBA.Strings.ChrW $
  • VBA.Strings.Format -> VBA.Strings.Format $
  • VBA.Strings.LCase -> VBA.Strings.LCase $
  • VBA.Strings.Left -> VBA.Strings.Left $
  • VBA.Strings.LeftB -> VBA.Strings.LeftB $
  • VBA.Strings.LTtrim -> VBA.Strings.LTrim $
  • VBA.Strings.Mid -> VBA.Strings.Mid $
  • VBA.Strings.MidB -> VBA.Strings.MidB $
  • VBA.Strings.Right -> VBA.Strings.Right $
  • VBA.Strings.RightB -> VBA.Strings.RightB $
  • VBA.Strings.RTrim -> VBA.Strings.RTrim $
  • VBA.Strings.Space -> VBA.Strings.Space $
  • VBA.Strings.Str -> VBA.Strings.Str $
  • VBA.Strings.String -> VBA.Strings.String $
  • VBA.Strings.Trim -> VBA.Strings.Trim $
  • VBA.Strings.UCase -> VBA.Strings.UCase $

Обратите внимание, что это псевдонимы функций, не совсем намеки на тип . Функция Left соответствует скрытой функции B_Var_Left , а версия Left$ соответствует скрытой функции B_Str_Left .

В ранних версиях VBA знак $ не является допустимым символом, а имя функции должно быть заключено в квадратные скобки. В Word Basic было много и много функций, которые возвращали строки, которые заканчивались в $.

Объявление строк фиксированной длины

В VBA строки могут быть объявлены с определенной длиной; они автоматически дополняются или усекаются, чтобы поддерживать указанную длину.

Public Sub TwoTypesOfStrings()

    Dim FixedLengthString As String * 5 ' declares a string of 5 characters
    Dim NormalString As String

    Debug.Print FixedLengthString       ' Prints "     "
    Debug.Print NormalString            ' Prints ""

    FixedLengthString = "123"           ' FixedLengthString now equals "123  "
    NormalString = "456"                ' NormalString now equals "456"

    FixedLengthString = "123456"        ' FixedLengthString now equals "12345"
    NormalString = "456789"             ' NormalString now equals "456789"

End Sub

Когда использовать статическую переменную

Статическая переменная, объявленная локально, не разрушается и не теряет своего значения при выходе из процедуры Sub. Последующие вызовы процедуры не требуют повторной инициализации или присвоения, хотя вы можете «нулевать» любые запоминаемые значения.

Они особенно полезны при позднем связывании объекта в вспомогательном подэлементе, который вызывается повторно.

Фрагмент 1: повторное использование объекта Scripting.Dictionary на многих листах

Option Explicit

Sub main()
    Dim w As Long
    
    For w = 1 To Worksheets.Count
        processDictionary ws:=Worksheets(w)
    Next w
End Sub

Sub processDictionary(ws As Worksheet)
    Dim i As Long, rng As Range
    Static dict As Object
    
    If dict Is Nothing Then
        'initialize and set the dictionary object
        Set dict = CreateObject("Scripting.Dictionary")
        dict.CompareMode = vbTextCompare
    Else
        'remove all pre-existing dictionary entries
        ' this may or may not be desired if a single dictionary of entries
        ' from all worksheets is preferred
        dict.RemoveAll
    End If
    
    With ws
        
        'work with a fresh dictionary object for each worksheet
        ' without constructing/destructing a new object each time
        ' or do not clear the dictionary upon subsequent uses and 
        ' build a dictionary containing entries from all worksheets
    
    End With
End Sub

Snippet 2: создать рабочий лист UDF, который опоздает с привязкой к объекту VBScript.RegExp

Option Explicit

Function numbersOnly(str As String, _
                     Optional delim As String = ", ")
    Dim n As Long, nums() As Variant
    Static rgx As Object, cmat As Object

    'with rgx as static, it only has to be created once
    'this is beneficial when filling a long column with this UDF
    If rgx Is Nothing Then
        Set rgx = CreateObject("VBScript.RegExp")
    Else
        Set cmat = Nothing
    End If
    
    With rgx
        .Global = True
        .MultiLine = True
        .Pattern = "[0-9]{1,999}"
        If .Test(str) Then
            Set cmat = .Execute(str)
            'resize the nums array to accept the matches
            ReDim nums(cmat.Count - 1)
            'populate the nums array with the matches
            For n = LBound(nums) To UBound(nums)
                nums(n) = cmat.Item(n)
            Next n
            'convert the nums array to a delimited string
            numbersOnly = Join(nums, delim)
        Else
            numbersOnly = vbNullString
        End If
    End With
End Function

static_UDF
Пример UDF со статическим объектом, заполненным полмиллиона строк

* Истекшее время, чтобы заполнить 500K строк с помощью UDF:
— с Dim rgx As Object : 148.74 секунд
— с Static rgx As Object : 26.07 секунд

* Они должны учитываться только для относительного сравнения. Ваши собственные результаты будут варьироваться в зависимости от сложности и
объем выполненных операций.

Помните, что UDF не рассчитывается один раз в жизни книги. Даже энергонезависимый UDF будет пересчитываться всякий раз, когда значения в пределах диапазона (ов), которые он ссылается, могут быть изменены. Каждое последующее событие пересчета только увеличивает преимущества статически объявленной переменной.

  • Статическая переменная доступна для времени жизни модуля, а не для процедуры или функции, в которой она была объявлена ​​и назначена.
  • Статические переменные могут быть объявлены только локально.
  • Статическая переменная содержит много одинаковых свойств переменной уровня частного модуля, но с более ограниченной областью.

Ссылки по теме: Static (Visual Basic)

В VBA, как и в любом другом языке программирования, переменные и константы используются для хранения каких-либо значений. Как и следует из названия, переменные могут изменяться, константы же хранят фиксированные значения.

Например, константа Pi хранит значение 3,14159265… Число «Пи» не будет изменяться в ходе выполнения программы, но все же хранить такое значение удобнее как константу.

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

Содержание

  1. Типы данных
  2. Объявление переменных и констант
  3. Option Explicit
  4. Область действия переменных и констант

Типы данных

Все переменные и константы относятся к определённому типу данных. В таблице ниже приведены типы данных, используемые в VBA, с описанием и диапазоном возможных значений:

Тип данных Размер Описание Диапазон значений
Byte 1 байт Положительные целые числа; часто используется для двоичных данных от 0 до 255
Boolean 2 байта Может принимать значения либо True, либо False True или False
Integer 2 байта Целые числа (нет дробной части) от -32 768 до +32 767
Long 4 байта Большие целые числа (нет дробной части) от -2 147 483 648 до +2 147 483 647
Single 4 байта Число с плавающей точкой одинарной точности от -3.4e38 до +3.4e38
Double 8 байт Число с плавающей точкой двойной точности от -1.8e308 до +1.8e308
Currency 8 байт Число с плавающей точкой, с фиксированным количеством десятичных разрядов от -922 337 203 685 477.5808 до +922 337 203 685 477.5807
Date 8 байт Дата и время – данные типа Date представлены числом с плавающей точкой. Целая часть этого числа выражает дату, а дробная часть – время от 1 Января 100 до 31 Декабря 9999
Object 4 байта Ссылка на объект Любая ссылка на объект
String изменяется Набор символов. Тип String может иметь фиксированную или изменяющуюся длину. Чаще используется с изменяющейся длиной Фиксированной длины — приблизительно до 65 500 символов. Переменной длины — приблизительно до 2 миллиардов символов
Variant изменяется Может содержать дату, число с плавающей точкой или строку символов. Этот тип используют в тех случаях, когда заранее не известно, какой именно тип данных будет введён Число – Double, строка – String

Очевидно, что пользуясь приведённой выше таблицей и правильно выбирая тип данных, можно использовать память более экономно (например, выбрать тип данных Integer вместо Long или Single вместо Double). Однако, используя более компактные типы данных, нужно внимательно следить за тем, чтобы в коде не было попыток уместить в них не соразмерно большие значения.

Объявление переменных и констант

Примечание переводчика: Говоря о переменных в VBA, стоит упомянуть ещё один очень важный момент. Если мы объявляем переменную, но не присваиваем ей какое-либо значение, то она инициализируется значением по умолчанию:
• текстовые строки — инициализируются пустыми строками;
• числа — значением 0;
• переменные типа Boolean — False;
• даты — 30 декабря 1899.

Прежде чем использовать переменную или константу, её нужно объявить. Для этого в макрос добавляют вот такую простую строку кода:

Dim Имя_Переменной As Тип_Данных

В показанной выше строке кода Имя_Переменной – это имя переменной, которая будет использована в коде, а Тип_Данных – это один из типов данных из таблицы, приведённой чуть ранее в этой статье. Например:

Dim sVAT_Rate As Single
Dim i As Integer

Аналогично объявляются константы, но при объявлении констант обязательно сразу указывается их значение. Например, вот так:

Const iMaxCount = 5000
Const iMaxScore = 100

Объявлять переменные в Excel не обязательно. По умолчанию все введённые, но не объявленные переменные в Excel будут иметь тип Variant и смогут принять как числовое, так и текстовое значение.

Таким образом, программист в любой момент сможет использовать новую переменную (даже если она не была объявлена), и Excel будет рассматривать её как переменную типа Variant. Однако, есть несколько причин, почему так поступать не следует:

  1. Использование памяти и скорость вычислений. Если не объявлять переменную с указанием типа данных, то по умолчанию для неё будет установлен тип Variant. Этот тип данных использует больше памяти, чем другие типы данных.Казалось бы, несколько лишних байт на каждую переменную – не так уж много, но на практике в создаваемых программах могут быть тысячи переменных (особенно при работе с массивами). Поэтому излишняя память, используемая переменными типа Variant, по сравнению с переменными типа Integer или Single, может сложится в значительную сумму.К тому же, операции с переменными типа Variant выполняются гораздо медленнее, чем с переменными других типов, соответственно лишняя тысяча переменных типа Variant может значительно замедлить вычисления.
  2. Профилактика опечаток в именах переменных. Если все переменные объявляются, то можно использовать оператор VBA — Option Explicit (о нём расскажем далее), чтобы выявить все не объявленные переменные.Таким образом исключается появление в программе ошибки в результате не верно записанного имени переменной. Например, используя в коде переменную с именем sVAT_Rate, можно допустить опечатку и, присваивая значение этой переменной, записать: «VATRate = 0,175». Ожидается, что с этого момента, переменная sVAT_Rate должна содержать значение 0,175 – но, конечно же, этого не происходит. Если же включен режим обязательного объявления всех используемых переменных, то компилятор VBA сразу же укажет на ошибку, так как не найдёт переменную VATRate среди объявленных.
  3. Выделение значений, не соответствующих объявленному типу переменной. Если объявить переменную определённого типа и попытаться присвоить ей данные другого типа, то появится ошибка, не исправив которую, можно получить сбой в работе программы.На первый взгляд, это может показаться хорошей причиной, чтобы не объявлять переменные, но на самом деле, чем раньше выяснится, что одна из переменных получила не те данные, которые должна была получить – тем лучше! Иначе, если программа продолжит работу, результаты могут оказаться неверными и неожиданными, а найти причину ошибок будет гораздо сложнее.Возможно также, что макрос будет «успешно» выполнен. В результате ошибка останется незамеченной и работа продолжится с неверными данными!

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

Option Explicit

Оператор Option Explicit заставляет объявлять все переменные, которые будут использованы в коде VBA, и при компиляции выделяет все не объявленные переменные как ошибки (прежде чем будет запущено выполнение кода). Применить этот оператор не сложно – просто запишите в самом верху файла VBA такую строку:

Option Explicit

Если хотите всегда вставлять Option Explicit в начало каждого нового созданного модуля VBA, то это можно делать автоматически. Для этого необходимо включить параметр Require Variable Declaration в настройках редактора VBA.

Это делается так:

  • В меню редактора Visual Basic нажмите Tools > Options
  • В появившемся диалоговом окне откройте вкладку Editor
  • Отметьте галочкой параметр Require Variable Declaration и нажмите ОК

При включенном параметре строка Option Explicit будет автоматически вставляться в начало каждого нового созданного модуля.

Область действия переменных и констант

Каждая объявленная переменная или константа имеет свою ограниченную область действия, то есть ограниченную часть программы, в которой эта переменная существует. Область действия зависит от того, где было сделано объявление переменной или константы. Возьмём, к примеру, переменную sVAT_Rate, которая используется в функции Total_Cost. В следующей таблице рассмотрены два варианта области действия переменной sVAT_Rate, объявленной в двух различных позициях в модуле:

Option Explicit

Dim sVAT_Rate As Single

Function Total_Cost() As Double


...


End Function
Если переменная sVAT_Rate объявлена в самом начале модуля, то областью действия этой переменной будет весь модуль (т.е. переменная sVAT_Rate будет распознаваться всеми процедурами в этом модуле).

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

Однако, если будет вызвана какая-то функция, расположенная в другом модуле, то для неё переменная sVAT_Rate будет не известна.

Option Explicit

Function Total_Cost() As Double

Dim sVAT_Rate As Single


...


End Function
Если переменная sVAT_Rate объявлена в начале функции Total_Cost, то её область действия будет ограничена только этой функцией (т.е. в пределах функции Total_Cost, можно будет использовать переменную sVAT_Rate, а за её пределами – нет).

При попытке использовать sVAT_Rate в другой процедуре, компилятор VBA сообщит об ошибке, так как эта переменная не была объявлена за пределами функции Total_Cost (при условии, что использован оператор Option Explicit).

В показанном выше примере переменная объявлена на уровне модуля при помощи ключевого слова Dim. Однако, бывает необходимо, чтобы объявленными переменными можно было пользоваться в других модулях. В таких случаях для объявления переменной вместо ключевого слова Dim нужно использовать ключевое слово Public.

Кстати, для того, чтобы объявить переменную на уровне модуля, вместо ключевого слова Dim можно использовать ключевое слово Private, которое укажет на то, что данная переменная предназначена для использования только в текущем модуле.

Для объявления констант также можно использовать ключевые слова Public и Private, но не вместо ключевого слова Const, а вместе с ним.

В следующих примерах показано использование ключевых слов Public и Private в применении к переменным и к константам.

Option Explicit

Public sVAT_Rate As Single

Public Const iMax_Count = 5000

...

В этом примере ключевое слово Public использовано для объявления переменной sVAT_Rate и константы iMax_Count. Областью действия объявленных таким образом элементов будет весь текущий проект.

Это значит, что sVAT_Rate и iMax_Count будут доступны в любом модуле проекта.

Option Explicit

Private sVAT_Rate As Single

Private Const iMax_Count = 5000

...

В этом примере для объявления переменной sVAT_Rate и константы iMax_Count использовано ключевое слово Private. Областью действия этих элементов является текущий модуль.

Это значит, что sVAT_Rate и iMax_Count будут доступны во всех процедурах текущего модуля, но не будут доступны для процедур, находящихся в других модулях.

Оцените качество статьи. Нам важно ваше мнение:

“One man’s constant is another man’s variable.” – Alan Perlis

This post provides a complete guide to using the VBA Dim statement.

The first section provides a quick guide to using the Dim statement including examples and the format of the Dim statement.

The rest of the post provides the most complete guide you will find on the VBA Dim Statement.

If you are interested in declaring parameters then you can read about them here.

A Quick Guide to using the VBA Dim Statement

Description Format Example
Basic variable Dim [variable name] As [Type] Dim count As Long
Dim amount As Currency
Dim name As String
Dim visible As Boolean
Fixed String Dim [variable name] As String * [size] Dim s As String * 4
Dim t As String * 10
Variant Dim [variable name] As Variant
Dim [variable name]
Dim var As Variant
Dim var
Object using Dim and New Dim [variable name] As New [object type] Dim coll As New Collection
Dim coll As New Class1
Object using Dim, Set and New Dim [variable name] As [object type]
Set [variable name] = New [object type]
Dim coll As Collection
Set coll = New Collection

Dim coll As Class1
Set coll = New Class1

Static array Dim [variable name]([first] To [last] ) As [Type] Dim arr(1 To 6) As Long
Dynamic array Dim [variable name]() As [Type]
ReDim [variable name]([first] To [last])
Dim arr() As Long
ReDim arr(1 To 6)
External Library
(Early Binding)*
Dim [variable name] As New [item] Dim dict As New Dictionary
External Library
(Early Binding using Set)*
Dim [variable name] As [item]
Set [variable name] = New [item]
Dim dict As Dictionary
Set dict = New Dictonary
External Library
(Late Binding)
Dim [variable name] As Object
Set [variable name] = CreateObject(«[library]»)
Dim dict As Object
Set dict = CreateObject(«Scripting.Dictionary»)

*Note: Early binding requires that you add the reference file using Tools->References from the menu. See here for how to add the Dictonary reference.

Useful Links

Declaring parameters in a sub or function
Using Objects in VBA
VBA Arrays
VBA Collection
VBA Dictionary
VBA Workbook
VBA Worksheet

What is the VBA Dim Statement

The Dim keyword is short for Dimension. It is used to declare variables in VBA.

Declare means we are telling VBA about a variable we will use later.

There are four types of Dim statements. They are all pretty similar in terms of syntax.

They are:

  1. Basic variable
  2. Variant
  3. Object
  4. Array

The following is a brief description of each type:

    1. Basic variable – this variable type holds one value. These are the types such as Long, String, Date, Double, Currency.
    1. Variant – VBA decides at runtime which type will be used. You should avoid variants where possible but in certain cases it is a requirement to use them.
    1. Object – This is a variable that can have multiple methods(i.e. subs/functions) and multiple properties(i.e. values). There are 3 kinds:
      1. Excel objects such as the Workbook, Worksheet and Range objects.
      2. User objects created using Class Modules.
      3. External libraries such as the Dictionary.
  1. Array – this is a group of variables or objects.

In the next section, we will look at the format of the VBA Dim statement with some examples of each.

In later sections we will look at each type in more detail.

Format of the VBA Dim Statement

The format of the Dim statement is shown below

' 1. BASIC VARIABLE
' Declaring a basic variable
Dim [variable name] As [type]

' Declaring a fixed string
Dim [variable name] As String * [size]

' 2. VARIANT
Dim [variable name] As Variant
Dim [variable name]

' 3. OBJECT
' Declaring an object
Dim [variable name] As [type]

' Declaring and creating an object
Dim [variable name] As New [type]

' Declaring an object using late binding
Dim [variable name] As Object

' 4. ARRAY
' Declaring a static array
Dim [variable name](first To last) As [type]

' Declaring a dynamic array
Dim [variable name]() As [type]

Below are examples of using the different formats

' https://excelmacromastery.com/
Sub Examples()

    ' 1. BASIC VARIABLE
    ' Declaring a basic variable
    Dim name As String
    Dim count As Long
    Dim amount As Currency
    Dim eventdate As Date
    
    ' Declaring a fixed string
    Dim userid As String * 8
    
    ' 2. VARIANT
    Dim var As Variant
    Dim var
    
    ' 3. OBJECT
    ' Declaring an object
    Dim sh As Worksheet
    Dim wk As Workbook
    Dim rg As Range
    
    ' Declaring and creating an object
    Dim coll1 As New Collection
    Dim o1 As New Class1
    
    ' Declaring an object - create object below using Set
    Dim coll2 As Collection
    Dim o2 As Class1
    
    Set coll2 = New Collection
    Set o2 = New Class1
    
    ' Declaring and assigning using late binding
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")
    
    ' 4. ARRAY
    ' Declaring a static array
    Dim arrScores(1 To 5) As Long
    Dim arrCountries(0 To 9) As String
    
    ' Declaring a dynamic array - set size below using ReDim
    Dim arrMarks() As Long
    Dim arrNames() As String
    
    ReDim arrMarks(1 To 10) As Long
    ReDim arrNames(1 To 10) As String

End Sub

We will examine these different types of Dim statements in the later sections.

How to Use Dim with Multiple Variables

We can declare multiple variables in a single Dim statement

Dim name As String, age As Long, count As Long

If we leave out the type then VBA automatically sets the type to be a Variant. We will see more about Variant later.

' Amount is a variant
Dim amount As Variant

' Amount is a variant
Dim amount

' Address is a variant - name is a string
Dim name As String, address

' name is a variant, address is a string
Dim name, address As String

When you declare multiple variables you should specify the type of each one individually

Dim wk As Workbook, marks As Long, name As String

You can place as many variables as you like in one Dim statement but it is good to keep it to 3 or 4 for readability.

Where Should I Put the Dim Statement?

The Dim statement can be placed anywhere in a procedure. However, it must come before any line where the variable is used.

If the variable is used before the Dim statement then you will get a “variable not defined” error:

When it comes to the positioning your Dim statements you can do it in two main ways. You can place all your Dim statements at the top of the procedure:

' https://excelmacromastery.com/
Sub DimTop()

    ' Placing all the Dim statements at the top
    Dim count As Long, name As String, i As Long
    Dim wk As Workbook, sh As Worksheet, rg As Range
    
    Set wk = Workbooks.Open("C:Docsdata.xlsx")
    Set sh = wk.Worksheets(1)
    Set rg = sh.Range("A1:A10")
    
    For i = 1 To rg.Rows.count
        count = rg.Value
        Debug.Print count
    Next i
  
End Sub

OR you can declare the variables immediately before you use them:

' https://excelmacromastery.com/
Sub DimAsUsed()

    Dim wk As Workbook
    Set wk = Workbooks.Open("C:Docsdata.xlsx")
    
    Dim sh As Worksheet
    Set sh = wk.Worksheets(1)
    
    Dim rg As Range
    Set rg = sh.Range("A1:A10")
    
    Dim i As Long, count As Long, name As String
    For i = 1 To rg.Rows.count
        count = rg.Value
        name = rg.Offset(0, 1).Value
        Debug.Print name, count
    Next i
  
End Sub

I personally prefer the latter as it makes the code neater and it is easier to read, update and spot errors.

Using Dim in Loops

Placing a Dim statement in a Loop has no effect on the variable.

When VBA starts a Sub (or Function), the first thing it does is to create all the variables that have been declared in the Dim statements.

The following 2 pieces of code are almost the same. In the first, the variable Count is declared before the loop. In the second it is declared within the loop.

' https://excelmacromastery.com/
Sub CountOutsideLoop()

    Dim count As Long

    Dim i As Long
    For i = 1 To 3
        count = count + 1
    Next i
    
    ' count value will be 3
    Debug.Print count

End Sub
' https://excelmacromastery.com/
Sub CountInsideLoop()

    Dim i As Long
    For i = 1 To 3
        Dim count As Long
        count = count + 1
    Next i
    
    ' count value will be 3
    Debug.Print count

End Sub

The code will behave exactly the same because VBA will create the variables when it enters the sub.

Can I use Dim to Assign a Value?

In languages like C++, C# and Java, we can declare and assign variables on the same line

' C++
int i = 6
String name = "John"

We cannot do this in VBA. We can use the colon operator to place the declare and assign lines on the same line.

Dim count As Long: count = 6

We are not declaring and assigning in the same VBA line. What we are doing is placing these two lines(below) on one line in the editor. As far as VBA is concerned they are two separate lines as here:

Dim count As Long
count = 6

Here we put 3 lines of code on one editor line using the colon:

count = 1: count = 2: Set wk = ThisWorkbook

There is really no advantage or disadvantage to assigning and declaring on one editor line. It comes down to a personal preference.

Is Dim Actually Required?

The answer is that it is not required. VBA does not require you to use the Dim Statement.

However, not using the Dim statement is a poor practice and can lead to lots of problems.

You can use a variable without first using the Dim statement. In this case the variable will automatically be a variant type.

This can lead to problems such as

  1. All variables are variants (see the Variant section for issues with this).
  2. Some variable errors will go undetected.

Because of these problems it is good practice to make using Dim mandatory in our code. We do this by using the Option Explicit statement.

Option Explicit

We can make Dim mandatory in a module by typing “Option Explicit” at the top of a module.

We can make this happen automatically in each new module by selecting Tools->Options from the menu and checking the box beside “Require Variable Declaration”. Then when you insert a new module, “Option Explicit” will be automatically added to the top.

VBA Require Variable Declaration

Let’s look at some of the errors that may go undetected if we don’t use Dim.

Variable Errors

In the code below we use the Total variable without using a Dim statement

' https://excelmacromastery.com/
Sub NoDim()

    Total = 6
    
    Total = Total + 1
    
    Debug.Print Total

End Sub

If we accidentally spell Total incorrectly then VBA will consider it a new variable.

In the code below we have misspelt the variable Total as Totall:

' https://excelmacromastery.com/
Sub NoDimError()

    Total = 6
    
    ' The first Total is misspelt
    Totall = Total + 1
    
    ' This will print 6 instead of 7
    Debug.Print Total

End Sub

VBA will not detect any error in the code and an incorrect value will be printed.

Let’s add Option Explicit and try the above code again

' https://excelmacromastery.com/
Option Explicit 

Sub NoDimError()

    Total = 6
    
    ' The first Total is misspelt
    Totall = Total + 1
    
    ' This will print 6 instead of 7
    Debug.Print Total

End Sub

Now when we run the code we will get the “Variable not defined” error. To stop this error appearing we must use Dim for each variable we want to use.

When we add the Dim statement for Total and run the code we will now get an error telling us that the misspelt Totall was not defined.

variable not defined 2

This is really useful as it helps us find an error that would have otherwise gone undetected.

Keyword Misspelt Error

Here is a second example which is more subtle.

When the following code runs it should change the font in cell A1 to blue.

However, when the code runs nothing happens.

' https://excelmacromastery.com/
Sub SetColor()

    Sheet1.Range("A1").Font.Color = rgblue

End Sub

The error here is that rgblue should be rgbBlue. If you add Option Explicit to the module, the error “variable not defined” will appear. This makes solving the problem much easier.

These two examples are very simple. If you have a lot of code then errors like this can be a nightmare to track down.

Using Dim with Basic Variables

VBA has the same basic variable types that are used in the Excel Spreadsheet.

You can see a list of all the VBA variable types here.

However, most of the time you will use the following ones

Type Storage Range Description
Boolean 2 bytes True or False This variable can be either True or False.
Long 4 bytes -2,147,483,648 to 2,147,483,647 Long is short for Long Integer. Use this instead of the Integer* type.
Currency 8 bytes -1.79769313486231E308 to-4.94065645841247E-324 for negative values; 4.94065645841247E-324 to 1.79769313486232E308 for positive values Similar to Double but has only 4 decimal places
Double 8 bytes -922,337,203,685,477.5808 to 922,337,203,685,477.5807
Date 8 bytes January 1, 100 to December 31, 9999
String varies 0 to approximately 2 billion Holds text.

*Originally we would use the Long type instead of Integer because the Integer was 16-bit and so the range was -32,768 to 32,767 which is quite small for a lot of the uses of integer.

However on a 32 bit(or higher) system the Integer is automatically converted to a Long. As Windows has been 32 bit since Windows 95NT there is no point in using an Integer.

In a nutshell, always use Long for an integer type in VBA.

Fixed String Type

There is one unusual basic variable type in VBA that you may not be familiar with.

This is the fixed string type. When we create a normal string in VBA we can add text and VBA will automatically resize the string for us

' https://excelmacromastery.com/
Sub StringType()

    Dim s As String
    
    ' s is "John Smith"
    s = "John Smith"
    
    ' s is "Tom"
    s = "Tom"

End Sub

A fixed string is never resized. This string will always be the same size no matter what you assign to it

Here are some examples

' https://excelmacromastery.com/
Sub FixedString()
    
    Dim s As String * 4
    
    ' s is "John"
    s = "John Smith"
    
    ' s = "Tom "
    s = "Tom"

End Sub

Using Dim with Variants

When we declare a variable to be a variant, VBA will decide at runtime which variable type it should be.

We declare variants as follows

' Both are variants
Dim count
Dim count As Variant

This sounds like a great idea in theory. No more worrying about the variable type

' https://excelmacromastery.com/
Sub UsingVariants()
    
    Dim count As Variant
        
    count = 7
    
    count = "John"
    
    count = #12/1/2018#

End Sub

However, using variants is poor practice and this is why:

  1. Runtime Errors – VBA will not notice incorrect type errors(i.e. Data Mismatch).
  2. Compile Errors – VBA cannot detect compile errors.
  3. Intellisense is not available.
  4. Size – A variant is set to 16 bytes which is the largest variable type

Runtime Errors

Errors are your friend!

They may be annoying and frustrating when they happen but they are alerting you to future problems which may not be so easy to find.

The Type Mismatch error alerts you when incorrect data is used.

For example. Imagine we have a sheet of student marks. If someone accidentally(or deliberately) replaces a mark with text then the data is invalid.

If we use a variant to store marks then no error will occur:

' https://excelmacromastery.com/
Sub MarksVariant()
    
    Dim mark As Variant
    
    Dim i As Long
    For i = 1 To 10
        
        ' Read the mark
        mark = Sheet1.Range("A" & i).Value
        
    Next

End Sub

This is not good because there is an error with your data and you are not aware of it.

If you make the variable Long then VBA will alert you with a “Type Mismatch” error if the values are text.

' https://excelmacromastery.com/
Sub MarksLong()
    
    Dim mark As Long
    
    Dim i As Long
    For i = 1 To 10
        
        ' Read the mark
        mark = Sheet1.Range("A" & i).Value
        
    Next

End Sub

Compile Errors

Using the compiler to check for errors is very efficient. It will check all of your code for problems before you run it. You use the compiler by selecting Debug->Compile VBAProject from the menu.

In the following code, there is an error. The Square function expects a long integer but we are passing a string(i.e. the name variable):

' https://excelmacromastery.com/
Sub CompileError()

    Dim name As String

    Debug.Print Square(name)

End Sub

Function Square(value As Long) As Long
    Square = value * value
End Function

If we use Debug->Compile on this code, VBA will show us an error:

dim compile error

This is good news as we can fix this error right away. However, if we declare the value parameter as a variant:

Function Square(value As Variant) As Long
    Square = value * value
End Function

then Debug.Compile will not treat this as an error. The error is still there but it is undetected.

Accessing the Intellisense

The Intellisense is an amazing feature of VBA. It gives you the available options based on the type you have created.

Imagine you declare a worksheet variable using Dim

Dim wk As Workbook

When you use the variable wk with a decimal point, VBA will automatically display the available options for the variable.

You can see the Intellisense in the screenshot below

VBA Intellisense

If you use Variant as a type then the Intellisense will not be available

Dim wk As Variant

This is because VBA will not know the variable type until runtime.

Variant Size

The size of a variant is 16 bytes. If the variable is going to be a long then it would only take up 4 bytes. You can see that this is not very efficient.

However, unlike the 1990’s where this would be an issue, we now have computers with lots of memory and it is unlikely you will notice an inefficiency unless you are using a huge amount of variables.

Using Dim with Objects

If you don’t know what Objects are then you can read my article about VBA Objects here.

There are 3 types of objects:

  1. Excel objects
  2. Class Module objects
  3. External library objects

Note: The VBA Collection object is used in a similar way to how we use Class Module object. We use new to create it.

Let’s look at each of these in turn.

Excel objects

Excel objects such as the Workbook, Worksheet, Range, etc. do not use New because they are automatically created by Excel. See When New is not required.

When a workbook is created or opened then Excel automatically creates the associated object.

For example, in the code below we open a workbook. VBA will create the object and the Open function will return a workbook which we can store in a variable

' https://excelmacromastery.com/
Sub OpenWorkbook()
    
    Dim wk As Workbook
    Set wk = Workbooks.Open("C:Docsdata.xlsx")

End Sub

If we create a new worksheet, a similar thing happens. VBA will automatically create it and provide use access to the object.

' https://excelmacromastery.com/
Sub AddSheet()
    
    Dim sh As Worksheet
    Set sh = ThisWorkbook.Worksheets.Add

End Sub

We don’t need to use the New keyword for these Excel objects.

We just assign the variable to the function that either creates a new object or that gives us access to an existing one.

Here are some examples of assigning the Workbook, Worksheet and range variables:

' https://excelmacromastery.com/
Sub DimWorkbook()
    
    Dim wk As Workbook
    
    ' assign wk to a new workbook
    Set wk = Workbooks.Add
    
    ' assign wk to the first workbook opened
    Set wk = Workbooks(1)
    
    ' assign wk to The workbook Data.xlsx
    Set wk = Workbooks("Data.xlsx")
    
    ' assign wk to the active workbook
    Set wk = ActiveWorkbook
    
End Sub
' https://excelmacromastery.com/
Sub DimWorksheet()
    
    Dim sh As Worksheet
    
    ' Assign sh to a new worksheet
    Set sh = ThisWorkbook.Worksheets.Add
    
    ' Assign sh to the leftmost worksheet
    Set sh = ThisWorkbook.Worksheets(1)
    
    ' Assign sh to a worksheet called Customers
    Set sh = ThisWorkbook.Worksheets("Customers")
    
    ' Assign sh to the active worksheet
    Set sh = ActiveSheet

End Sub
' https://excelmacromastery.com/
Sub DimRange()

    ' Get the customer worksheet
    Dim sh As Worksheet
    Set sh = ThisWorkbook.Worksheets("Customers")
    
    ' Declare the range variable
    Dim rg As Range
    
    ' Assign rg to range A1
    Set rg = sh.Range("A1")
    
    ' Assign rg to range B4 to F10
    Set rg = sh.Range("B4:F10")
    
    ' Assign rg to range E1
    Set rg = sh.Cells(1, 5)
    
End Sub

If you want to know more about these objects you can check out these articles: VBA Workbook, VBA Worksheet and VBA Ranges and Cells.

Using Dim with Class Module Objects

In VBA we use Class Modules to create our own custom objects. You can read all about Class Modules here.

If we are creating an object then we need to use the New keyword.

We can do this in the Dim statement or in the Set statement.

The following code creates an object using the New keyword in the Dim statement:

' Declare and create
Dim o As New class1
Dim coll As New Collection

Using New in a Dim statement means that exactly one object will be created each time our code runs.

Using Set gives us more flexibility. We can create many objects from one variable. We can also create an object based on a condition.

This following code shows how we create a Class Module object using Set.

(To create a Class Module, go to the project window, right-click on the appropiate workbook and select “Insert Class Module”. See Creating a Simple Class Module for more details.)

' Declare only
Dim o As Class1

' Create using Set
Set o = New Class1

Let’s look at an example of using Set. In the code below we want to read through a range of data. We only create an object if the value is greater than 50.

We use Set to create the Class1 object. This is because the number of objects we need depends on the number of values over 50.

' https://excelmacromastery.com/
Sub UsingSet()
    
    ' Declare a Class1 object variable
    Dim o As Class1
    
    ' Read a range
    Dim i As Long
    For i = 1 To 10
        If Sheet1.Range("A" & i).Value > 50 Then

            ' Create object if condition met
            Set o = New Class1
            
        End If
    Next i

End Sub

I’ve kept this example simple for clarity. In a real-world version of this code we would fill the Class Module object with data and add it to a data structure like a Collection or Dictionary.

Here is an example of a real-world version based on the data below:

dim sample data

' Class Module - clsStudent
Public Name As String
Public Subject As String

' Standard Module
' https://excelmacromastery.com/
Sub ReadMarks()

    ' Create a collection to store the objects
    Dim coll As New Collection
    
    ' Current Region gets the adjacent data
    Dim rg As Range
    Set rg = Sheet1.Range("A1").CurrentRegion
    
    Dim i As Long, oStudent As clsStudent
    For i = 2 To rg.Rows.Count
        
        ' Check value
        If rg.Cells(i, 1).Value > 50 Then
            ' Create the new object
            Set oStudent = New clsStudent
            
            ' Read data to the student object
            oStudent.Name = rg.Cells(i, 2).Value
            oStudent.Subject = rg.Cells(i, 3).Value
            
            ' add the object to the collection
            coll.Add oStudent
            
        End If
        
    Next i
    
    ' Print the data to the Immediate Window to test it
    Dim oData As clsStudent
    For Each oData In coll
        Debug.Print oData.Name & " studies " & oData.Subject
    Next oData

End Sub

To learn more about Set you can check out here.

Objects from an External Library

A really useful thing we can do with VBA is to access external libraries. This opens up a whole new world to what we can do.

Examples are the Access, Outlook and Word libraries that allow us to communicate with these applications.

We can use libraries for different types of data structures such as the Dictionary, the Arraylist, Stack and Queue.

There are libraries for scraping a website (Microsoft HTML Object Library), using Regular Expressions (Microsoft VBScript Regular Expressions) and many other tasks.

We can create these objects in two ways:

  1. Early Binding
  2. Late Binding

Let’s look at these in turn.

Early Binding

Early binding means that we add a reference file. Once this file is added we can treat the object like a class module object.

We add a reference using Tools->Reference and then we check the appropriate file in the list.

For example, to use the Dictionary we place a check on “Microsoft Scripting Runtime”:

vba references dialog

Once we have the reference added we can use the Dictionary like a class module object

' https://excelmacromastery.com/
Sub EarlyBinding()

    ' Use Dim only
    Dim dict1 As New Dictionary
    
    ' Use Dim and Set
    Dim dict2 As Dictionary
    Set dict2 = New Dictionary

End Sub

The advantage of early binding is that we have access to the Intellisense. The disadvantage is that it may cause conflict issues on other computers.

The best thing to do is to use early binding when writing the code and then use late binding if distributing your code to other users.

Late Binding

Late binding means that we create the object at runtime.

We declare the variable as an “Object” type. Then we use CreateObject to create the object.

' https://excelmacromastery.com/
Sub LateBinding()

    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")
    
End Sub

Using Dim with Arrays

There are two types of arrays in VBA. They are:

  1. Static – the array size is set in the Dim statement and it cannot change.
  2. Dynamic – the array size is not set in the Dim statement. It is set later using the ReDim statement.
' STATIC ARRAY

' Stores 7 Longs - 0 to 6
Dim arrLong(0 To 6) As Long

' Stores 7 Strings - 0 to 6
Dim arrLong(6) As String

A dynamic array gives us much more flexibility. We can set the size while the code is running.

We declare a dynamic array using the Dim statement and we set the size later using ReDim.

' DYNAMIC ARRAY

' Declare the variable
Dim arrLong() As Long

' Set the size
ReDim arrLong(0 To 6) As Long

Using ReDim

The big difference between Dim and ReDim is that we can use a variable in the ReDim statement. In the Dim statement, the size must be a constant value.

' https://excelmacromastery.com/
Sub UserSet()

    ' Declare the variable
    Dim arrLong() As Long
    
    ' Ask the user for the size
    Dim size As Long
    size = InputBox("Please enter the size of the array.", Default:=1)
    
    ' Set the size based on the user input
    ReDim arrLong(0 To size) As Long

End Sub

We can actually use the Redim Statement without having first used the Dim statement.

In the first example you can see that we use Dim:

' https://excelmacromastery.com/
Sub UsingDimReDim()

    ' Using Dim
    Dim arr() As String

    ReDim arr(1 To 5) As String
    
    arr(1) = "Apple"
    arr(5) = "Orange"
    
End Sub

In the second example we don’t use Dim:

' https://excelmacromastery.com/
Sub UsingReDimOnly()

    ' Using  ReDim only
    ReDim arr(1 To 5) As String
    
    arr(1) = "Apple"
    arr(5) = "Orange"
    
End Sub

The advantage is that you don’t need the Dim statement. The disadvantage is that it may confuse someone reading your code. Either way it doesn’t make much difference.

You can use the Preserve keyword with ReDim to keep existing data while you resize an array. You can read more about this here here.

You can find everything you need to know about arrays in VBA here.

Troubleshooting Dim Errors

The table below shows the errors that you may encounter when using Dim. See VBA Errors for an explanation of the different error types.

Error Type Cause
Array already dimensioned Compile Using Redim on an array that is static
Expected: identifier Syntax Using a reserved word as the variable name
Expected: New of type name Syntax The type is missing from the Dim statement
Object variable or With block variable not set Runtime New was not used to create the object(see Creating an Object)
Object variable or With block variable not set Runtime Set was not used to assign an object variable.
User-defined type not defined Compile The type is not recognised. Can happen if a reference file is not added under Tools->Reference or the Class Module name is spelled wrong.
Statement invalid outside Type block Compile Variable name is missing from the Dim statement
Variable not defined Compile The variable is used before the Dim line.

Local versus Module versus Global Variables

When we use Dim in a procedure (i.e. a Sub or Function), it is considered to be local. This means it is only available in the procedure where it is used.

The following are the different types of variables found in VBA:

  • Local variables are variables that are available to the procedure only. Local variables are declared using the Dim keyword.
  • Module variables are variables that are only available in the current module only. Module variables are declared using the Private keyword.
  • Global variables are variables that are available to the entire project. Global variables are declared using the Public keyword.

In the code below we have declared count as a global variable:

 ' Global
 ' https://excelmacromastery.com/
 Public count As Long

 Sub UseCount1()

    count = 6
    
 End Sub

 Sub UseCount2()

    count = 4
    
 End Sub

What happens if we have a global variable and a local variable with the same name?

It doesn’t actually cause an error. VBA gives the local declaration precedence:

 ' https://excelmacromastery.com/

 ' Global
 Public count As Long 

 Sub UseCount()
    ' Local
    Dim count As Long
    
    ' Refers to the local count
    count = 6
    
 End Sub

Having a situation like this can only lead to trouble as it is difficult to track which count is being used.

In general global variables should be avoided. They make the code very difficult to read because their values can be changed anywhere in the code. This makes errors difficult to spot and resolve.

The one use of a global variable is retaining a value between code runs. This can be useful for certain applications where you want to ‘remember’ a value after the code has stopped running.

In the code below we have a sub called Update. Each time we run the Update sub(using Run->Run Sub from the menu or F5) it will add 5 to the amount variable and print the result to the Immediate Window(Ctrl + G to view this window):

 Public amount As Long

 Sub Update()
    amount = amount + 5
    Debug.Print "Update: " & amount
 End Sub

The results are:

First run: amount = 5

Second run: amount = 10

Third run: amount = 15

and so on.

If we want to clear all global variable values then we can use the End keyword. Note that the End keyword will stop the code and reset all variables so you should only use it as the last line in your code.

Here is an example of using the End keyword:

Sub ResetAllGlobals()
    End ' Resets all variables and ends the current code run
End Sub

Dim versus Private versus Public

We can declare variables using Public, Private and Dim. In some cases, they can be used interchangeably.

However, the following is the convention we use for each of the declaration keywords:

  1. Dim – used to declare local variables i.e. available only in the current procedure.
  2. Private – used to declare module variables and procedures. These are available within the current module only.
  3. Public – used to declare global variables and procedures. These are available throughout the project.
  4. Global(obsolete) – an older and obsolete version of Public. Can only be used in standard modules. It only exists for backward compatibility.

Note the Public and Private keywords are also used within Class Modules.

Conclusion

This concludes the article on the VBA Dim Statement. If you have any questions or thoughts then please let me know in the comments below.

What’s Next?

Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out the The Ultimate VBA Tutorial.

Related Training: Get full access to the Excel VBA training webinars and all the tutorials.

(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)

Переменные, типы данных и константы

Главное предназначение VB А — обработка данных. Некоторые данные сохраняются в объек­тах, например, диапазонах рабочих листов. Другие данные хранятся в созданных вами переменных.

Переменная представляет собой именованное место хранения данных в памяти компью­тера.

Переменные могут содержать данные разных типов — от простых логических, или бу­левых, значений ( True или False ) до больших значений с двойной точностью (см. следующий раздел).

Значение присваивается переменной с помощью оператора равенства (подробнее об этом — далее в главе).

VBA поддерживает несколько огра­ничений в именовании переменных:

  • Можно использовать в названиях символы букв, числа и некоторые знаки препи­нания, но первой в имени переменной всегда должна вводиться буква.
  • VBA не различает регистры.
  • Нельзя использовать в именах пробелы или точки.
  • Чтобы сделать имена переменных удобочитаемыми, используют смешанный регистр (например, InterestKate , а не interestkate ) или вводят символ подчеркивания ( lnterest _ Rate ).
  • Специальные символы объявления типов (#, $, %, & или !) не применяются в имени переменной.
  • Названия переменных ограничены длиной 254 символов.
  • Не допускается применять в качестве названий переменных или процедур зарезервированные слова, т.е. такие слова, которые используются VBA .

Определение типов данных

  • Тип данных указывает, в каком виде данные хранятся в памяти: как целые значения, дей­ствительные числа, текст н т.п.
  • VBA может автоматически типизировать данные, что приводит к медленному выполнению операций и не эффективному использованию памяти.
  • При явном объявлении типа данных всех используемых пе­ременных VBA может выполнять дополнительную проверку ошибок на эта­пе компиляции.
  • При явном объявлении типа данных программа работает быстрее и занимает меньше места в оперативной памяти.
  • Чтобы обеспечить обязательное объявление всех используемых переменных, необходимо включить строку
    Option . Explicit
    в качестве первой инструкции в модуле VBA .

В таблице перечислены поддерживаемые в VBA типы данных

Тип данных

Резервируется байт

Наименьшее значение

Наибольшее значение

Byte

1

0

255

Boolean

2

False (Ложь)

True (Истина)

Integer

2

-32768

32767

Long

4

-2147483648

2147483647

Single

4

-3.402823 Е38

-1.401298 Е-45

1.401298Е-45

3.402823Е38

Double

8

-1,79769313486232Е308

-4,94065645341247Е-324

4,94065645841247Е-324

1,79769313486232Е308

Currency

8

-922337203685477,5808

922337203685477,5807

Decimal

14

+/-79228162514264337593543950335 без десятичных знаков

+/-7,9228162514264337593543950335 с 28-ью знаками после запятой

Date

8

1 января 100 года

31 декабря 9999 года

Object

4

Любая ссылка на объект

string (пере­менной длины)

10 байт + длина строки

0

приблизительно 2 млрд

string (фикси­рованной длины)

Длина строки

1

65400

Variant (числа)

16

Любое числовое значение в рамках диапазона типа данных Double

Variant (сим­волы)

22 байта + длина строки

0

приблизительно 2 млрд

Пользовательский

Зависит от типа

Зависит от элемента

  • Чтобы в тексте программы распознать тип данных переменной или константы можно использовать стандартную приставку (префикс) в нижнем регистре в названии переменной в соответствии с приведенной таблицей.

Префикс

Тип данных

b

Boolean

i

Integer

l

Long

s

Single

d

Double

с

Currency

dt

Date / Time

str

String

obj

Object

v

Variant

u

Пользовательский

Объявление переменных

  • Если для переменной, используемой в процедуре VBA , не объявлен тип данных, то, по умолчанию, будет задан тип данных Variant .
  • Данные, которые хранятся в Variant , изменяют свой тип, в зависимости от того, ка­кие операции над ними выполняются.
    Пример 1 .

Sub VariantDemo ()

MyVar = «123»

MyVar = MyVar / 2

MyVar = «Ответ: » & MyVar

MsgBox MyVar

End Sub

  • При обработке типа дан­ных Variant могут возникнуть проблемы.
    Пример 2 . Какое сообщение выдаст следующая процедура?

Sub VariantDemo 2()

MyVar = «123»

MyVar = MyVar + MyVar

MyVar = «Ответ: » & MyVar

MsgBox MyVar

End Sub

Функция определения типа данных

Для определения типа данных переменной используется функция VBA TypeName .

Пример 1.

Sub VariantDemo2()

MyVar = «123»

MsgBox TypeName(MyVar)

MyVar = MyVar / 2

MsgBox TypeName(MyVar)

MyVar = «Ответ: » & MyVar

MsgBox TypeName(MyVar)

MsgBox MyVar

End Sub

Тестирование явного объявления типов данных

Чтобы оценить важность определения типа данных, рассмотрим следующую процедуру, в которой выполняются циклические вычисления, а затем отображается общее время выпол­нения процедуры.

Sub TimeTestU

Dim x As Integer, у As Integer

Dim A As Integer, В As Integer, С As Integer

Dim i As Integer, j As Integer

Dim StartTime As Date, EndTime As Date

‘ Сохранение времени начала вычислений

StartTime = Timer

‘ Выполнение вычислений

х = 0

у = 0

For i = 1 То 5000

For j = 1 То 1000

А = х + у + i

В = у — х — i

С = х — у — i

Next j

Next i

‘ Получение времени окончания вычислений

EndTime = Timer

‘ Отображение общего времени

MsgBox Format(EndTime – StartTime)

End Sub

Задача.

Сравните время выполнения этой программы и время выполнения этой же программы при превращении операторов Dim в комментарии.

Область действия переменных

Область действия переменной определяет, в каких модулях и процедурах она может ис­пользоваться. Существуют следующие типы областей действия переменных.

Область действия

Способ объявления переменной

Отдельная процедура

В процедуру включается оператор Dim или static

Отдельный модуль

Перед первой процедурой в модуле вводится оператор Dim или private

Все модули

Перед первой процедурой в модуле вводится оператор Public

Локальные переменные

  • Локальная переменная — это переменная, объявленная в процедуре.
  • Локальные перемен­ные могут использоваться только в процедуре, в которой они объявлены.
  • После выполнения процедуры переменная становится невостребованной, поэтому Excel освобождает соответст­вующую область памяти.
  • Если требуется сохранить значение переменной, объявите ее как static .
  • Чтобы объявить локальную переменную — вставьте оператор Dim между операторами Sub и End Sub .
  • Dim – сокращение от Dimension (Размерность). В старых версиях BASIC этот оператор использовался исключительно для объявления размерности массива.
  • Другой способ указания типа данных для переменной : язык VBA позволяет присоединить символ к на­званию, чтобы указать ее тип данных.
    Пример, можно объявить пере­менную MyVar как целое число, добавив к ее названию символ %: Dim MyVar %
  • Символы объявления типов данных представлены для большинства типов данных VBA (отсутствующие в таблице типы данных не имеют собственного символа объявления типа).

Тип данных

Символ объявления типа

Integer

%

Long

&

Single

!

Double

#

Currency

@

String

S

•  Локальные переменные позволяют экономно использовать память, так как VBA освобождает память, которую они используют, после окончания выполнения процедуры.

Переменные уровня модуля

Иногда необходимо, чтобы переменная была доступна во всех процедурах модуля. В та­ком случае объявите переменную перед первой процедурой модуля (за пределами процедур или функций).

В приведенном ниже примере оператор Dim — первая инструкция в модуле. Обе проце­дуры MySub и YourSub имеют доступ к переменной CurrentValue .

Dim CurrentValue As Integer

Sub MySub{)

‘ -[Здесь вводится текст процедуры] —

End SUb

Sub YourSub()

‘-[Здесь вводится текст процедуры] —

End Sub

Значение переменной уровня модуля не изменяется при окончании выполнения процедуры.

Переменные Public

Чтобы сделать переменную доступной во всех процедурах всех модулей VBA в проекте, необ­ходимо объявить переменную на уровне модуля с помощью ключевого слова Public перед первой процедурой модуля, например, так:

Public CurrentRate as Long

Код объявления пере­менных Public должен вводиться в стандартном модуле VB А, а не в коде модуля листа или формы.

Переменные Static

Переменные Static — особый случай. Они объявляются на уровне процедуры и сохра­няют свое значение после окончания процедуры.

Sub MySub()

Static Counter As Integer

‘-[Здесь вводится текст процедуры] –

End Sub

Работа с константами

Константа – имено­ванное значение или строка, которая не меняется при выполнении программы.

Объявление констант

Константы объявляются с помощью оператора Const .

Примеры :

Const NumQuarters as Integer = 4

Const Rate = .0725, Period = 12

Const ModName as String = «Budget Macros»

Public Const AppName as String = «Budget Application»

Во втором примере тип данных не объявлен. Следовательно, указанные две константы имеют тип Variant .

Константы имеют область действия как и переменные.

Область действия

Способ объявления константы

Отдельная процедура

В процедуре или функции

Отдельный модуль

Перед первой процедурой в модуле

Все модули

Перед первой процедурой в модуле с ключевым словом Public

При попытке изменить значение константы в процедуре VBA вы получите ошибку.

Использование предопределенных констант

В Excel и VBA существует целый ряд предопределенных констант, которые можно ис­пользовать без объявления.

В сле­дующей процедуре для изменения ориентации страницы активного листа на альбомную при­менена встроенная константа ( xlLandscape ):

Sub SetToLandscape()

ActiveSheet.PageSetup.Orientation = xlLandscape

End Sub

Константу xlLandscape можно обнаружить путем записи макроса.

Описание констан­т можно найти в справочной системе.

Если включен параметр AutoList Members , то можно получить помощь непосредственно при вводе кода. Во многих случаях VBA автоматически перечисляет все константы, присваиваемые опреде­ленному свойству.

Управление строками

В VBA представлено два типа строк.

  • Строки фиксированной длины объявляются с определенным количеством символов. Максимальная длина строки составляет 65535 символов.
  • Строки переменной длины теоретически могут вмещать до 2 млрд. символов.

Память для строки отводится из расчета 1 байт на каждый символ и для хранения заголовка строки.

В следующем примере переменная MyString объявляется как строка с максимальной длиной 50 символов. YourString тоже объявлена как строка, но она имеет переменную

длину:

Dim MyString As String * 50

Dim YourString As String

Работа с датами

Переменная, определенная как Date , занимает 8 байт памяти и может содержать даты в диапазоне от 1 января 100 года до 31 декабря 9999 года.

В VBA дата и время определяются как значения, заключенные между знаками # (см. далее).

Ошибка дат в Excel

В Excel используется неправильное предположение, что 1900 год – високосный.

В ячейке с формулой =ДАТА(1900;2;29) появится значение 29 февраля 1900 года.

Функция DateSerial (190 Q ,2,29) в VBA возвратит 1 марта 1900 года (!).

Операторы присвоения

Оператор присвоения — это инструкция VBA , выполняющая математическое вычисление и присваивающая результат переменной или объекту.

Выражение определяется как комбинация ключевых слов, операторов, переменных и констант. Эта комбинация возвращает в результате строку, число или объект. Выражение может осуществлять вычисление, обрабатывать символы или тестировать данные.

В VBA оператором присвоения выступает знак равенства (=).

Примеры использования операторов присвоения (выражения приводятся справа от знака равенства):

х = 1

X = X + 1

х = ( у * 2) ! ( г * 2) FileOpen = True FileOpen = Not FileOpen Range С «The Year»).Value = 2001

Выражения могут быть очень сложными. Чтобы сделать длинные выражения более удобными для восприятия, используйте символ продолжения строки (пробел с подчеркиванием).

Зачастую в выражениях применяются функции. Это могут быть встроенные функции VBA , функции рабочих листов Excel или специальные функции, разработанные в VBA .

Булевы операторы VBA

Таблица. Булевы операторы VBA

Оператор

Действие

not

Логическое отрицание выражения

And

Логическая конъюнкция двух выражений

Or

Логическая дизъюнкция двух выражений

xoR

Логическое отрицание двух выражений

Eqv

Логическая эквивалентность двух выражений

imp

Логическая импликация двух выражений

Примеры.

  1. Свойство DisplayGridLines принимает значение True или False . Следовательно, применение оператора Not изменяет True на False , a False — на True :
    ActiveWindow . DisplayGridLines = _
    Not ActiveWindow . DisplayGridLines
  2. Представленное далее выражение осуществляет логическую операцию And . Оператор MsgBox отображает True , только если Лисг1 — активный лист и активная ячейка находит­ся в строке 1. Если одно или оба этих условия неверны, оператор MsgBox отображает False :
    MsgBox ActiveSheet . Name = «Лист1» And ActiveCell . Row = 1
  3. Следующее выражение осуществляет логическую операцию Or . Оператор MsgBox отображает True , если активен лист Лист1 или Лист2:
    MsgBox ActiveSheet.Name = » Лист 1″ Or ActiveSheet.Name = » Лист 2″

Массивы

Массив — это именованная группа проиндексированных элементов одного типа. На конкретный элемент массива ссылаются, используя имя массива и индекс. Например, массив MonthNames из 12-ти строк (каждая переменная соответствует названию месяца). Можно обратиться к первому элементу массива как
MonthNames(0), ко второму — как MonthNames(1) и т.д., до MonthNames(11).

Одномерные массивы

Массив объявляется с помощью операторов Dim или Public . Можно определить количество элементов в массиве: введите первый индексный номер, ключевое слово То и последний индексный номер — вся конструкция будет заключена в скобки. Например, так можно объявить массив, содержащий ровно 100 целых чисел:
Dim MyArray(1 To 100) As Integer

Многомерные массивы

Массивы VBA могут иметь до 60-ти измерений. Показанный ниже оператор объявляет двухмерный 100-элементный массив целых чисел:
Dim MyArray(1 To 10, 1 То 10) As Integer

Так присваивается значение элементу предыдущего массива
МуАггау(1, 4) = 125

Трехмерный массив
Dim MyArray(1 To 5, 1 То 6, 1 То 7) As Integer
состоит из 420 чисел типа Double.

Динамические массивы

Динамический массив не имеет предопределенного количества элементов. Динамический массив объявляется с незаполненными значениями в скобках:

Dim MyArray () As Integer

Перед использованием динамического массива необходимо обратиться к оператору
ReDim , указывающему VBA , сколько элементов находится в массиве
или
ReDim Preserve , если решено сохранить текущую длину массива.

Оператор ReDim можно использовать сколько угодно раз, изменяя, если требуется, размер массива.

Переменные объектов

Переменная объекта — это переменная, представляющая целый объект, например, диапазон или рабочий лист. Переменные объектов имеют особое значение по двум причинам:

¦ значительно упрощают программу;

¦ ускоряют выполнение программы.

Переменные объектов, как и обычные переменные, объявляются с помощью оператора Dim или Public . Например, в следующем операторе переменная inputArea объявляется как объект Range : Public InputArea As Range

Чтобы узнать, каким образом переменные объектов упрощают программу, проанализируем процедуру, написанную без их использования:

Sub KoObjVar()

Worksheets(» Лист 1″).Range(«Al»).Value =124

Worksheets(» Лист 1″).Range(«Al»).Font.Bold = True

Worksheets(» Лист 1″).Range(«Al»).Font.Italic = True

End Sub

Эта процедура вводит значение в ячейку А1 листа Лист1 активной рабочей книги, а затем делает шрифт содержимого ячейки полужирным и курсивным. В примере введено довольно много кода для такой простой операции. Чтобы пощадить себя, сведите процедуру к исполь­зованию объектной переменной:

Sub ObjVar()

Dim MyCell As Range

Sec MyCell = Worksheets(» Лист 1″).Range(«Al»)

MyCell.Value =124

MyCell.Font.Bold = True

MyCell.Font.Italic = True

End Sub

После объявления переменной MyCell как объекта Range оператор Set присваивает ей сам объект. В результате в следующих операторах используется упрощенная ссылка MyCell вместо длинной Worksheets (» Лист1″) . Range(» Al «).

Пользовательские типы данных

VBA позволяет создавать специальные, или пользовательские, типы данных . Определенный пользователем тип данных может облегчить управление некоторыми типами данных. Например, если приложение обрабатывает сведения о клиенте, то можно создать пользовательский тип данных с названием
Customerlnfo:

Type Customerlnfo
Company As String * 25
Contact As String * 15
RegionCode As Integer
Sales As Long
End Type

Пользовательские типы данных определяются вверху модуля перед началом

Если пользовательский тип данных уже создан для объявления переменной этого типа примените оператор Dim . Обычно пользовательский тип данных определяется для массивов:

Dim Customers ( 1 To 100) As Customerlnfo

Все 100 элементов этого массива состоят из четырех компонентов (как указано в пользовательском типе данных— Customerlnfo ). Вы можете сослаться на конкретный компонент элемента :

Customers(5).Company = «Acme Tools»

Customers(1).Contact = «Tim Robertson»

Customers(1).RegionCode = 3

Customers(1).Sales = 150677

Чтобы скопировать информацию из Customers (1) в Customers ( 2 ), используется следующая инструкция:

Customers (2) = Customers (1)

Предыдущий пример эквивалентен приведенному далее блоку инструкций:

Customers(2).Company = Customers(1).Company

Customers(2).Contact = Customers(1).Contact

Customers(2}.RegionCode = Customers(1).RegionCode

Customers(2).Sales = Customers(1).Sales

Variables are used in almost all computer program and VBA is no different. It’s a good practice to declare a variable at the beginning of the procedure. It is not necessary, but it helps to identify the nature of the content (text, data, numbers, etc.)

In this VBA tutorial, you will learn-

  • VBA Variables
  • VBA Data Types
  • Constant in VBA

Variables are specific values that are stored in a computer memory or storage system. Later, you can use that value in code and execute. The computer will fetch that value from the system and show in the output. Each of the Excel VBA variable types must be given a name.

To name the variable in VBA, you need to follow the following rules.

  • It must be less than 255 characters
  • No spacing is allowed
  • It must not begin with a number
  • Period is not permitted

Here are some example for Valid and Invalid names for variables in VBA.

VBA Data Types, Variables & Constant Valid Names VBA Data Types, Variables & Constant Invalid Names
My_Watch My.Watch
NewCar1 1_NewCar (not begin with number)
EmployeeID Employee ID ( Space not allowed)

In VBA, we need to declare the variables before using them by assigning names and data type.

In VBA, Variables are either declared Implicitly or Explicitly.

  • Implicitly: Below is an example of a variable declared Implicitly.
  • label=guru99
  • volume=4
  • Explicitly: Below is an example of variable declared Explicitly. You can use “Dim” keyword in syntax
  • Dim Num As Integer
  • Dim password As String

VBA variable is no different than other programming languages. To declare a variable in VBA you use the keyword “Dim.”

Syntax for VBA Variable,

To declare a variable in VBA, type Dim followed by a name:

Sub Exercise ()
        Dim <name>
End Sub

Before we execute the variables we have to record a macro in Excel. To record a macro do the following –

Step 1): Record the Macro 1

Step 2) : Stop Macro 1

Step 3): Open the Macro editor, enter the code for variable in the Macro1

Step 4): Execute the code for Macro 1

Example, for VBA Variable

Sub Macro1()
	Dim Num As Integer
	Num = 99
	MsgBox " Guru " & Num
End Sub

When you run this code, you will get the following output in your sheet.

VBA Data Types, Variables & Constant

Excel VBA Data Types

Computer cannot differentiate between the numbers (1,2,3..) and strings (a,b,c,..). To make this differentiation, we use Data Types.

VBA data types can be segregated into two types

  • Numeric Data Types
Type Storage Range of Values
Byte 1 byte 0 to 255
Integer 2 bytes -32,768 to 32,767
Long 4 bytes -2,147,483,648 to 2,147,483,648
Single 4 bytes -3.402823E+38 to -1.401298E-45 for negative values 1.401298E-45 to 3.402823E+38 for positive values.
Double 8 bytes -1.79769313486232e+308 to -4.94065645841247E-324 for negative values
4.94065645841247E-324 to 1.79769313486232e+308 for positive values.
Currency 8 bytes -922,337,203,685,477.5808 to 922,337,203,685,477.5807
Decimal 12 bytes +/- 79,228,162,514,264,337,593,543,950,335 if no decimal is use +/- 7.9228162514264337593543950335 (28 decimal places)
  • Non-numeric Data Types
Data Type Bytes Used Range of Values
String (fixed Length) Length of string 1 to 65,400 characters
String (Variable Length) Length + 10 bytes 0 to 2 billion characters
Boolean 2 bytes True or False
Date 8 bytes January 1, 100 to December 31, 9999
Object 4 bytes Any embedded object
Variant(numeric) 16 bytes Any value as large as Double
Variant(text) Length+22 bytes Same as variable-length string

In VBA, if the data type is not specified, it will automatically declare the variable as a Variant.

Let see an example, on how to declare variables in VBA. In this example, we will declare three types of variables string, joining date and currency.

Step 1) Like, in the previous tutorial, we will insert the commandButton1 in our Excel sheet.

VBA Data Types, Variables & Constant

Step 2) In next step, right-click on the button and select View code. It will open the code window as shown below.

VBA Data Types, Variables & Constant

Step 3) In this step,

VBA Data Types, Variables & Constant

Step 4) Turn off design mode, before clicking on command button

VBA Data Types, Variables & Constant

Step 5) After turning off the design mode, you will click on commandButton1. It will show the following variable as an output for the range we declared in code.

  • Name
  • Joining Date
  • Income in curreny

VBA Data Types, Variables & Constant

Constant in VBA

Constant is like a variable, but you cannot modify it. To declare VBA constants, you can use keyword Const.

There are two types of constant,

  • Built-in or intrinsic provided by the application.
  • Symbolic or user defined

You can either specify the scope as private by default or public. For example,

Public Const DaysInYear=365

Private Const Workdays=250

Download Excel containing above code

Download the above Excel Code

Summary:

  • Variables are specific values that are stored in a computer memory or storage system.
  • You can use VBA Dim types keyword in syntax to declare variable explicitly
  • VBA data types can be segregated into two types
  • Numeric Data Types
  • Non-numeric Data Types
  • In VBA, if the data type is not specified. It will automatically declare the variable as a Variant
  • Constant is like a variable, but you cannot modify it. To declare a constant in VBA you use keyword Const.

In this Article

  • Integer (Int) Variable Type
    • Long Variable Type
  • Decimal Values & Int Data Types
    • Decimal / Double Data Type
  • Declare Int Variable at Module or Global Level
    • Module Level
    • Global Level
  • Convert String to Int
  • Convert Int to String
    • Format Integer Stored as String

Integer (Int) Variable Type

The VBA Int data type is used to store whole numbers (no decimal values). However as we’ll see below, the Integer values must fall within the range ‑32768 to 32768.

To declare an Int variable, you use the Dim Statement (short for Dimension):

Dim intA as Integer

Then, to assign a value to a variable, simply use the equal sign:

intA = 30000

Putting this in a procedure looks like this:

Sub IntExample()
'declare the integer
   Dim intA as Integer
'populate the integer
   intA = 30000
'show the message box
   MsgBox intA
End Sub

If you run the code above, the following message box will be shown.

vba integer intexample msgbox

Long Variable Type

As mentioned above, Int variables can only store values between ‑32768 to 32768. If you attempt to assign a value outside that range to an Int variable you’ll receive an error:

vba integer intexample overflow error

When you click on de-bug, the code will break at the ‘populate the integer line as an integer cannot store a number as high as 50000.

vba integer intexample overflow debug

Instead, you can declare a variable with the Long data type:

Dim longA as Long

Long Variables can store very long data types (-2,147,483,648 to 2,147,483,648).

<<link to long variable article>>

Why would you use Int variables instead of Long variables?

Long variables use more memory. Years ago, memory was a big concern when writing code, however now computing technology is much improved and it’s doubtful you’ll encounter memory issues caused by long variables when writing VBA code.

We recommend always using Long variables instead of Int variables. We will continue this tutorial discussing Int variables, but keep in mind that you can use the Long variable type instead.

Decimal Values & Int Data Types

Int variables can not store decimal values. If you pass a decimal number an integer, the decimal number will be rounded to remove the decimal.

Therefore, if you were to run the procedure below:

Sub IntExampleB() 
'declare the integer
   Dim intA as Integer 
'populate the integer 
   intA = 3524.12
'show the message box 
   MsgBox intA 
End Sub

You would get the following result (rounding down):

vba integer passing decimal round down msgbox

However, this code below:

Sub IntExampleB()
 'declare the integer 
   Dim intA as Integer 
'populate the integer 
   intA = 3524.52 
'show the message box 
   MsgBox intA 
End Sub

Would return the following message box (rounding up):

vba integer passing decimal round up msgbox

Decimal / Double Data Type

If you want to store a decimal place, you would need to declare a variable that allows for decimal places.  There are 3 data types that you can use – Single, Double or Currency.

Dim sngPrice as Single
Dim dblPrice as Double
Dim curPrice as Currency

The Single data type will round the decimal point slightly differently to the double and currency data type, so it is preferable to use double to single for accuracy.  A double can have up to 12 decimal places while currency and single can both have up to 4 decimal places.

vba integer double example

For further information about these data types, you can have a look here.

Declare Int Variable at Module or Global Level

In the previous examples, we’ve declared the Int variable within a procedure. Variables declared with a procedure can only be used within that procedure.

vba integer procedure declaration

Instead, you can declare Int variables at the module or global level.

Module Level

Module level variables are declared at the top of code modules with the Dim statement.

vba integer module declaration

These variables can be used with any procedure in that code module.

VBA Coding Made Easy

Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!

automacro

Learn More

Global Level

Global level variables are also declare at the top of code modules. However, instead of using the Dim statement, use the Public statement to indicate that the integer variable is available to be used throughout your VBA Project.

Public IntA as Integer

vba integer global declaration

If you were to declare the integer at a module level and then try to use it in a different module, an error would occur.

vba integer declaration notdefined

However, if you had used the Public keyword to declare the integer, the error would not occur and the procedure would run perfectly.

Convert String to Int

There might be an instance or instances when you will need to convert a number stored as a string to an integer value.

vba integer intexample string to integer immediate

You will notice in the immediate window that the integer value goes to the right indicating a number, while the string value goes to the left – indicating text.

Convert Int to String

Conversely, you can convert an integer value to a string.

vba integer intexample integer to string immediate

For further information about these data types, you can have a look here.

VBA Programming | Code Generator does work for you!

Format Integer Stored as String

<<also talk about the Format function, to assign number formatting>>

Понравилась статья? Поделить с друзьями:
  • Dignity meaning of word
  • Digits to text excel
  • Digital word of mouth marketing
  • Digital signing in word
  • Dig into the word