Хитрости »
Основные понятия (22)
Сводные таблицы и анализ данных (7)
Графики и диаграммы (5)
Работа с VB проектом (11)
Power BI и Power Query (11)
Условное форматирование (5)
Списки и диапазоны (5)
Макросы(VBA процедуры) (62)
Разное (37)

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

Переменная - это некий контейнер, в котором 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.2078)
String 1 От 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 и т.д. Т.е. это книги, листы, ячейки, диаграммы. Типов много, почти на каждый объект и коллекцию. Рассматривать здесь все бессмысленно. Могу лишь привести пару строк кода:

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


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

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

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

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

Всего шесть типов, которые можно объявить подобным методом:
! - Single
# - Double
$ - String
% - Integer
& - Long
@ - Currency

На что стоит обратить внимание, при объявлении переменных подобным образом: между именем переменной и знаком типа не должно быть пробелов.
Я лично предпочитаю использовать первый метод, т.е. полное указание типа. Это читабельнее и понятнее. Но это мои предпочтения и в своих кодах Вы вправе использовать удобный Вам метод - ошибки не будет.

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

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

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

    Правильное объявление

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


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

"Что самое сложное в работе программиста? - выдумывать имена переменным." :-)А ведь придумать имя переменной тоже не так-то просто. Можно, конечно, давать им имена типа: 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, при помощи которых можно указать тип данных по умолчанию для переменных, первая буква имени которых попадает в заданный в операторе диапазон. Например:

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

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

Ниже приведен полный перечень операторов типов и данные, которые задает каждый из них:
DefBool - Задает тип Boolean
DefByte - Задает тип Byte
DefCur - Задает тип Currency
DefDate - Задает тип Date
DefDbl - Задает тип Double
DefInt - Задает тип Integer
DefLng - Задает тип Long
DefObj - Задает тип Object
DefSng - Задает тип Single
DefStr - Задает тип String
DefVar - Задает тип Variant

По умолчанию в VBA применена инструкция DefVar для всех переменных.

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


 
Небольшой пример использования переменных в кодах:

Просмотреть пошагово выполнение данного кода поможет статья: Отлов ошибок и отладка кода VBA
Важно! Если переменной назначается ссылка на ячейку(Set var = Range("A1")), то обращение к переменной идентично обращению в самой ячейке А1 когда бы это ни происходило. Такое назначение не запоминает свойства ячейки до или после - в переменной хранится ссылка на конкретную ячейку и доступ есть исключительно к свойствам ячейки на текущий момент. Чтобы запомнить значение, цвет ячейки или даже адрес (а так же и другие свойства) до изменения ячейки и применить их даже после изменения/перемещения самой ячейки - необходимо запоминать в переменные именно свойства ячейки:

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



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

Константам могут быть назначены данные тех же типов, что и для переменных. И область видимости/жизни переменных задается так же операторами Public и Static. Здесь обращаю внимание на то, что Dim уже не используется, т.к. Dim это идентификатор только для переменных. Пару важных отличий объявления констант от объявления переменных:

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

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

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

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

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

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


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

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

Access Multex Outlook Power Query и Power BI VBA работа в редакторе VBA управление кодами Бесплатные надстройки Дата и время Диаграммы и графики Записки Защита данных Интернет Картинки и объекты Листы и книги Макросы и VBA Настройка Печать Поиск данных Почта Программы Работа с приложениями Работа с файлами Разработка приложений Сводные таблицы Списки Тренинги и вебинары Финансовые Форматирование Формулы и функции Функции Excel Функции VBA Ячейки и диапазоны акции MulTEx анализ данных ссылки
Обсуждение: 13 комментариев
  1. Александр:

    в вашем примере - где поиск первой заполненной ячейки есть строка

    Dim lFirstRow As Long, lFirstCol As Long, rFndRng As Range

    что такое "RANGE"? Здесь не нашел описания

    0
  2. Алексанадр - Range это объект Excel - диапазон. Здесь он не описан, т.к. он напрямую к VBA не относится, а является частью объектной модели Excel. А все доступные из Excel объекты перечислить даже одной страницы не хватит(диапазон, ячейка, диаграммы и отдельные элементы диаграмм, кнопки и т.д.).

    0
  3. Staniiislav:

    Здравствуйте, подскажите пожалуйста, почему некоторые программисты объявляют переменные внутри самой процедуры.
    Допустим идут какие-то вычисления, затем переменой Text$ присваиваются какое-то значение, вопрос правильно присваивать значение переменно Text в начале программного кода, или можно и в самой процедуре? И в чем разница?
    Спасибо

    0
  4. Staniiislav, все зависит от логики кода. Можно и вначале присвоить, можно и в середине. Переменная для того и нужна, чтобы можно было менять её значение в зависимости от задачи и по ходу её выполнения.
    Притом вначале программного кода(вне процедуры) в VBA значение можно назначить исключительно константе. Переменную можно только объявить. А назначать значение в любом случае придется внутри процедуры.
    В более продвинутых языках(например С#, C++ и пр.) назначать значение переменной можно сразу при объявлении(даже более грамотно назначать при объявлении, чтобы они не хранили "мусор").

    0
  5. Staniiislav:

    Понятно! Спасибо за пояснение!

    0
  6. lik:

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

    0
  7. Василий:

    Добрый день!
    Подскажите, пожалуйста, как объявить переменную (Target), что бы с ней работал оператор GoTo
    GoTo Target

    0
  8. Василий, никак. Метки нельзя именовать или сделать переменными. Но уверен, что проще пересмотреть логику кода - GoTo в большинстве случаев не нужен и среди некоторых программистов вообще считается его использование дурным тоном.

    0
    • GoTo оправдано при использовании метода On Error для предотвращения последствий критических ошибок. Всё зависит от реализации ТЗ.

      0
  9. Василий:

    Спасибо, Дмитрий!
    Но в моем случае без этого никак((
    Да и не программист я..

    0
  10. Алексей:

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

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

    Дмитрий, Вы уверены?

    Согласно Microsoft, я так понимаю, это одно и тоже
    https://msdn.microsoft.com/ru-ru/library/ke6sh835.aspx#Объявление типа данных

    0
    • Алексей, я уверен. Статья, на которую Вы ссылаетесь описывает правила именования переменных в среде NET. А NET и VBA это разные вещи. Попробуйте воспользоваться окном Locals в VBA, объявить переменные так, как написано у меня и как написано в статье по ссылке Вашей. Посмотрите, какие типы будут назначены в этих случаях переменным.

      0
Поделитесь своим мнением

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


Для оформления сообщений Вы можете использовать следующие тэги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Тренинги

Заказать
Наши партнеры
Перейти
Перейти
Счетчики
Анализ сайта

Яндекс.Метрика
© 2017 Excel для всех  Войти
Авторизация
*
*
Регистрация
*
*
*
Пароль не введен
*
captcha
Генерация пароля