Vba excel позднее связывание

Раннее и позднее связывание переменных с экземплярами внешних и внутренних объектов в VBA Excel. Преимущества ранней привязки объектов. Примеры кода.

Связывание – это процесс назначения внутреннего или внешнего объекта переменной.

Внутренними называются объекты, которые принадлежат объектной модели Excel (Range, Sheet, Workbook, Chart). Внешние объекты не принадлежат объектной модели Excel. А также новый экземпляр Excel.Application является внешним объектом по отношению к тому экземпляру приложения Excel, из которого он создается.

Раннее связывание

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

Определение типа объекта при ранней привязке выполняется еще до запуска приложения.

Объявление переменной определенного типа

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

‘Внутренние объекты

Dim myRange As Range

Dim mySheet As Sheets

Dim myWorkbook As Workbook

‘Внешние объекты

Dim myDictionary As Dictionary

Dim myExcel As Excel.Application

Dim myWord As Word.Application

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

‘Внутренние объекты

Set myRange = Range(«A1:D10»)

Set mySheet = Sheets(1)

Set myWorkbook = Workbooks.Open(«C:Книга1.xlsm»)

‘Внешние объекты

Set myDictionary = New Dictionary

Set myExcel = New Excel.Application

Set myWord = New Word.Application

Присвоение переменной объекта при объявлении

Присвоение переменной, при ее объявлении, нового экземпляра внешнего объекта:

Dim myDictionary As New Dictionary

Dim myExcel As New Excel.Application

Dim myWord As New Word.Application

Ссылка на библиотеку внешнего объекта

Чтобы использовать раннее связывание для внешнего объекта, необходимо подключить в редакторе VBA Excel ссылку на библиотеку этого объекта, если она еще не подключена. Подключается ссылка на библиотеку в окне «References VBAproject», перейти в которое можно через главное меню редактора: Tools–>References…

Ссылка на библиотеку Microsoft Scripting Runtime, которая необходима для ранней привязки объекта Dictionary:

Ссылка на библиотеку Microsoft Word Object Library, которая необходима для ранней привязки объекта Word.Application:

После выбора библиотеки следует нажать кнопку «OK».

Преимущества ранней привязки

Главное преимущество раннего связывания заключается в возможности использовать при написании кода VBA Excel лист выбора и вставки свойств-методов привязанных объектов (Auto List Members). Лист подсказок отображается автоматически или вызывается сочетанием клавиш «Ctrl+Пробел» или «Ctrl+J».

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

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

Скопируйте процедуру Primer1 с ранней привязкой объекта Sheet в любой программный модуль:

Sub Primer1()

Dim mySheet As Sheet

mySheet

End Sub

Поставьте точку после mySheet в 3 строке и вы увидите лист выбора и вставки свойств-методов:

Если вдруг лист подсказок не отобразился автоматически, его можно вызвать сочетанием клавиш «Ctrl+Пробел» или «Ctrl+J».

Теперь скопируйте процедуру Primer2 с поздней привязкой объекта Sheet в любой программный модуль:

Sub Primer2()

Dim mySheet As Object

Set mySheet = Sheets(1)

mySheet

End Sub

Поставьте точку после mySheet в 4 строке – лист подсказок не отобразится:

Сочетания клавиш «Ctrl+Пробел» и «Ctrl+J» тоже не помогут. В данном случае тип объекта, присвоенного переменной, определяется только в процессе выполнения программы.

Позднее связывание

Позднее связывание – это присвоение переменной, объявленной как Object, экземпляра внутреннего объекта с помощью ключевого слова Set или экземпляра внешнего объекта с помощью ключевого слова Set и функции GetObject или CreateObject.

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

‘Внутренние объекты

‘Диапазон ячеек

Dim myRange As Object

Set myRange = Range(«A1:D10»)

‘Рабочий лист

Dim mySheet As Object

Set mySheet = Sheets(1)

‘Рабочая книга Excel

Dim myWorkbook As Object

Set myWorkbook = Workbooks.Open(«C:Книга1.xlsm»)

‘Внешние объекты

‘Словарь

Dim myDictionary As Object

Set myDictionary = CreateObject(«Scripting.Dictionary»)

‘Приложение Excel

Dim myExcel As Object

Set myExcel = CreateObject(«Excel.Application»)

‘Приложение Word

Dim myWord As Object

Set myWord = CreateObject(«Word.Application»)

Функция CreateObject используется для создания нового экземпляра объекта, а функция GetObject – для получения сохраненного объекта.

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

МЕНЮ САЙТА

  • 1
  • 2
  • 3

КАТЕГОРИИ РАЗДЕЛА

ОПРОСЫ


AUTOMATION: использование Раннего и Позднего Связывания

Перевод статьи «Using early binding and late binding in Automation» с официального сайта поддержки Майкрософт. Перевод выполнен Романом Вороновым от 14-го июля 2015.

КРАТКОЕ СОДЕРЖАНИЕ

Применяемый способ связывания с сервером Automation (сервис Microsoft, осуществляющий передачу информации между пользовательскими интерфейсами) отражается на производительности, гибкости и на совместимости. Статья объясняет типы связывания и сравнивает плюсы и минусы каждого.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

Automation – это процесс, при котором некоторый программный компонент взаимодействует и / или контролирует другой программный компонент посредством Компонентно-Объектной Модели (на англ. COM) Майкрософта. Этот принцип лежит в основе большинства кросс-компонентных взаимодействий в таких языках как Visual Basic (VB) или Visual Basic for Applications (VBA) и стал неотъемлемой частью большинства программ.

Исторически, объект Automation – это любой объект, поддерживающий интерфейс IDispatch. Этот интерфейс позволяет клиенту запрашивать методы и свойства во время исполнения программы. Происходит это даже без предварительного знания об объекте на стадии разработки, с которым будет взаимодействие. Это называется поздним связыванием. Сегодня, однако, термин «Объект Automation» может быть использован в отношении любого объекта COM, даже не поддерживающего интерфейс IDispatch (и, следовательно, недоступного для позднего связывания). В этой статье предполагается, что объект, который Вы автоматизируете, поддерживает как позднее, так и раннее связывание.

Что же такое связывание?

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

Для большего понимания рассмотрим «связывание» применительно к публикации некоторых материалов. Представьте, что Ваш код – это текст книги, где в каком-то параграфе Вы пишите: «подробности смотрите далее в главе 12, на странице Х». Вы не знаете точный номер страницы, пока книга не закончена. Поэтому до того, как параграф будет прочтён, все страницы книги должны быть «связаны» вместе чтобы Вы могли проставить конкретный номер страницы для ссылки. Приходится ждать, пока книга будет закончена, «связана», чтобы можно было обращаться к разным её частям.

Связывание в программировании носит те же черты. Ваш код состоит из частей, которые должны быть собраны вместе до того, как код может быть «прочтён». Связывание – это замена имён функций на адреса в памяти (или, что точнее, на смещения памяти), куда код будет «прыгать» при вызове этих функций. Для COM объектов адрес – это смещение по памяти в таблице указателей объекта (так называемая v-таблица). COM-функция связывается через таблицу указателей.

Структура COM-объекта довольно проста. Когда код содержит ссылку на объект – он содержит косвенное указание на вершину таблицы указателей. А таблица указателей — ни что иное как массив адресов в памяти, каждая запись которого ведёт к разным функциям данного объекта. Например, для вызова 3-й функции COM-объекта нужно прыгнуть сверху таблицы до 3-й записи и пройти к указанной здесь области памяти. Это исполнит код функции и, по завершению, возвратит нас к исполнению следующей строки основного кода.

Все COM объекты наследуются от интерфейса IUnknown («неизвестный» интерфейс, англ.) и первые три записи в таблице указателей являются методами этого интерфейса. Поэтому, например, при необходимости освободить объект – вызывается третья функция в таблице указателей (IUnknown::Release).

К слову, эта работа выполняется языком Visual Basic самостоятельно, «за кулисами» программирования. Как VB программист, Вам не придётся работать с таблицей указателей напрямую. Однако, это — основа связывания COM-объектов, крайне важная для понимания процесса связывания.

Раннее связывание

Описанный выше пример – классическое раннее связывание (или связывание через таблицу указателей). Для всех COM объектов эта форма связывания имеет место всякий раз, когда вызывается IUnknown интерфейс этого объекта. Но что насчёт других функций этого объекта? Как вызвать метод обновления или родительское свойство? Эти привычные функции уникальны для объекта. А если положение этих функций в таблице указателей заведомо неизвестно, то как найти адреса для их вызова?

Ответ, конечно, зависит от того, знаем ли мы (или нет) заведомо об устройстве таблицы указателей объекта. Если мы знаем, то можно проделать тот же трюк, что ранее описан про освобождение объекта через метод интерфейса IUnknown: «прыжком» заданной длины до нужного места в таблице указателей. Это пример того, что принято считать «ранним связыванием».

Для применения раннего связывания к объекту следует ориентироваться в его таблице указателей. На языке Visual Basic это можно сделать через добавление ссылки на библиотеку типов, описывающую объект, его интерфейс (таблица указателей) и на все функции объекта. После чего можно объявить объект принадлежащим к конкретному типу и использовать объект через его таблицу указателей. Например, если необходимо автоматизировать MSO Excel с использованием раннего связывания – следует добавить ссылку на «Microsoft Excel [?].0 Object Library» (где [?] зависит от версии используемого приложения Excel) в меню «References» (ссылки) проекта и объявить переменную с типом «Excel.Application». С этого момента любой вызов Вашей объектной переменной будет работать с ранним связыванием:

' Задать ссылку на 'Microsoft Excel 8.0 Object Library' в
' Project|References меню (или Tools|References для VB4 или VBA).

' Объявить объект через раннее связывание
 Dim oExcel As Excel.Application
 Set oExcel = CreateObject("Excel.Application")

' Свойство видимости вызывается через таблицу указателей
 oExcel.Visible = True

Этот приём отлично работает в большинстве случаев. Но что, если на стадии разработки нам заведомо неизвестно, какой объект мы будем использовать? К примеру, что, если необходимо обращаться к множеству версий Excel или к вообще неизвестному объекту?

Позднее связывание

COM включает интерфейс IDispatch. Объекты, использующие IDispatch, имеют либо диспинтерфейс (если IDispatch – единственный поддерживаемый ими интерфейс), либо двойной интерфейс (если плюс к первому у них есть привычный интерфейс, к которому можно применить раннее связывание). При использовании IDispatch интерфейса для связывания считается, что применяется «позднее связывание». При этом точные положения свойств и методов, вызываемых клиентом, в ходе работы программы определяются методами самого IDispatch. Возвращаясь к примеру с книгой: представьте, что вместо указания нужной страницы в тексте есть сноска, пройдя по которой мы найдём содержание, в котором ещё нужно будет найти номер нужной страницы. И всё это во время чтения нашей условной книги.

Магия интерфейса поддерживается двумя функциями: GetIDsOfName («получить идентификаторы имён» с англ.) и Invoke («вызов» с англ.). Первая функция связывает имена функций с особым идентификатором. А когда идентификатор нужной функции известен – оную можно вызвать с помощью функции Invoke. Такая форма вызова методов называется «поздним связыванием».

Запомните, в Visual Basic способ связывания задаётся объявлением объекта. Когда объект инициализируется как переменная типа «Object» — мы, по сути, говорим Visual Basic’у использовать интерфейс IDispatch, тем самым применяя позднее связывание:

' Для позднего связывания не нужны ссылки на библиотеки типов
' Если объект поддерживает интерфейс IDispatch, его метод может 
' быть динамически найден и вызван при исполнении кода

' Объявляем объект для позднего связывания
 Dim oExcel As Object
 Set oExcel = CreateObject("Excel.Application")

' Свойство видимости определяется через интерфейс IDispatch
 oExcel.Visible = True

Как видите, весь остальной код такой же, как и при раннем связывании. Единственное отличие при написании кода – в объявлении переменной.

Заметьте, что «позднее связывание» касается вызываемой функции, а не способа её вызова. Из ранее изложенного материала следует, что к интерфейсу IDispatch уже применяется «раннее связывание». Для задания свойства видимости, Visual Basic обращается к таблице указателей (IDispatch::Invoke). И уже COM-объект несёт ответственность за перенаправление запроса к корректной функции для отрисовки Excel приложения. Подобное перенаправление позволяет Visual Basic клиенту быть скомпилированным (при этом, привязанным к корректному адресу функции) и вместе с этим не знать саму функцию, с которой будет дальше работать.

Связывание идентификатора

Некоторые клиенты автоматизации (в первую очередь пакеты MFC и Visual Basic 3.0, хотя также касается Visual Basic 5.0, 6.0) используют смешанную форму позднего связывания – связывание идентификатора. Если COM объект известен на этапе разработки, идентификаторы вызываемых функций могут быть захвачены и направлены на IDispatch::Invoke напрямую. При этом нет необходимости в вызове GetIDsOfNames во время работы программы. Этим значительно увеличивается производительность, так как вместо двух вызовов COM на каждую функцию — происходит только один.

Связывание идентификатора нельзя выбрать напрямую в Visual Basic 5.0 или 6.0. Оно используется для объектов, которые обозначены в библиотеке типов, но не содержат обычного интерфейса (объекты только с одним диспинтерфейсом) и для элементов управления ActiveX. При этом везде, где это возможно, Visual Basic будет использовать раннее связывание по умолчанию.

Какое связывание стоит использовать?

Ответ на этот вопрос зависит в первую очередь от структуры Вашего проекта. Microsoft рекомендует раннее связывание в большинстве случаев. Однако, могут быть причины выбрать и позднее связывание. Раннее связывание – предпочтительный метод. Его достоинство – в привязке приложения напрямую к адресу вызываемой функции, никаких поисков ссылок в режиме исполнения программы. С точки зрения скорости исполнения – минимум вдвое быстрее позднего связывания.

Раннее связывание также обеспечивает безопасность при работе с типами. Когда у Вас привязана ссылка к библиотеке типов компонента, Visual Basic поддерживает IntelliSense технологию (автоматическое предложение свойств и методов по первым введённым символам), что позволяет кодировать каждую функцию корректно. Visual Basic также предупредит, если тип данных параметра или возвращаемого значения некорректен, что сэкономит время на написании и исправлении кода.

Позднее связывание по-прежнему применимо в ситуациях, когда конкретный интерфейс объекта ещё не известен на стадии разработки. Если предполагается, что Ваше приложение будет обращаться к множеству неизвестных серверов или ему потребуется вызывать функции по имени (например, с помощью CallByName функции в Visual Basic 6.0), тогда потребуется позднее связывание. Позднее связывание также полезно при работе с вопросами совместимости между разными версиями компонента, интерфейс которого от версии к версии претерпевал изменения.

Преимущества раннего связывания призывают использовать оное везде, где это возможно.

Сохранение совместимости между версиями

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

Приложения Microsoft Office – хороший пример подобных COM-серверов. Офисные приложения обычно расширяют свои интерфейсы для добавления нового функционала или для коррекции предыдущих меж-версионных наработок. Если требуется автоматизировать офисное приложение, раннее связывание рекомендуется с самой ранней версией продукта из предполагаемых в системе Вашего клиента. Например, если нужно разработать решение для Excel 95, Excel 97, Excel 2000 и Excel 2002 – следует использовать библиотеку типов для Excel 95 (XL5en32.olb) для обеспечения совместимости со всеми тремя версиями.

Офисные приложения показывают, как объектные модели с большими двойными интерфейсами могут испытывать серьёзные ограничения при переносе на некоторые платформы. Наилучшим будет выбрать IDispatch интерфейс для работы на разных платформах. Более подробно о поддержке совместимости с офисными приложениями можно посмотреть ЗДЕСЬ (ссылка на англоязычную статью).

ССЫЛКИ

Более детальную информацию по COM, таблицам указателей и использованию автоматизации можно найти в книгах:
1). Rogerson, Dale, Inside COM, MSPRESS, ISBN: 1-57231-349-8.
2). Curland, Matt, Advanced Visual Basic 6, DevelopMentor, 0201707128.

О СТАТЬЕ

Идентификатор статьи: 245115, последнее обновление от 5 ноября 2007 года в 16:31:03, версия 7.2
Применимо к:
— Microsoft Office Ultimate 2007
— MicrosoftOffice Enterprise 2007
— MicrosoftOffice Professional 2007
— MicrosoftOffice Professional Plus 2007
— MicrosoftOffice Standard 2007
— MicrosoftOffice Home and Student 2007
— MicrosoftOffice Basic 2007
— MicrosoftOffice 2003, All Editions
— MicrosoftOffice XP Developer Edition
— MicrosoftOffice 2000 Developer Edition
— MicrosoftVisual Basic 5.0 Professional Edition
— MicrosoftVisual Basic 6.0 Professional Edition
— MicrosoftVisual Basic 5.0 Enterprise Edition
— MicrosoftVisual Basic Enterprise Edition for Windows 6.0
Ключевые слова: kbautomation kbinfo KB245115

  • 1
  • 2
  • 3
  • 4
  • 5

Категория: Работа с приложениями и библиотеками | Добавил: Rioran (14.07.2015)

Просмотров: 5905

| Рейтинг: 5.0/1

Добавлять комментарии могут только зарегистрированные пользователи.

[

Регистрация

|

Вход

]

 

ttt480

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

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

Вопрос к специалистам.

Объясните своими — предельно простыми словами — чем раннее связывание — отличается от позднего ?
И зачем это связывание в экселе вообще нужно ?

 

а что Вас не устроило из того что Вы прочитали до этого вопроса о раннем и позднем связывании в инете?
раннее связывание — это точное определение  типа обьекта. это оптимизирует скорость работы компилятора и позволяет более рационально выделять память
Microsoft рекомендует использовать ранее связывание везде, где это возможно
раннее связывание позволяет компилятору понять Вы используете корректные свойства и методы обьекта еще на стадии проверки синтаксиса кода, а не в ходе его выполнения.
отдаленный аналог: Option Explicit
он заставляет программиста с самого начала представлять какие переменные и какого типа ему понадобятся.  

Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!

 

Казанский

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

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

#3

21.05.2018 02:07:52

Цитата
ttt480 написал:
зачем это связывание в экселе вообще нужно ?

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

https://www.google.ru/search?q=раннее+связывание+и+позднее+связывание+vba
https://docs.microsoft.com/ru-ru/dotnet/visual-basic/programming-guide/language-features/early-late-binding/
http://wordexpert.ru/forum/viewtopic.php?id=1962

Изменено: Казанский21.05.2018 02:08:40

 

bedvit

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

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

Виталий

#4

21.05.2018 09:10:13

Писал COM.DLL c dual интерфейсом (раннее связывание и позднее), поэтому кратко,

Цитата
ttt480 написал:
предельно простыми словами

ранее связывание — компилятор/транслятор знает об объекте ДО компиляции/трансляции, т.е. вы можете посмотреть свойства и методы даже в процессе написания кода. Поэтому это связывание на 50% быстрее позднего (оценочно). При позднем связывании компилятор/транслятор ничего не знает о вашем объекте, и работает с ним в процессе выполнения кода (поэтому в отладчике не видно свойств и методов). Но для раннего связывания, что бы компилятор видел ваш объект, нужно его подключить в референсах проекта. Есть объекты, которые работают через раннее или позднее связывание, есть с двойным СОМ интерфейсом — dual.

«Бритва Оккама» или «Принцип Калашникова»?

 

vikttur

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

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

А дальше посыплются вопросы: а что такое компиляция  и для чего транслятор :)

 

ttt480

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

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

bedvit, а в чем преимущества позднего связывания ?

 

БМВ

Модератор

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

Excel 2013, 2016

#7

21.05.2018 12:20:14

Цитата
ttt480 написал:
в чем преимущества позднего связывания ?

В поощрении лентяев, к каким себя отношу, которым лень определить переменные с которыми они работают.

По вопросам из тем форума, личку не читаю.

 

bedvit

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

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

Виталий

#8

21.05.2018 12:50:38

Цитата
vikttur написал: а что такое компиляция  и для чего транслятор

:D

Цитата
ttt480 написал: в чем преимущества позднего связывания ?

Более универсально, разрабатывалось в основном для использования в скриптовых языках (VBA считается таким языком), не нужно подключать библу в References, подключается сразу в коде

Код
Dim I As Object: Set I = CreateObject("ИмяБиблы")

Но есть и минусы, скорость, нет инфо о методах, используется только в ограниченном количестве языков (в основном скриптовые).
Можно посмотреть на

примере

(есть и ранее и позднее связывание).
Написал много, но потом удалил — ибо просили по простому, а здесь нужно немного понимать в (интерфейсы IUnknown, IDispatch, Dual(+COM Automation), таблица адресов методов, маршалинг и т.д. )
Матчасть под спойлером

Скрытый текст

Изменено: bedvit21.05.2018 16:59:03

«Бритва Оккама» или «Принцип Калашникова»?

 

Максим Зеленский

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

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

Microsoft MVP

#9

21.05.2018 12:51:18

Цитата
ttt480 написал:
а в чем преимущества позднего связывания ?

при раннем, как уже написали, надо прописывать референс проекта. При позднем — не надо :)

F1 творит чудеса

 

Дмитрий Щербаков

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

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

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

#10

21.05.2018 12:54:20

Цитата
БМВ написал:
В поощрении лентяев

не только. Если пишем код, в котором обращение идет к тому же Outlook, то при раннем связывании мы обязаны поставить галку в Tools -References. При этом связывание будет именно с нашей версией Outlook. У меня это будет Outlook.Application.16. И если я вышлю свой код кому-то, у кого хотя бы 2013 офис или еще меньше — то код еще при запуске выдаст ошибку компиляции, т.к. не найдет библиотеку Outlook16.
При позднем же связывании мы указываем только имя класса объекта(«Outlook.Application») без указания версии и VBA постарается найти любую сборку. Т.е. будет работать и в 2013 и в 2016. Тут останется только писать код так, чтобы использовать только те свойства и методы, которые есть в обеих версиях.

Изменено: Дмитрий Щербаков21.05.2018 13:03:40
(опечатка)

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

 

Jack Famous

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

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

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

ttt480, соглашусь больше с bedvit’ом, и Дмитрием.
Рассказывать пользователю, какие менюшки нужно открыть и где галочку поставить/снять, чтобы ваш код заработал будет выглядеть, мягко говоря, очень странно… Программа должна просто работать. Позднее связывание намного более универсально для этого. Однако, в случаях, когда разработчик точно уверен, какие библиотеки стоят/подключены на компьютерах пользователей, правильнее и быстрее (по скорости работы макроса) будет раннее связывание.

Лично я практически всегда (для неродных экселю библиотек) стараюсь использовать именно позднее связывание, ввиду описанных выше нюансов. Бывало и такое, что при вылете с ошибкой xl «снимает галочки» некоторых подключенных библиотек. Для позднего связывания это неважно — само подключит, а вот раннее приведёт к вылету с ошибкой.

Изменено: Jack Famous21.05.2018 13:11:34

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

bedvit

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

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

Виталий

#12

21.05.2018 13:12:30

Дмитрий верно, столкнулся с этим, при переносе с одной версии Excel на другую (с разными операционками) + может быть не зарегестрирован СОМ в реестре и нет ссылки в референсах. Поэтому теперь в коде при раннем связывании обязательно снимаю галку в референсах в конце кода.

Код
ThisWorkbook.VBProject.References.AddFromGuid "{77D79CA3-15A0-4310-B8D8-0BCBE3F72D96}", 1, 0: Continue ' подключаем библу "BedvitCOM" в References - version(1.0) 
'Для раннего связывания сначала включаем в References библу, потом в конце кода отключаем. Для позднего связывания этого не нужно (см.ниже).
'Если BedvitCOM не оключать, могут быть ошибки в этом файле при отсутствии зарегестрированной BedvitCOM - выслали кому-то файл, или открыли из другого ПК и т.д., где не установлеена или не открыта надстройка BedvitXLL (которая автоматом распаковывает и регистрирует библиотеку BedvitCOM в реестре) или не зарегистрированна BedvitCOM вручную
ThisWorkbook.VBProject.References.Remove ThisWorkbook.VBProject.References("BedvitCOM") 'оключаем библу в References

«Бритва Оккама» или «Принцип Калашникова»?

 

bedvit

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

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

Виталий

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

«Бритва Оккама» или «Принцип Калашникова»?

 

AAF

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

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

#14

21.05.2018 13:21:07

Цитата
Дмитрий Щербаков написал:
Тут останется только писать код так, чтобы использовать только те свойства и методы, которые есть в обеих версиях.

Что-то все быстро так написали ответы и выложить не успеваешь, приходится переписывать, и что вообще добавить, наверное, нечего (при моем уровне), кроме того, что некоторые «лентяи» так об этом и не узнали бы в процессе своего творчества.
Но даже в рамках данного контекста надо просто помнить о скорости, если обращение к Вашей переменной применяется в коде более 10-ков тыс. раз., то вряд ли Вас за скорость поблагодарят Userы

Изменено: AAF21.05.2018 13:26:38

 

Дмитрий Щербаков

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

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

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

#15

21.05.2018 13:39:00

Цитата
AAF написал:
то вряд ли Вас за скорость поблагодарят Userы

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

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

 

AAF

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

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

#16

21.05.2018 13:40:15

Цитата
Дмитрий Щербаков написал:
Я считаю, что работающий медленно код лучше, чем вообще не работающий

Безусловно!!!
Но, с предположительной точки зрения ТС, возможно, моя попытка сформировать такой вектор тяги может оказать положительное влияние в определенной ситуации.

Изменено: AAF21.05.2018 13:45:34

 

Jack Famous

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

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

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#17

21.05.2018 13:40:31

Цитата
bedvit написал:
можно все делать программно

видел пару раз такое. Полезный навык и хороший приём — спасибо!  :)

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

БМВ

Модератор

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

Excel 2013, 2016

#18

21.05.2018 13:52:11

Цитата
Дмитрий Щербаков написал:
не только

Дмитрий, беcспорно. Правильнее было написать  «Например в поощрении лентяев»

По вопросам из тем форума, личку не читаю.

 

AAF

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

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

#19

21.05.2018 13:58:51

Цитата
БМВ написал:
«Например в поощрении лентяев»

Ну я думаю, что «лентяйский» код — это не крестовый поход за упрощение, а скорее костыль необходимый для сущности «быстрой» совместимости (ну и, конечно улучшению коммерциализации данного направления и всего что с ним связано)…

 

ttt480

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

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

Теперь мне все стало ясно.

Мрак непонимания — окончательно рассеялся.
Спасибо за ответы.

 

Jack Famous

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

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

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

ttt480, для того форумы и нужны  ;)  :D

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

StoTisteg

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

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

#22

22.05.2018 17:53:38

Цитата
Дмитрий Щербаков написал:
работающий медленно код лучше, чем вообще не работающий

Это, конечно, только теория, но нельзя ли сначала попытаться сотворить раннее программно,
как писал bedvit, а при фейле — условной компиляцией перейти к позднему?

 

sokol92

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

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

#23

22.05.2018 18:13:20

Можно. Более распространенная практика: отладка сложного макроса (макросов) с ранним связыванием, а затем замена типов переменных  для объектов из «прицепленных» библиотек на Object и «отцепка» библиотек.

Владимир

Содержание

Всякий раз, когда вы назначаете объект объектной переменной, VB выполняет процесс, называемый привязка. Объекты могут быть связаны с ранней или поздней привязкой. Отличить легко: Если вы объявляете переменную как Object, вы запаздываете с привязкой. Раннее связывание позволяет компилятору выполнять другие оптимизации и выделять память перед выполнением приложения, что позволяет вашему коду работать намного быстрее. Однако в некоторых случаях может быть желательно позднее связывание.

Примеры:

12345678910111213 Раннее связываниеДополнительное раннее связывание ()’Создать переменную для хранения нового приложения ExcelDim xlApp как Excel.Application’Присвойте приложение Excel переменнойУстановите xlApp = New Excel.Application’Добавить книгу в xlApp и сделать xlApp видимымxlApp.Workbooks.AddxlApp.Visible = ВерноКонец подписки
123456789101112 Позднее связываниеДополнительное позднее связывание ()’Создать переменную для хранения нового объектаDim xlApp как объект’Назначить приложение Excel объектуУстановите xlApp = CreateObject («Excel.Application»)’Добавить книгу в xlApp и сделать xlApp видимымxlApp.Workbooks.AddxlApp.Visible = ВерноКонец подписки

Вы поможете развитию сайта, поделившись страницей с друзьями

На чтение 25 мин. Просмотров 12.3k.

VBA Dim

Алан Перлис

Постоянная одного человека — переменная другого

Эта статья содержит полное руководство по работе с переменными и использованию VBA Dim.

Первый раздел содержит краткое руководство по использованию оператора
Dim, включая примеры и формат оператора Dim.

Остальная часть поста содержит наиболее полное руководство, которое вы
найдете в VBA Dim Statement.

Если вы заинтересованы в объявлении параметров, вы можете прочитать о
них здесь.

Содержание

  1. Краткое руководство по использованию VBA Dim Statement
  2. Полезные ссылки 
  3. Что такое VBA Dim Statement?
  4. Формат VBA Dim Statement
  5. Как использовать Dim с несколькими переменными
  6. Где я должен поместить Dim Statement?
  7. Использование Dim в циклах
  8. Могу ли я использовать Dim для присвоения значения?
  9. Dim действительно требуется?
  10. Использование Dim с Basic Variables
  11. Использование Dim с Variants
  12. Использование Dim с Objects
  13. Использование Dim с Arrays
  14. Устранение неполадок ошибок  Dim
  15. Локальные и глобальные переменные
  16. Заключение

Краткое руководство по использованию VBA Dim Statement

Описание Формат Пример
Базовая
переменная
Dim [имя
переменной] 
As [Тип]
Dim count As Long
Dim amount 
As Currency
Dim name As String
Dim visible 
As Boolean
Фиксированная
строка
Dim [имя
переменной] 
As String *[размер]
Dim s As String * 4
Dim t As String * 10
Вариант Dim [имя
переменной] 
As Variant
Dim [имя
переменной]
Dim var As Variant
Dim var
Объект
использует
Dim и New
Dim [имя
переменной] 
As New [тип объекта]
Dim coll As New 
Collection
Dim coll As New 
Class1
Объект
использует
Dim и New
Dim [имя
переменной] 
As [тип объекта]
Set [имя
переменной] = New [тип объекта]
Dim coll As Collection
Set coll = New 
Collection
Dim coll As Class1
Set coll = New Class1
Статический
массив
Dim [имя
переменной]
([первый] 
To [последний] ) 
As[Тип]
Dim arr(1 To 6) 
As Long
Динамический
массив
Dim [имя
переменной]() 
As [Тип]
ReDim [имя
переменной]
([первый] 
To [последний])
Dim arr() As Long
ReDim arr(1 To 6)
Внешняя
библиотека
(Раннее
связывание) *
Dim [имя
переменной] 
As New [пункт]
Dim dict 
As New Dictionary
Внешняя
библиотека
(Раннее
связывание с
использованием
Set) *
Dim [имя
переменной] 
As [пункт]
Set [имя
переменной] = 
New [пункт]
Dim dict As Dictionary
Set dict = 
New Dictonary 
Внешняя
библиотека
(Позднее
связывание)
Dim [имя
переменной] 
As Object
Set [имя
переменной] = CreateObject
(«[библиотека]»)
Dim dict As Object
Set dict = CreateObject(«Scripting.
Dictionary»)

* Примечание. Для раннего связывания необходимо добавить
справочный файл с помощью меню «Инструменты» -> «Ссылки». Смотрите здесь,
как добавить ссылку на Dictonary.

Полезные ссылки 

  • Объявление параметров в подпрограмме или функции
  • Использование объектов в VBA
  • Массивы VBA
  • Коллекции VBA
  • Словарь VBA
  • VBA Workbook
  • VBA Worksheet

Что такое VBA Dim Statement?

Ключевое слово Dim — это сокращение от Dimension. Он
используется для объявления переменных в VBA.

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

Существует четыре типа Dim Statement. Все они очень похожи по синтаксису.

Вот они:

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

Ниже приводится краткое описание каждого типа

  1. Basic variable — этот тип переменной содержит одно значение. Это такие типы, как Long, String, Date, Double, Currency.
  2. Variant — VBA решает во время выполнения, какой тип будет использоваться. Вы должны избегать вариантов, где это возможно, но в некоторых случаях требуется их использование.
  3. Object — это переменная, которая может иметь несколько методов (то есть подпрограмм / функций) и несколько свойств (то есть значений). Есть 3 вида:
    Объекты Excel, такие как объекты Workbook, Worksheet и Range.
    Пользовательские объекты, созданные с использованием модулей классов.
    Внешние библиотеки, такие как Словарь.
  4. Array — это группа переменных или объектов.

В следующем разделе мы рассмотрим формат оператора VBA Dim с
некоторыми примерами каждого из них.

В последующих разделах мы рассмотрим каждый тип более
подробно.

Формат VBA Dim Statement

Формат выражения Dim показан ниже.

' 1. BASIC VARIABLE
' Объявление основной переменной
Dim [Имя переменной] As [тип]

' Объявление фиксированной строки
Dim [Имя переменной] As String * [размер]

' 2. VARIANT
Dim [Имя переменной] As Variant
Dim [Имя переменной]

' 3. OBJECT
' Объявление объекта
Dim [Имя переменной] As [тип]

' Объявление и создание объекта
Dim [Имя переменной] As New [тип]

' Объявление объекта с использованием позднего связывания
Dim [Имя переменной] As Object

' 4. ARRAY
' Объявление статического массива
Dim [Имя переменной](first To last) As [тип]

' Объявление динамического массива
Dim [Имя переменной]() As [тип]
Ниже приведены примеры использования различных форматов.
Sub Primeri()

    ' 1. BASIC VARIABLE
    ' Объявление основной переменной
    Dim name As String
    Dim count As Long
    Dim amount As Currency
    Dim eventdate As Date
    
    ' Объявление фиксированной строки
    Dim userid As String * 8
    
    ' 2. VARIANT
    Dim var As Variant
    Dim var
    
    ' 3. OBJECT
    ' Объявление объекта
    Dim sh As Worksheet
    Dim wk As Workbook
    Dim rg As Range
    
    ' Объявление и создание объекта
    Dim coll1 As New Collection
    Dim o1 As New Class1
    
    ' Объявление объекта - создайте объект ниже, используя Set
    Dim coll2 As Collection
    Dim o2 As Class1
    
    Set coll2 = New Collection
    Set o2 = New Class1
    
    ' 	Объявление и присвоение с использованием позднего связывания
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")
    
    ' 4. ARRAY
    ' Объявление статического массива
    Dim arrScores(1 To 5) As Long
    Dim arrCountries(0 To 9) As String
    
    ' Объявление динамического массива - установите размер ниже, используя 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

Мы рассмотрим эти различные типы операторов Dim в следующих
разделах.

Как использовать Dim с несколькими переменными

Мы можем объявить несколько переменных в одном выражении Dim.

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

Если мы опускаем тип, то VBA автоматически устанавливает тип как Variant. Мы увидим больше
о Variant позже.

' Сумма является вариантом
Dim amount As Variant

' Сумма является вариантом
Dim amount

' Адрес это вариант - имя это строка
Dim name As String, address

' имя - это вариант, адрес – строка
Dim name, address As String

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

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

Вы можете поместить столько переменных, сколько захотите, в
одном выражении Dim, но
для удобства чтения рекомендуется оставить его равным 3 или 4.

Где я должен поместить Dim Statement?

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

Если переменная используется перед оператором Dim, вы получите ошибку
«переменная не определена»

Dim statements

Когда дело доходит до позиционирования ваших Dim утверждений, вы можете сделать это двумя основными способами. Вы можете разместить все свои Dim заявления в верхней части процедуры.

Sub DimVverh()

    ' Размещение всех Dim statements наверху
    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:ДокументыОтчет.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

ИЛИ вы можете объявить переменные непосредственно перед их
использованием:

Sub DimIsp()

    Dim wk As Workbook
    Set wk = Workbooks.Open("C:ДокументыОтчет.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

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

Использование Dim в циклах

Помещение оператора Dim в цикл не влияет на переменную.

Когда VBA запускает Sub (или Function), первым делом он
создает все переменные, которые были объявлены в выражениях Dim.

Следующие 2 фрагмента кода практически одинаковы. Во-первых,
переменная Count объявляется перед циклом. Во втором он объявлен в цикле.

Sub CountPeredCiklom()

    Dim count As Long

    Dim i As Long
    For i = 1 To 3
        count = count + 1
    Next i
    
    ' значение счета будет 3
    Debug.Print count

End Sub
Sub CountPosleCikla()

    Dim i As Long
    For i = 1 To 3
        Dim count As Long
        count = count + 1
    Next i
    
    ' значение счета будет 3
    Debug.Print count

End Sub

Код будет вести себя точно так же, потому что VBA создаст переменные при
входе в подпрограмму.

Могу ли я использовать Dim для присвоения значения?

В таких языках, как C ++, C # и Java, мы можем объявлять и назначать переменные в одной строке:

' C++
int i = 6
String name = "Иван"

Мы не можем сделать это в VBA. Мы можем использовать оператор двоеточия для размещения
объявлений и назначения строк в одной строке.

Dim count As Long: count = 6

Мы не объявляем и не присваиваем в одной строке VBA. Что мы
делаем, это помещаем эти две строки (ниже) в одну строку в редакторе. Что
касается VBA, это две отдельные строки, как здесь:

Dim count As Long
count = 6

Здесь мы помещаем 3 строки кода в одну строку редактора,
используя двоеточие:

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

Нет никаких преимуществ или недостатков в назначении и
объявлении в одной строке редактора. Все сводится к личным предпочтениям.

Dim действительно требуется?

Ответ в том, что это не обязательно. VBA не требует от вас
использовать Dim Statement.

Однако не использовать оператор Dim — плохая практика и
может привести к множеству проблем.

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

Это может привести к таким проблемам, как

  1. Все переменные являются вариантами (проблемы с
    этим см. В разделе «Варианты»).
  2. Некоторые переменные ошибки останутся
    незамеченными.

Из-за этих проблем рекомендуется сделать использование Dim
обязательным в нашем коде. Мы делаем это с помощью оператора Option Explicit.

Option Explicit

 Мы можем сделать Dim
обязательным в модуле, набрав «Option Explicit» в верхней части модуля.

Мы можем сделать это автоматически в каждом новом модуле,
выбрав Tools-> Options из меню и отметив флажок «Требовать декларацию
переменной». Затем, когда вы вставите новый модуль, «Option Explicit» будет
автоматически добавлен в начало.

VBA Require Variable Declaration

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

Ошибки Переменной

В приведенном ниже коде мы используем переменную Total без использования оператора Dim.

Sub BezDim()

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

End Sub

Если мы случайно написали Total неправильно, VBA сочтет это
новой переменной.

В приведенном ниже коде мы неправильно написали переменную Total как Totall.

Sub BezDimOshibki()

    Total = 6
    
    ' Первый Total - это ошибка
    Totall = Total + 1
    
    ' напечатает 6 вместо 7
    Debug.Print Total

End Sub

VBA не обнаружит ошибок в коде, и будет напечатано неверное
значение.

Давайте добавим Option Explicit и попробуйте приведенный
выше код снова

Option Explicit 

Sub BezDimOshibki()

    Total = 6
    
    ' Первый Total - это ошибка
    Totall = Total + 1
    
    ' Напечатает 6 вместо 7
    Debug.Print Total

End Sub

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

Когда мы добавим оператор Dim для Total
и запустим код, мы получим ошибку, сообщающую, что опечатка Totall не была определена.

variable not defined 2

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

Ошибка в ключевом слове

Вот второй пример, который более тонкий.

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

Однако, когда код запускается, ничего не происходит.

Sub ZadatCvet()

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

End Sub

Ошибка здесь в том, что rgblue должен быть rgbBlue. Если вы
добавите Option Explicit в модуль, появится ошибка «переменная не определена».
Это значительно облегчает решение проблемы.

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

Использование Dim с Basic Variables

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

Вы можете увидеть список всех типов переменных VBA здесь.

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

Тип Хранение Диапазон Описание
Boolean 2 байта ИСТИНА или ЛОЖЬ Эта переменная
может быть
ИСТИНА или
ЛОЖЬ.
Long 4 байта от -2,147,483,648
до 2,147,483,647
Long — это
сокращение от
Long Integer.
Используйте это
вместо
типа Integer *
Currency 8 байт от -1,79769313486231E308
до -4,94065645841247E-324
для отрицательных
значений;
от 4.94065645841247E-324
до 1.79769313486232E308
для положительных
значений
Аналогично
Double,
но имеет
только 4
знака после
запятой
Double 8 байт от -922,337,203,685,477.5808
до 922,337,203,685,477.5807
Date 8 байт С 1 января 100
по 31 декабря 9999
String меняется От 0 до примерно
2 миллиардов
Содержит
текст

* Первоначально мы использовали бы тип Long вместо Integer,
потому что Integer был 16-разрядным, и поэтому диапазон был от -32 768 до 32
767, что довольно мало для многих случаев использования целых чисел.

Однако в 32-битной (или выше) системе целое число автоматически
преобразуется в длинное. Поскольку Windows была 32-битной начиная с Windows 95
NT, нет смысла использовать Integer.

В двух словах, всегда используйте Long для целочисленного
типа в VBA.

Фиксированный тип строки

В VBA есть один необычный тип базовой переменной, с которым
вы, возможно, не знакомы.

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

Sub TipStroki()

    Dim s As String
    
    ' s is "Иван Петров"
    s = "John Smith"
    
    ' s is "Игорь"
    s = "Tom"

End Sub

Фиксированная строка никогда не изменяется. Эта строка
всегда будет иметь одинаковый размер независимо от того, что вы ей назначаете

вот несколько примеров:

Sub FiksStroka()
    
    Dim s As String * 4
    
    ' s is "Иван"
    s = "Иван Перов"
    
    ' s = "Игорь "
    s = "Игорь"

End Sub

Использование Dim с Variants

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

Мы объявляем варианты следующим образом

' Оба варианта
Dim count
Dim count As Variant
Это звучит как отличная идея в теории. Больше не нужно беспокоиться о типе переменной
Sub IspVariants()
    
    Dim count As Variant
        
    count = 7
    
    count = "Иван"
    
    count = #12/1/2018#

End Sub

Однако использование вариантов является плохой практикой, и
вот почему:

  1. VBA
    не будет замечать неправильных ошибок типа (т. Е. Несоответствие данных).
  2. Вы не можете получить доступ к Intellisense.
  3. VBA
    угадывает лучший тип, и это может быть не то, что вы хотите.

Тип ошибки

Ошибки твои друзья!

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

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

Например. Представьте, что у нас есть лист оценок учеников.
Если кто-то случайно (или намеренно) заменит метку на текст, данные будут
недействительными.

Если мы используем вариант для хранения меток, то ошибки не
возникнет

Sub MarksVariant()
    
    Dim marks As Variant
    
    Dim i As Long
    For i = 1 To 10
        
        ' Прочитайте отметку
        mark = Sheet1.Range("A" & i).Value
        
    Next

End Sub

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

Если вы зададите переменную Long, VBA сообщит вам об ошибке
«Несоответствие типов», если значения являются текстовыми.

Sub MarksLong()
    
    Dim mark As Long
    
    Dim i As Long
    For i = 1 To 10
        
        ' Прочитайте отметку
        mark = Sheet1.Range("A" & i).Value
        
    Next

End Sub

Доступ к Intellisense

Intellisense — удивительная особенность VBA. Он дает вам
доступные параметры в зависимости от типа, который вы создали.

Представьте, что вы объявляете переменную листа, используя
Dim

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

Вы можете увидеть Intellisense на скриншоте ниже

VBA Intellisense

Если вы используете Variant как тип, то Intellisense будет
недоступен

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

Использование Dim с Objects

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

Есть 3 типа объектов:

  1. Объекты Excel
  2. Объекты модуля класса
  3. Внешние объекты библиотеки

Примечание. Объект VBA Collection используется аналогично тому, как мы используем объект Class Module. Мы используем новое, чтобы создать его.

Давайте посмотрим на каждый из них по очереди.

Объекты Excel

Объекты Excel, такие как Рабочая книга, Рабочий лист,
Диапазон и т. Д., Не используют Новый, поскольку они автоматически создаются
Excel. Смотрите, «когда New не требуется».

При создании или открытии книги Excel автоматически создает
связанный объект.

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

Sub OtkrWorkbook()
    
    Dim wk As Workbook
    Set wk = Workbooks.Open("C:ДокументыОтчет.xlsx")

End Sub

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

Sub DobavSheet()
    
    Dim sh As Worksheet
    Set sh = ThisWorkbook.Worksheets.Add

End Sub

Нам не нужно использовать ключевое слово New для этих объектов Excel.

Мы просто присваиваем переменную функции, которая либо
создает новый объект, либо дает нам доступ к существующему.

Вот несколько примеров назначения переменных Workbook, Worksheet и range

Sub DimWorkbook()
    
    Dim wk As Workbook
    
    ' назначить wk новой книге
    Set wk = Workbooks.Add
    
    ' назначить wk первой открытой книге
    Set wk = Workbooks(1)
    
    ' назначить wk рабочей книге Отчет.xlsx
    Set wk = Workbooks("Отчет.xlsx")
    
    ' назначить wk активной книге
    Set wk = ActiveWorkbook
    
End Sub
Sub DimWorksheet()
    
    Dim sh As Worksheet
    
    ' Назначить sh на новый лист
    Set sh = ThisWorkbook.Worksheets.Add
    
    ' Назначьте sh на крайний левый лист
    Set sh = ThisWorkbook.Worksheets(1)
    
    ' Назначьте sh на лист под названием «Клиенты»
    Set sh = ThisWorkbook.Worksheets("Клиенты")
    
    ' Присвойте sh активному листу
    Set sh = ActiveSheet

End Sub
Sub DimRange()

    ' Получить рабочий лист клиента
    Dim sh As Worksheet
    Set sh = ThisWorkbook.Worksheets("Клиенты")
    
    ' Объявите переменную диапазона
    Dim rg As Range
    
    ' Присвойте rg диапазону A1
    Set rg = sh.Range("A1")
    
    ' Назначьте rg в диапазоне от B4 до F10
    Set rg = sh.Range("B4:F10")
    
    ' Присвойте rg диапазону E1
    Set rg = sh.Cells(1, 5)
    
End Sub

Если вы хотите узнать больше об этих объектах, вы можете ознакомиться со следующими статьями: Workbook VBA, Worksheet VBA и Cell и Range VBA.

Использование Dim с Class Module Objects

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

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

Мы можем сделать это в операторе Dim или в операторе Set.

Следующий код создает объект, используя ключевое слово New в выражении Dim:

' Объявить и создать
Dim o As New class1
Dim coll As New Collection

Использование New в выражении Dim означает, что каждый раз
при запуске нашего кода будет создаваться ровно один объект.

Использование Set дает нам больше гибкости. Мы можем создать
много объектов из одной переменной. Мы также можем создать объект на основе
условия.

Этот следующий код показывает, как мы создаем объект Class Module, используя Set. (Чтобы создать модуль класса, перейдите в окно проекта, щелкните правой кнопкой мыши соответствующую книгу и выберите «Вставить модуль класса». Подробнее см. «Создание Simple Class Module».)

' Объявить только
Dim o As Class1

' Создать с помощью Set
Set o = New Class1

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

Мы используем Set для создания объекта Class1. Это потому, что количество нужных нам объектов зависит от
количества значений более 50.

Sub IspSet()
    
    ' Объявите переменную объекта Class1
    Dim o As Class1
    
    ' Читать диапазон
    Dim i As Long
    For i = 1 To 10
        If Sheet1.Range("A" & i).Value > 50 Then

            ' Создать объект, если условие выполнено
            Set o = New Class1
            
        End If
    Next i

End Sub

Я сохранил этот пример простым для ясности. В реальной версии этого кода мы бы заполнили объект Class Module данными и добавили его в структуру данных, такую как Collection или Dictionary.

Вот пример реальной версии, основанной на данных ниже:

dim sample data

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

' Стандартный модуль
Sub ChitatBalli()

    ' Создать коллекцию для хранения объектов
    Dim coll As New Collection
    
    ' Current Region получает соседние данные
    Dim rg As Range
    Set rg = Sheet1.Range("A1").CurrentRegion
    
    Dim i As Long, oStudent As clsStudent
    For i = 2 To rg.Rows.Count
        
        ' Проверьте значение
        If rg.Cells(i, 1).Value > 50 Then
            ' Создать новый объект
            Set oStudent = New clsStudent
            
            ' Читать данные на объект студента
            oStudent.Name = rg.Cells(i, 2).Value
            oStudent.Subject = rg.Cells(i, 3).Value
            
            ' добавить объект в коллекцию
            coll.Add oStudent
            
        End If
        
    Next i
    
    ' Распечатайте данные в Immediate Window, чтобы проверить их
    Dim oData As clsStudent
    For Each oData In coll
        Debug.Print oData.Name & " studies " & oData.Subject
    Next oData

End Sub

Чтобы узнать больше о Set вы можете заглянуть сюда.

Объекты из внешней библиотеки

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

Примерами являются библиотеки Access, Outlook и Word,
которые позволяют нам взаимодействовать с этими приложениями.

Мы можем использовать библиотеки для различных типов
структур данных, таких как Словарь, Массив, Стек и Очередь.

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

Мы можем создать эти объекты двумя способами:

  1. Раннее связывание
  2. Позднее связывание

Давайте посмотрим на это по очереди.

Раннее связывание

Раннее связывание означает, что мы добавляем справочный
файл. Как только этот файл добавлен, мы можем рассматривать объект как объект
модуля класса.

Мы добавляем ссылку, используя Tools-> Reference, а затем
проверяем соответствующий файл в списке.

Например, чтобы использовать словарь, мы ставим флажок
«Microsoft Scripting Runtime»

vba references dialog

Как только мы добавим ссылку, мы можем использовать словарь
как объект модуля класса

Sub RanSvyaz()

    ' Используйте только Dim
    Dim dict1 As New Dictionary
    
    ' Используйте Dim и Set
    Dim dict2 As Dictionary
    Set dict2 = New Dictionary

End Sub

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

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

Позднее связывание

Позднее связывание означает, что мы создаем объект во время
выполнения.

Мы объявляем переменную как тип «Объект». Затем мы
используем CreateObject для создания объекта.

Sub PozdSvyaz()

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

Использование Dim с Arrays

В VBA есть два типа массивов:

  1. Статический — размер массива задается в
    операторе Dim и не может изменяться.
  2. Динамический — размер массива не указан в
    выражении Dim. Это устанавливается позже с помощью оператора ReDim
' Статический массив

' Магазины 7 длинных - от 0 до 6
Dim arrLong(0 To 6) As Long

' Магазины 7 длинных - от 0 до 6
Dim arrLong(6) As String

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

Мы объявляем динамический массив, используя инструкцию Dim,
и устанавливаем размер позже, используя ReDim.

' Динамический массив

' Объявите переменную
Dim arrLong() As Long

' Установить размер
ReDim arrLong(0 To 6) As Long

Использование ReDim

Большая разница между Dim и ReDim
заключается в том, что мы можем использовать переменную в выражении ReDim. В операторе Dim размер должен быть
постоянным значением.

Sub IspSet()

    ' Объявите переменную
    Dim arrLong() As Long
    
    ' Спросите пользователя о размере
    Dim size As Long
    size = InputBox("Пожалуйста, введите размер массива.", Default:=1)
    
    ' Установите размер на основе пользовательского ввода
    ReDim arrLong(0 To size) As Long

End Sub

На самом деле мы можем использовать оператор Redim без
предварительного использования оператора Dim.

В первом примере вы можете видеть, что мы используем Dim:

Sub IspDimReDim()

    ' Использование Dim
    Dim arr() As String

    ReDim arr(1 To 5) As String
    
    arr(1) = "Яблоко"
    arr(5) = "Апельсин"
    
End Sub

Во втором примере мы не используем Dim:

Sub IspTolkoReDim ()

    ' Использование только ReDim
    ReDim arr(1 To 5) As String
    
    arr(1) = "Яблоко"
    arr(5) = "Апельсин"
    
End Sub

Преимущество состоит в том, что вам не нужно тусклое
утверждение. Недостатком является то, что это может сбить с толку тех, кто
читает ваш код. В любом случае это не имеет большого значения.

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

Вы можете найти все, что вам нужно знать о массивах в VBA здесь.

Устранение неполадок ошибок  Dim

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

Ошибка Тип Причина
Массив уже
рассчитан
Компиляция Использование
Redim для
статического
массива.
Ожидаемый:
идентификатор
Синтаксис Использование
зарезервированного слова в качестве
имени переменной.
Ожидаемый:
новый тип имени
Синтаксис Тип отсутствует в
выражении Dim.
Переменная объекта или переменная
блока не
установлена
Время выполнения New не был
использован для
создания объекта.
Переменная объекта или переменная
блока
не установлена
Время выполнения Set не использовался для назначения
переменной объекта.
Пользовательский
тип не определен
Компиляция Тип не распознан.
Это может
произойти, если
ссылочный файл не добавлен в меню
«Инструменты->
Ссылка» или имя
модуля класса
написано
неправильно.
Недопустимый
оператор вне блока
Type
Компиляция Имя переменной
отсутствует в
выражении Dim
Переменная
не определена
Компиляция Переменная
используется перед Dim-строкой.

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

Когда мы используем Dim в процедуре (то есть подпрограмме или функции), она считается
локальной. Это означает, что это доступно только с этой процедурой.

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

В приведенном ниже коде мы объявили count как глобальную переменную:

' Глобальная
Dim count As Long
Sub UseCount1()
    count = 6
End Sub
Sub UseCount2()
    count = 4
End Sub

Что произойдет, если у нас будет глобальная переменная и
локальная переменная с одинаковым именем?

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

' Глобальная
Dim count As Long

Sub UseCount()
    ' Локальная
    Dim count As Long
    
    ' Относится к локальному счету
    count = 6
    
End Sub

Подобная ситуация может привести только к проблемам, так как
трудно отследить, какой счет используется.

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

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

Dim против Private

В VBA есть ключевое слово Private.

Если мы используем ключевое слово Private с переменной или
подфункцией / функцией, то этот элемент доступен только в текущем модуле.

Использование Dim и Private для переменной дает тот же
результат

' Доступно во всем этом модуле
Private priCount As Long
Dim dimCount As Long

Sub UseCount()

    ' Доступно только в этом разделе
    Private priName As String
    Dim dimName As String
    
End Sub

В VBA принято использовать Private для глобальных переменных
и Dim для локальных

' Доступно во всем этом модуле
Private priCount As Long

Sub UseCount()
    ' Только локальный
    Dim dimName As String
    
End Sub

Local OnlyThere
в VBA есть 2 других
типа объявлений, которые называются Public и Global.

Ниже приводится краткое изложение всех 4 типов:

  1. Dim
    — используется для объявления локальных переменных, т. Е. В процедурах.
  2. Private
    — используется для объявления глобальных переменных и процедур. Эти переменные
    доступны только для текущего модуля.
  3. Public
    — используется для объявления глобальных переменных и процедур. Эти переменные
    доступны во всех модулях.
  4. Global
    — старая и устаревшая версия Public.
    Может использоваться только в стандартных модулях. Он существует только для обратной
    совместимости.

Заключение

На этом мы заканчиваем статью о VBA Dim Statement. Если у вас есть
какие-либо вопросы или мысли, пожалуйста, дайте мне знать в комментариях ниже.

Ранняя привязка против поздней привязки

Связывание — это процесс назначения объекта идентификатору или имени переменной. Раннее связывание (также известное как статическое связывание) — это когда объект, объявленный в Excel, имеет определенный тип объекта, такой как рабочий лист или рабочая книга. Позднее связывание происходит при создании общих ассоциаций объектов, таких как типы объявлений Object и Variant.

Раннее связывание ссылок имеет некоторые преимущества перед поздним связыванием.

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

Примечание. Чтобы реализовать раннее связывание, вы должны добавить соответствующую ссылку на проект VBA с помощью команды «Инструменты» → «Ссылки» VBE.
Эта библиографическая ссылка затем переносится с проектом; ему не нужно повторно ссылаться, когда проект VBA распространяется и запускается на другом компьютере.

'Looping through a dictionary that was created with late binding¹
Sub iterateDictionaryLate()
    Dim k As Variant, dict As Object
    
    Set dict = CreateObject("Scripting.Dictionary")
    dict.comparemode = vbTextCompare          'non-case sensitive compare model
    
    'populate the dictionary
    dict.Add Key:="Red", Item:="Balloon"
    dict.Add Key:="Green", Item:="Balloon"
    dict.Add Key:="Blue", Item:="Balloon"
    
    'iterate through the keys
    For Each k In dict.Keys
        Debug.Print k & " - " & dict.Item(k)
    Next k
    
    dict.Remove "blue"      'remove individual key/item pair by key
    dict.RemoveAll          'remove all remaining key/item pairs

End Sub

'Looping through a dictionary that was created with early binding¹
Sub iterateDictionaryEarly()
    Dim d As Long, k As Variant
    Dim dict As New Scripting.Dictionary
    
    dict.CompareMode = vbTextCompare          'non-case sensitive compare model
    
    'populate the dictionary
    dict.Add Key:="Red", Item:="Balloon"
    dict.Add Key:="Green", Item:="Balloon"
    dict.Add Key:="Blue", Item:="Balloon"
    dict.Add Key:="White", Item:="Balloon"
    
    'iterate through the keys
    For Each k In dict.Keys
        Debug.Print k & " - " & dict.Item(k)
    Next k

    'iterate through the keys by the count
    For d = 0 To dict.Count - 1
        Debug.Print dict.Keys(d) & " - " & dict.Items(d)
    Next d
    
    'iterate through the keys by the boundaries of the keys collection
    For d = LBound(dict.Keys) To UBound(dict.Keys)
        Debug.Print dict.Keys(d) & " - " & dict.Items(d)
    Next d
    
    dict.Remove "blue"                         'remove individual key/item pair by key
    dict.Remove dict.Keys(0)                   'remove first key/item by index position
    dict.Remove dict.Keys(UBound(dict.Keys))   'remove last key/item by index position
    dict.RemoveAll                             'remove all remaining key/item pairs

End Sub

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

Это то, где поздняя привязка выгодна. При использовании позднего связывания вам не нужно добавлять ссылку в меню «Инструменты»> «Ссылки». На машинах, имеющих соответствующую библиотеку, код будет работать. На машинах без этой библиотеки команды, ссылающиеся на библиотеку, не будут работать, но все остальные коды в вашем документе будут продолжать функционировать.

Если вы не знакомы с библиотекой, на которую вы ссылаетесь, может быть полезно использовать раннее связывание при написании кода, а затем перейти к позднему связыванию перед развертыванием. Таким образом, вы можете использовать возможности IntelliSense и обозревателя объектов VBE во время разработки.

Принципиальные отличия

Как работает механизм связывания в VB

Зачем нужно позднее связывание

Связывание с внешними объектами

Используйте раннее связывание, где это возможно

Экспериментируйте

В классических процедурных языках
(например, в DOS’овских версиях MS Basic)
основополагающим принципом было использование
технологии раннего связывания. А позднее
связывание впервые было реализовано в
системах-интерпретаторах, так что парадокс,
возможно, заключается в том, что примитивный язык
для начинающих под названием «Бейсик» стал
прообразом «крутых» ООП-систем.

Система Visual Basic базируется на
сочетании механизмов раннего и позднего
связывания программного кода, что является одной
из характерных черт современных
объектно-ориентированных языков. Каждая из этих
технологий имеет свои достоинства и недостатки,
которые нужно иметь в виду при разработке
приложений.

Принципиальные отличия

Попробуем сформулировать определения.

  1. С точки зрения программирования связывание — это процедура установки связи
    между идентификатором, используемым в коде программы, и его физическим объектом
    (в общем случае — любым программным компонентом: переменной, процедурой,
    модулем, приложением и т.д.).
  2. Раннее связывание — установка таких связей до начала выполнения программы.
    Обычно под этим понимается связывание в процессе компиляции исходных модулей
    и компоновки исполняемого модуля из объектных. Однако сюда же относится процедура
    проверки наличия всех библиотек времени выполнения (Run-Time module) при запуске
    приложения.
  3. Позднее связывание — установка связей в процессе выполнения программы. Речь
    обычно идет либо о динамических связях (когда только в ходе работы приложения
    определяется, какие объекты будут нужны), либо о формировании таких объектов
    во время работы.

Примечание. Многие VB-программисты
вообще не очень хорошо представляют себе, что
процедура формирования исполняемого модуля (или
запуска программы в среде VB) состоит из
компиляции отдельных модулей и последующей их
компоновки в загрузочный. Дело в том, что VB не
позволяет подключать внешние объектные модули,
поэтому компания Microsoft решила не детализировать
этот процесс, назвав его компиляцией. Отметим,
что это не характеристика языка Basic, а
исключительно желание Microsoft. Например, во времена
MS Basic/DOS отдельно были компилятор и компоновщик,
которые можно было использовать автономно, вне
среды разработки.

Чтобы начать разбираться в этом, напишите следующий простой программный код:

Sub Main()
  Dim MyVal%
  MyVal = 13 
  If MyVal Mod 5 = 0 Then	‘ если нацело делится на 5
    Call MyProc  	        ‘ то обращение к функции
  End If
End Sub

Sub MyProc()
  Call HisProc          	‘ обращение к какой-то процедуре
End Sub

При работе, например с QuickBasic, еще в
момент запуска программы в среде интерпретатора
сразу будет выдано сообщение об ошибке: «Не
определена процедура HisProc». Дело в том, что в QB
стал одним из первых массовых инструментов
разработки, в котором был реализован принцип
компилирующего интерпретатора.

Напомним, что классическая схема
интерпретатора предполагает, что проверка
синтаксиса оператора — в том числе
разрешенность ссылок (фактического наличия
указанной ссылки: переменной, процедуры и
пр.) — осуществляется только в момент его
выполнения. То есть только в момент обращения к
данному оператору производятся синтаксический
разбор текстовой записи оператора и его
исполнение.

Например, если вы напишете на GWBasic (мне с трудом удалось найти на сохранившемся
дистрибутиве MS-DOS 4.0) такой код:

100 GOTO 200
110 a$ = MID$(“asdf”,1,1,1,1)
200 PRINT “Привет”

то ошибка в операторе 110 (явно неверная
запись оператора) появится, только если мы уберем
оператор 100.

Компилирующий интерпретатор QB при
отладке в среде сначала проводил полный
синтаксический контроль кода всей программы,
включая связывание всех идентификаторов и
преобразование ее текстового кода во внутренний
p-Code. И только потом уже выполнял этот внутренний
код в режиме интерпретации. Кроме транслятора, QB
имел настоящий компилятор, создавший объектные
двоичные модули, которые потом объединялись
компоновщиком в программы на машинном коде.

Таким образом, в GWBasic был реализован
механизм позднего связывания (на этапе
выполнения программы), а в QB — раннего (на
этапе компиляции). Преимущества последнего не
требуют особого объяснения — масса ошибок
программиста автоматически вылавливалась
транслятором. Не говоря уже о том, что при
использовании позднего связывания многие ошибки
очень сложно выловить с помощью тестовых
запусков, так как нет гарантий, что тест пройдет
через абсолютно все операторы приложения.

При работе в VB и VBA реализованы два
режима компиляции кода при работе в среде,
которые определяются состоянием флажка Compile On
Demand на вкладке General диалогового окна Tools|Options.

  1. Если флажок установлен (этот режим определяется по умолчанию при инсталляции
    VB или Office 2000), то компиляция исходного кода будет выполняться только
    в момент его выполнения. В этом случае при запуске приведенного выше примера
    в среде VB сообщение об ошибке появится только в случае, если d будет нацело
    делиться на 5 (например, MyVal = 15). То есть проверка разрешенности ссылки
    на HisProc будет выполняться только в момент выполнения процедуры MyProc,
    что является явным признаком механизма позднего связывания.
  2. Если флажок сброшен, то сначала будет выполняться полная компиляция всей
    программы. Сообщение об ошибке появится сразу же при запуске программы на
    выполнение.

Преимущество первого варианта — более высокая скорость запуска программы, что
особенно важно при отладке отдельных фрагментов большого проекта. Кроме того,
вы можете сосредоточиться на конкретном коде и пока не отвлекаться на ошибки
в других частях приложения. Не говоря уже о том, что в случае динамического
подключения VBA-проектов такой режим поможет обращаться к внешним процедурам
(см. статью «Программное взаимодействие проектов Office 2000» в этом номере
журнала).

Преимущества второго варианта также очевидны — более высокое качество отладки
и надежная работа программы. В связи с этим можно сформулировать два совета.

Совет для VBA-разработчиков. При отладке проекта работайте только со
вторым вариантом режима компиляции кода. Это поможет вам избежать множества
проблем, которые могут быть автоматически выявлены транслятором. Если вас волнует
проблема скорости запуска программы (большой проект), то можно установить Compile
On Demand, но на завершающем этапе отладки все же сбросьте его. После завершения
отладки (в том числе в режиме опытной эксплуатации) можно установить первый
режим — запуск программы будет выполняться быстрее.

Совет для VB-разработчиков. Он
формулируется не столь категорично. Установка
режима Compile On Demand происходит без особых проблем,
так как при создании EXE-модуля все равно будет
выполнена полная компиляция проекта. Тем не
менее здесь можно дать два «подсовета».

  1. При работе с небольшими проектами сбросьте Compile On Demand.
  2. Если время запуска программы в среде является критичным, то можно установить
    Compile On Demand. Однако время от времени для тестового запуска проекта в
    среде VB используйте вместо команды Run|Start (F5 или соответствующей кнопки
    на панели инструментов) команду Run|Start With Full Compile (Ctrl+F5), которая
    производит обязательную компиляцию всего проекта, независимо от установки
    Compile On Demand.
В начало

В начало

Как работает механизм связывания в VB

Но все же механизм позднего связывания
VB в режиме Compile On Demand несколько отличается от
«классического» варианта, реализованного в GWBasic.
Дело в том, что VB в этом случае выполняет
синтаксический контроль не пооператорно, а
попроцедурно, то есть производится трансляция
всего кода процедуры в момент обращения к ней.

Чтобы убедиться в этом, напишите для процедуры MyProc такой код:

Sub MyProc()
  Dim a$
  Exit Sub                  ‘  выход из процедуры
  	                            ‘ эти операторы содержат ошибки:
  D = 1                      	‘ переменная не определена
  A$ = Mid$(“asdr”,1,1,1,1)  	‘ неверный синтаксис функции Mid
End Sub

При обращении к этой процедуре тут же будут выданы ошибки в последних двух
строках, хотя реально эти операторы никогда не будут выполняться.

Здесь мне хотелось бы сделать
замечание относительно того, что, несмотря на
многие достоинства интеллектуального редактора
VB/VBE, по некоторым функциям (очень важным для
разработчика) он заметно уступает тому, что было
реализовано Microsoft почти полтора десятка лет
назад в QB.

Например, редактор VB совершенно спокойно реагирует на ввод такой явно ошибочной
строки

A$= Mid$(“asdr”,1,1,1,1) ‘ неверный синтаксис функции     Mid

QB выдал бы сообщение об ошибке
синтаксиса непосредственно при вводе кода.

Еще один пример подобного спокойствия VB:

A$ = TextBox.test

Здесь очевидно, что программист
ошибся, введя «test» вместо «text». VB отлично знает,
что у текстового поля нет свойства test (он привел
список допустимых свойств в своей подсказке), но
при этом ничего не сообщает разработчику,
ограничившись тем, что не «поднял» первую букву
идентификатора.

Совет: используйте в идентификаторах переменных и процедур прописные буквы
и вводите код только с использованием строчных букв нижнего регистра клавиатуры.
Тогда вы по реакции редактора (он должен «поднять» нужные символы) сразу
увидите — определен идентификатор или нет (поворчим немного: хороший редактор
мог бы сообщить об этом в явном виде).

В начало

В начало

Зачем нужно позднее связывание

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

Простой пример использования этого
механизма — использование внешних DLL и, в
частности, функций Win API.

Здесь проверка существования нужного
файла и заданной процедуры выполняется только в
момент обращения к этой процедуре (проверка
соответствия описания и обращения к процедуре
выполняется на этапе компиляции). Но данный
пример работы VB как раз не в его пользу: конечно
же, было бы лучше предусмотреть вариант, чтобы
такая проверка выполнялась на этапе запуска
(именно запуска, а не компиляции) приложения.

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

Dim MyObject As Object
…
‘ тут объект должен быть создан, например
If SomeVar = 0 Then 	‘ объект = ссылка
  Set MyObject = ActiveDocument.VBProject.References.Item(1) 
Else
  Set MyObject =  ActiveDocument.VBProject.  ‘ объект = проект активного документа
End If
…
a$ = MyObject.FullPath 	‘ это будет работать, только если SomeVar = 0

С точки зрения традиционного
компилятора с механизмом раннего связывания в
последнем операторе имеется явная ошибка, так
как непонятно, что за объект будет реально создан
и будет ли он обладать свойством FullPath (это
станет известно только в момент выполнения
программы). «Хороший» компилятор вполне может
отследить тип присваиваемого объекта при
линейном алгоритме, но в случае нашего ветвления
он будет так же бессилен.

Вот еще один пример на ту же тему. Очевидно, что такая процедура

Sub MyProc(cntControl As Control)
    MsgBox cntControl.Text
End Sub

в зависимости от передаваемого в нее
конкретного элемента управления будет либо
работать (Text), либо не работать (Label).

Рассмотрим еще одну любопытную ситуацию на примере связи двух VBA-проектов.
Если мы хотим из нашего активного проекта обратиться к процедуре OtherProcedure
документа OtherDoc.doc, то сначала можно сделать ссылку на этот документ в окне
Tools|References и написать такой простой код:

Call OtherProcedure

(Мы считаем, что имя процедуры является
уникальным, поэтому не указываем полный путь к
ней — Call OtherDoc.OtherModule.OtherProcedure.)

Если же мы захотим выполнить установку динамической ссылки на документ, то
можно реализовать следующую конструкцию:

Sub MyProcedure
  ‘ установка ссылки программным образом:
  ActiveDocument.VBProject.References.AddFromFile “OtherDoc.doc”
  ‘ обращение к процедуре:
  Call OtherProcedure
End If

Но такой код не будет работать! Дело в том, что, как только процедура MyProcedure
получит управление, будет выполнена компиляция кода, в ходе которой обнаружится,
что идентификатор OtherProcedure не определен. Решение этой проблемы выглядит
следующим образом:

Sub MyProcedure
  ‘ установка ссылки программным образом:
  ActiveDocument.VBProject.References.AddFromFile “OtherDoc.doc”
  ‘ обращение к промежуточной процедуре:
  Call MyOtherProcedure
End If

Sub MyOtherProcedure
  ‘ к этому моменту имя OtherProcedure будет уже определено
  Call OtherProcedure
End If

Но такая конструкция будет работать только в режиме Compile On Demand. Радикальное
же решение проблемы заключается в использовании в данном случае свойства Run
для обращения к процедурам подключаемых проектов (подробнее см. статью «Программное
взаимодействие проектов Office 2000»).

В начало

В начало

Связывание с внешними объектами

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

Sub EarlyBinding()
  ‘ Пример раннего связывания
  ‘ с внешним объектом Word
  Dim oWord As New Word.Application  ‘создаем конкретный объект
  ‘ Можно создать объект таким образом:
  ‘ Dim oWord As Word.Application  ‘ описываем конкретный
  ‘ Set oWord = New Word.Application  ‘ создаем новый экземпляр
  
  oWord.Visible = True
     MsgBox “Раннее связывание”
  oWord.Quit
  Set oWord = Nothing
  
End Sub

Sub LateBinding()
  ‘ Пример позднего связывания
  ‘ с внешним объектом Word
  Dim oWord As Object  ‘ неопределенный объект
  
  Set oWord = CreateObject(“Word.Application”)
  oWord.Visible = True
    MsgBox “Позднее связывание”
  oWord.Quit
  Set oWord = Nothing
  
End Sub

Достоинство раннего связывания: работают подсказки и синтаксический контроль
при создании исполняемого модуля. Но этот вариант (точнее, вся программа, независимо
от того, было или не было обращение к EarlyBinding) будет работать только в
случае наличия ссылки (Project|References) на реально существующее приложение.
При этом имеется два варианта создания объекта:

Dim oWord As New Word.Application ‘создаем конкретный     объект

и

Dim oWord As Word.Application ‘ описываем конкретный
Set oWord = New Word.Application ‘ создаем новый экземпляр

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

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

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

Sub LateBinding(AppName$)
  ‘ Пример позднего связывания
  ‘ с внешним объектом AppName$
  Dim oApp As Object  ‘ неопределенный объект
  
  Set oApp = CreateObject(AppName$)
  oApp.Visible = True
  oApp.Quit
  Set oApp = Nothing
  
End Sub

Разумеется, тут нужно быть уверенным, что написанные методы действительно
могут работать с объектом. Но в данном простом примере можно применять практически
любое приложение, использующее ActiveX-интерфейс.

В начало

В начало

Используйте раннее связывание, где это возможно

Одна из проблем использования
технологии позднего связывания заключается в
том, что в этом случае отключается
предварительный синтаксический контроль кода, в
том числе отсутствуют интеллектуальные
подсказки при вводе сложных выражений. То есть
программисту приходится отказываться от очень
полезной функции интеллектуального редактора.
(Несмотря на отмеченные выше «потери» качества,
современная среда разработки, конечно же,
получила очень много полезных для разработчика
функций по сравнению с инструментами
десятилетней давности.)

Например, вам нужно распечатать некоторые свойства проектов и библиотек, на
которые имеет ссылки ваш активный документ (об этом говорится в статье «Программное
взаимодействие проектов Office 2000»). Для этого можно написать следующий код:

Dim ActiveRef As Object
For Each ActiveRef In ActiveDocument.VBProject.References
    ‘ имя проекта или библиотеки
  Debug.Print “Имя проекта = “ & ActiveRef.name   
    ‘ полное имя файла 
  Debug.Print “Полное имя файла = “ & ActiveRef.fullpath
Next

Недостаток этой конструкции, с точки
зрения разработчика, очевиден: в операторе For Each
выполняет динамическое определение объекта
ActiveRef в качестве ссылки. Поэтому редактор ничего
не знает о том, как будет произведена эта
установка, и в последующих операторах Print не
может показать список допустимых свойств для
объекта ActiveRef (именно это мы и хотели подчеркнуть,
написав свойства Name и FullPath строчными
буквами — редактор также «не поднимет» буквы
в этих именах).

Оригинальное решение этой проблемы приводит Владимир Биллиг в своей статье
«Документы Office 2000 и их проекты» (www.microsoft.ru/offext/officedev/articles/articles.htm).
Он предлагает в процессе ввода кода описать ActiveRef в виде конкретного объекта,
в данном случае как Dim ActiveRef As Reference. При этом, как утверждается,
будет работать синтаксис-подсказка. Однако при запуске кода на выполнение такое
определение объекта окажется недействительным, поэтому нужно будет написать
определение Dim ActiveRef As Object. (То есть «As Reference» используется только
для ввода кода, а затем для отладки и выполнения эта строка меняется на «As
Object».)

К сожалению, мои попытки воспользоваться этим советом не увенчались успехом.
Возможно, причина заключается в использовании разных релизов продукта или в
каких-то тонких настройках. Но здесь можно констатировать только одно: механизм
нетривиального определения объектов в Office 97/2000 выглядит пока довольно
сырым. Например, Владимир Биллиг отмечает, что идентичные программные конструкции
в одних приложениях работают, а в других нет. В нашем случае видны явные противоречия,
когда редактор «поднимает» название типа в строке

Dim MyRef As Reference

показывая, что ключевое слово «Reference»
знакомо ему, но при запуске программы сообщает,
что этот тип объекта ему неизвестен.

В этой ситуации для повышения удобства программирования я предлагаю избегать
конструкции For Each и применять традиционный цикл с числовой переменной. Так,
представленный выше алгоритм распечатки свойств присоединенных проектов можно
реализовать в следующем виде:

With ActiveDocument.VBProject.References
  For i = 1 To .Count
    Debug.Print “Имя проекта = “ & .Item(i).Name
    Debug.Print “Полное имя файла = “ & .Item(i).FullPath
  Next
End With

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

For i = 0 To .Count –1
В начало

В начало

Экспериментируйте

Из всего сказанного выше можно сделать
следующие выводы:

  1. VB предоставляет достаточно гибкие возможности по управлению процессом «связывания»
    кода;
  2. Механизм связывания объектов в VB находится в затянувшейся стадии становления,
    здесь имеется много подводных камней;
  3. Возможно, установка сервисных пакетов обновления поможет устранить некоторые
    из отмеченных проблем и противоречий.

Так или иначе — будьте внимательны при написании программ и выборе тех
или иных конструкций. И еще — экспериментируйте для поиска наиболее удобных
для вас вариантов.

КомпьютерПресс 9’2000

Работа с переменными

Автор Дмитрий Якушев На чтение25 мин. Просмотров271

Алан Перлис

Постоянная одного человека — переменная другого

Эта статья содержит полное руководство по работе с переменными и использованию VBA Dim.

Первый раздел содержит краткое руководство по использованию оператора Dim, включая примеры и формат оператора Dim.

Остальная часть поста содержит наиболее полное руководство, которое вы найдете в VBA Dim Statement.

Если вы заинтересованы в объявлении параметров, вы можете прочитать о них здесь.

Содержание

  1. Краткое руководство по использованию VBA Dim Statement
  2. Полезные ссылки 
  3. Что такое VBA Dim Statement?
  4. Формат VBA Dim Statement
  5. Как использовать Dim с несколькими переменными
  6. Где я должен поместить Dim Statement?
  7. Использование Dim в циклах
  8. Могу ли я использовать Dim для присвоения значения?
  9. Dim действительно требуется?
  10. Option Explicit
  11. Ошибки Переменной
  12. Ошибка в ключевом слове
  13. Использование Dim с Basic Variables
  14. Фиксированный тип строки
  15. Использование Dim с Variants
  16. Тип ошибки
  17. Доступ к Intellisense
  18. Использование Dim с Objects
  19. Объекты Excel
  20. Использование Dim с Class Module Objects
  21. Объекты из внешней библиотеки
  22. Раннее связывание
  23. Позднее связывание
  24. Использование Dim с Arrays
  25. Использование ReDim
  26. Устранение неполадок ошибок  Dim
  27. Локальные и глобальные переменные
  28. Dim против Private
  29. Заключение

Краткое руководство по использованию VBA Dim Statement

Описание

Формат

Пример

Базовая
переменная

Dim [имя
переменной] 
As [Тип]

Dim count As Long
Dim amount 
As Currency
Dim name As String
Dim visible 
As Boolean

Фиксированная
строка

Dim [имя
переменной] 
As String *[размер]

Dim s As String * 4
Dim t As String * 10

Вариант

Dim [имя
переменной] 
As Variant
Dim [имя
переменной]

Dim var As Variant
Dim var

Объект
использует
Dim и New

Dim [имя
переменной] 
As New [тип объекта]

Dim coll As New 
Collection
Dim coll As New 
Class1

Объект
использует
Dim и New

Dim [имя
переменной] 
As [тип объекта]
Set [имя
переменной] = 
New [тип объекта]

Dim coll As Collection
Set coll = New 
Collection
Dim coll As Class1
Set coll = New Class1

Статический
массив

Dim [имя
переменной]
([первый] 
To [последний] ) 
As[Тип]

Dim arr(1 To 6) 
As Long

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

Dim [имя
переменной]() 
As [Тип]
ReDim [имя
переменной]
([первый] 
To [последний])

Dim arr() As Long
ReDim arr(1 To 6)

Внешняя
библиотека
(Раннее
связывание) *

Dim [имя
переменной] 
As New [пункт]

Dim dict 
As New Dictionary

Внешняя
библиотека
(Раннее
связывание с
использованием
Set) *

Dim [имя
переменной] 
As [пункт]
Set [имя
переменной] = 
New [пункт]

Dim dict As Dictionary
Set dict = 
New Dictonary 

Внешняя
библиотека
(Позднее
связывание)

Dim [имя
переменной] 
As Object
Set [имя
переменной] = CreateObject
(«[библиотека]»)

Dim dict As Object
Set dict = CreateObject(«Scripting.
Dictionary»)

* Примечание. Для раннего связывания необходимо добавить справочный файл с помощью меню «Инструменты» -> «Ссылки». Смотрите здесь, как добавить ссылку на Dictonary.

Полезные ссылки 

  • Объявление параметров в подпрограмме или функции
  • Использование объектов в VBA
  • Массивы VBA
  • Коллекции VBA
  • Словарь VBA
  • VBA Workbook
  • VBA Worksheet

Что такое VBA Dim Statement?

Ключевое слово Dim — это сокращение от Dimension. Он используется для объявления переменных в VBA.

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

Существует четыре типа Dim Statement. Все они очень похожи по синтаксису.

Вот они:

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

Ниже приводится краткое описание каждого типа

  1. Basic variable — этот тип переменной содержит одно значение. Это такие типы, как Long, String, Date, Double, Currency.
  2. Variant — VBA решает во время выполнения, какой тип будет использоваться. Вы должны избегать вариантов, где это возможно, но в некоторых случаях требуется их использование.
  3. Object — это переменная, которая может иметь несколько методов (то есть подпрограмм / функций) и несколько свойств (то есть значений). Есть 3 вида:
    Объекты Excel, такие как объекты Workbook, Worksheet и Range.
    Пользовательские объекты, созданные с использованием модулей классов.
    Внешние библиотеки, такие как Словарь.
  4. Array — это группа переменных или объектов.

В следующем разделе мы рассмотрим формат оператора VBA Dim с некоторыми примерами каждого из них.

В последующих разделах мы рассмотрим каждый тип более подробно.

Формат VBA Dim Statement

Формат выражения Dim показан ниже.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

‘ 1. BASIC VARIABLE

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

Dim [Имя переменной] As [тип]

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

Dim [Имя переменной] As String * [размер]

‘ 2. VARIANT

Dim [Имя переменной] As Variant

Dim [Имя переменной]

‘ 3. OBJECT

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

Dim [Имя переменной] As [тип]

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

Dim [Имя переменной] As New [тип]

‘ Объявление объекта с использованием позднего связывания

Dim [Имя переменной] As Object

‘ 4. ARRAY

‘ Объявление статического массива

Dim [Имя переменной](first To last) As [тип]

‘ Объявление динамического массива

Dim [Имя переменной]() As [тип]

Ниже приведены примеры использования различных форматов.

Sub Primeri()

    ‘ 1. BASIC VARIABLE

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

    Dim name As String

    Dim count As Long

    Dim amount As Currency

    Dim eventdate As Date

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

    Dim userid As String * 8

    ‘ 2. VARIANT

    Dim var As Variant

    Dim var

    ‘ 3. OBJECT

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

    Dim sh As Worksheet

    Dim wk As Workbook

    Dim rg As Range

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

    Dim coll1 As New Collection

    Dim o1 As New Class1

    ‘ Объявление объекта — создайте объект ниже, используя Set

    Dim coll2 As Collection

    Dim o2 As Class1

    Set coll2 = New Collection

    Set o2 = New Class1

    ‘   Объявление и присвоение с использованием позднего связывания

    Dim dict As Object

    Set dict = CreateObject(«Scripting.Dictionary»)

    ‘ 4. ARRAY

    ‘ Объявление статического массива

    Dim arrScores(1 To 5) As Long

    Dim arrCountries(0 To 9) As String

    ‘ Объявление динамического массива — установите размер ниже, используя 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

Мы рассмотрим эти различные типы операторов Dim в следующих разделах.

Как использовать Dim с несколькими переменными

Мы можем объявить несколько переменных в одном выражении Dim.

1

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

Если мы опускаем тип, то VBA автоматически устанавливает тип как Variant. Мы увидим больше о Variant позже.

1

2

3

4

5

6

7

8

9

10

11

‘ Сумма является вариантом

Dim amount As Variant

‘ Сумма является вариантом

Dim amount

‘ Адрес это вариант — имя это строка

Dim name As String, address

‘ имя — это вариант, адрес – строка

Dim name, address As String

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

1

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

Вы можете поместить столько переменных, сколько захотите, в одном выражении Dim, но для удобства чтения рекомендуется оставить его равным 3 или 4.

Где я должен поместить Dim Statement?

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

Если переменная используется перед оператором Dim, вы получите ошибку «переменная не определена»

Когда дело доходит до позиционирования ваших Dim утверждений, вы можете сделать это двумя основными способами. Вы можете разместить все свои Dim заявления в верхней части процедуры.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Sub DimVverh()

    ‘ Размещение всех Dim statements наверху

    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:ДокументыОтчет.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

ИЛИ вы можете объявить переменные непосредственно перед их использованием:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Sub DimIsp()

    Dim wk As Workbook

    Set wk = Workbooks.Open(«C:ДокументыОтчет.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

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

Использование Dim в циклах

Помещение оператора Dim в цикл не влияет на переменную.

Когда VBA запускает Sub (или Function), первым делом он создает все переменные, которые были объявлены в выражениях Dim.

Следующие 2 фрагмента кода практически одинаковы. Во-первых, переменная Count объявляется перед циклом. Во втором он объявлен в цикле.

1

2

3

4

5

6

7

8

9

10

11

12

13

Sub CountPeredCiklom()

    Dim count As Long

    Dim i As Long

    For i = 1 To 3

        count = count + 1

    Next i

    ‘ значение счета будет 3

    Debug.Print count

End Sub

1

2

3

4

5

6

7

8

9

10

11

12

Sub CountPosleCikla()

    Dim i As Long

    For i = 1 To 3

        Dim count As Long

        count = count + 1

    Next i

    ‘ значение счета будет 3

    Debug.Print count

End Sub

Код будет вести себя точно так же, потому что VBA создаст переменные при входе в подпрограмму.

Могу ли я использовать Dim для присвоения значения?

В таких языках, как C ++, C # и Java, мы можем объявлять и назначать переменные в одной строке:

1

2

3

‘ C++

int i = 6

String name = «Иван»

Мы не можем сделать это в VBA. Мы можем использовать оператор двоеточия для размещения объявлений и назначения строк в одной строке.

1

Dim count As Long: count = 6

Мы не объявляем и не присваиваем в одной строке VBA. Что мы делаем, это помещаем эти две строки (ниже) в одну строку в редакторе. Что касается VBA, это две отдельные строки, как здесь:

1

2

Dim count As Long

count = 6

Здесь мы помещаем 3 строки кода в одну строку редактора, используя двоеточие:

1

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

Нет никаких преимуществ или недостатков в назначении и объявлении в одной строке редактора. Все сводится к личным предпочтениям.

Dim действительно требуется?

Ответ в том, что это не обязательно. VBA не требует от вас использовать Dim Statement.

Однако не использовать оператор Dim — плохая практика и может привести к множеству проблем.

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

Это может привести к таким проблемам, как

  1. Все переменные являются вариантами (проблемы с этим см. В разделе «Варианты»).
  2. Некоторые переменные ошибки останутся незамеченными.

Из-за этих проблем рекомендуется сделать использование Dim обязательным в нашем коде. Мы делаем это с помощью оператора Option Explicit.

Option Explicit

 Мы можем сделать Dim обязательным в модуле, набрав «Option Explicit» в верхней части модуля.

Мы можем сделать это автоматически в каждом новом модуле, выбрав Tools-> Options из меню и отметив флажок «Требовать декларацию переменной». Затем, когда вы вставите новый модуль, «Option Explicit» будет автоматически добавлен в начало.

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

Ошибки Переменной

В приведенном ниже коде мы используем переменную Total без использования оператора Dim.

1

2

3

4

5

6

7

8

9

Sub BezDim()

    Total = 6

    Total = Total + 1

    Debug.Print Total

End Sub

Если мы случайно написали Total неправильно, VBA сочтет это новой переменной.

В приведенном ниже коде мы неправильно написали переменную Total как Totall.

1

2

3

4

5

6

7

8

9

10

11

Sub BezDimOshibki()

    Total = 6

    ‘ Первый Total — это ошибка

    Totall = Total + 1

    ‘ напечатает 6 вместо 7

    Debug.Print Total

End Sub

VBA не обнаружит ошибок в коде, и будет напечатано неверное значение.

Давайте добавим Option Explicit и попробуйте приведенный выше код снова

1

2

3

4

5

6

7

8

9

10

11

12

13

Option Explicit

Sub BezDimOshibki()

    Total = 6

    ‘ Первый Total — это ошибка

    Totall = Total + 1

    ‘ Напечатает 6 вместо 7

    Debug.Print Total

End Sub

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

Когда мы добавим оператор Dim для Total и запустим код, мы получим ошибку, сообщающую, что опечатка Totall не была определена.

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

Ошибка в ключевом слове

Вот второй пример, который более тонкий.

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

Однако, когда код запускается, ничего не происходит.

1

2

3

4

5

Sub ZadatCvet()

    Sheet1.Range(«A1»).Font.Color = rgblue

End Sub

Ошибка здесь в том, что rgblue должен быть rgbBlue. Если вы добавите Option Explicit в модуль, появится ошибка «переменная не определена». Это значительно облегчает решение проблемы.

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

Использование Dim с Basic Variables

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

Вы можете увидеть список всех типов переменных VBA здесь .

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

Тип

Хранение

Диапазон

Описание

Boolean

2 байта

ИСТИНА или ЛОЖЬ

Эта переменная
может быть
ИСТИНА или
ЛОЖЬ.

Long

4 байта

от -2,147,483,648
до 2,147,483,647

Long — это
сокращение от
Long Integer.
Используйте это
вместо
типа Integer *

Currency

8 байт

от -1,79769313486231E308
до -4,94065645841247E-324
для отрицательных
значений;
от 4.94065645841247E-324
до 1.79769313486232E308
для положительных
значений

Аналогично
Double,
но имеет
только 4
знака после
запятой

Double

8 байт

от -922,337,203,685,477.5808
до 922,337,203,685,477.5807

Date

8 байт

С 1 января 100
по 31 декабря 9999

String

меняется

От 0 до примерно
2 миллиардов

Содержит
текст

* Первоначально мы использовали бы тип Long вместо Integer, потому что Integer был 16-разрядным, и поэтому диапазон был от -32 768 до 32 767, что довольно мало для многих случаев использования целых чисел.

Однако в 32-битной (или выше) системе целое число автоматически преобразуется в длинное. Поскольку Windows была 32-битной начиная с Windows 95 NT, нет смысла использовать Integer.

В двух словах, всегда используйте Long для целочисленного типа в VBA.

Фиксированный тип строки

В VBA есть один необычный тип базовой переменной, с которым вы, возможно, не знакомы.

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

1

2

3

4

5

6

7

8

9

10

11

Sub TipStroki()

    Dim s As String

    ‘ s is «Иван Петров»

    s = «John Smith»

    ‘ s is «Игорь»

    s = «Tom»

End Sub

Фиксированная строка никогда не изменяется. Эта строка всегда будет иметь одинаковый размер независимо от того, что вы ей назначаете

вот несколько примеров:

1

2

3

4

5

6

7

8

9

10

11

Sub FiksStroka()

    Dim s As String * 4

    ‘ s is «Иван»

    s = «Иван Перов»

    ‘ s = «Игорь «

    s = «Игорь»

End Sub

Использование Dim с Variants

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

Мы объявляем варианты следующим образом

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

‘ Оба варианта

Dim count

Dim count As Variant

Это звучит как отличная идея в теории. Больше не нужно беспокоиться о типе переменной

Sub IspVariants()

    Dim count As Variant

    count = 7

    count = «Иван»

    count = #12/1/2018#

End Sub

Однако использование вариантов является плохой практикой, и вот почему:

  1. VBA не будет замечать неправильных ошибок типа (т. Е. Несоответствие данных).
  2. Вы не можете получить доступ к Intellisense.
  3. VBA угадывает лучший тип, и это может быть не то, что вы хотите.

Тип ошибки

Ошибки твои друзья!

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

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

Например. Представьте, что у нас есть лист оценок учеников. Если кто-то случайно (или намеренно) заменит метку на текст, данные будут недействительными.

Если мы используем вариант для хранения меток, то ошибки не возникнет

1

2

3

4

5

6

7

8

9

10

11

12

13

Sub MarksVariant()

    Dim marks As Variant

    Dim i As Long

    For i = 1 To 10

        ‘ Прочитайте отметку

        mark = Sheet1.Range(«A» & i).Value

    Next

End Sub

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

Если вы зададите переменную Long, VBA сообщит вам об ошибке «Несоответствие типов», если значения являются текстовыми.

1

2

3

4

5

6

7

8

9

10

11

12

13

Sub MarksLong()

    Dim mark As Long

    Dim i As Long

    For i = 1 To 10

        ‘ Прочитайте отметку

        mark = Sheet1.Range(«A» & i).Value

    Next

End Sub

Доступ к Intellisense

Intellisense — удивительная особенность VBA. Он дает вам доступные параметры в зависимости от типа, который вы создали.

Представьте, что вы объявляете переменную листа, используя Dim

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

Вы можете увидеть Intellisense на скриншоте ниже

Если вы используете Variant как тип, то Intellisense будет недоступен

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

Использование Dim с Objects

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

Есть 3 типа объектов:

  1. Объекты Excel
  2. Объекты модуля класса
  3. Внешние объекты библиотеки

Примечание. Объект VBA Collection используется аналогично тому, как мы используем объект Class Module. Мы используем новое, чтобы создать его.

Давайте посмотрим на каждый из них по очереди.

Объекты Excel

Объекты Excel, такие как Рабочая книга, Рабочий лист, Диапазон и т. Д., Не используют Новый, поскольку они автоматически создаются Excel. Смотрите, «когда New не требуется».

При создании или открытии книги Excel автоматически создает связанный объект.

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

1

2

3

4

5

6

Sub OtkrWorkbook()

    Dim wk As Workbook

    Set wk = Workbooks.Open(«C:ДокументыОтчет.xlsx»)

End Sub

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

1

2

3

4

5

6

Sub DobavSheet()

    Dim sh As Worksheet

    Set sh = ThisWorkbook.Worksheets.Add

End Sub

Нам не нужно использовать ключевое слово New для этих объектов Excel.

Мы просто присваиваем переменную функции, которая либо создает новый объект, либо дает нам доступ к существующему.

Вот несколько примеров назначения переменных Workbook, Worksheet и range

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

Sub DimWorkbook()

    Dim wk As Workbook

    ‘ назначить wk новой книге

    Set wk = Workbooks.Add

    ‘ назначить wk первой открытой книге

    Set wk = Workbooks(1)

    ‘ назначить wk рабочей книге Отчет.xlsx

    Set wk = Workbooks(«Отчет.xlsx»)

    ‘ назначить wk активной книге

    Set wk = ActiveWorkbook

End Sub

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

Sub DimWorksheet()

    Dim sh As Worksheet

    ‘ Назначить sh на новый лист

    Set sh = ThisWorkbook.Worksheets.Add

    ‘ Назначьте sh на крайний левый лист

    Set sh = ThisWorkbook.Worksheets(1)

    ‘ Назначьте sh на лист под названием «Клиенты»

    Set sh = ThisWorkbook.Worksheets(«Клиенты»)

    ‘ Присвойте sh активному листу

    Set sh = ActiveSheet

End Sub

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Sub DimRange()

    ‘ Получить рабочий лист клиента

    Dim sh As Worksheet

    Set sh = ThisWorkbook.Worksheets(«Клиенты»)

    ‘ Объявите переменную диапазона

    Dim rg As Range

    ‘ Присвойте rg диапазону A1

    Set rg = sh.Range(«A1»)

    ‘ Назначьте rg в диапазоне от B4 до F10

    Set rg = sh.Range(«B4:F10»)

    ‘ Присвойте rg диапазону E1

    Set rg = sh.Cells(1, 5)

End Sub

Если вы хотите узнать больше об этих объектах, вы можете ознакомиться со следующими статьями: Workbook VBA , Worksheet VBA и Cell и Range VBA .

Использование Dim с Class Module Objects

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

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

Мы можем сделать это в операторе Dim или в операторе Set.

Следующий код создает объект, используя ключевое слово New в выражении Dim:

1

2

3

‘ Объявить и создать

Dim o As New class1

Dim coll As New Collection

Использование New в выражении Dim означает, что каждый раз при запуске нашего кода будет создаваться ровно один объект.

Использование Set дает нам больше гибкости. Мы можем создать много объектов из одной переменной. Мы также можем создать объект на основе условия.

Этот следующий код показывает, как мы создаем объект Class Module, используя Set. (Чтобы создать модуль класса, перейдите в окно проекта, щелкните правой кнопкой мыши соответствующую книгу и выберите «Вставить модуль класса». Подробнее см. «Создание Simple Class Module ».)

1

2

3

4

5

‘ Объявить только

Dim o As Class1

‘ Создать с помощью Set

Set o = New Class1

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

Мы используем Set для создания объекта Class1. Это потому, что количество нужных нам объектов зависит от количества значений более 50.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

Sub IspSet()

    ‘ Объявите переменную объекта Class1

    Dim o As Class1

    ‘ Читать диапазон

    Dim i As Long

    For i = 1 To 10

        If Sheet1.Range(«A» & i).Value > 50 Then

            ‘ Создать объект, если условие выполнено

            Set o = New Class1

        End If

    Next i

End Sub

Я сохранил этот пример простым для ясности. В реальной версии этого кода мы бы заполнили объект Class Module данными и добавили его в структуру данных, такую как Collection или Dictionary.

Вот пример реальной версии, основанной на данных ниже:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

‘ Class Module — clsStudent

Public Name As String

Public Subject As String

‘ Стандартный модуль

Sub ChitatBalli()

    ‘ Создать коллекцию для хранения объектов

    Dim coll As New Collection

    ‘ Current Region получает соседние данные

    Dim rg As Range

    Set rg = Sheet1.Range(«A1»).CurrentRegion

    Dim i As Long, oStudent As clsStudent

    For i = 2 To rg.Rows.Count

        ‘ Проверьте значение

        If rg.Cells(i, 1).Value > 50 Then

            ‘ Создать новый объект

            Set oStudent = New clsStudent

            ‘ Читать данные на объект студента

            oStudent.Name = rg.Cells(i, 2).Value

            oStudent.Subject = rg.Cells(i, 3).Value

            ‘ добавить объект в коллекцию

            coll.Add oStudent

        End If

    Next i

    ‘ Распечатайте данные в Immediate Window, чтобы проверить их

    Dim oData As clsStudent

    For Each oData In coll

        Debug.Print oData.Name & » studies « & oData.Subject

    Next oData

End Sub

Чтобы узнать больше о Set вы можете заглянуть сюда.

Объекты из внешней библиотеки

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

Примерами являются библиотеки Access, Outlook и Word, которые позволяют нам взаимодействовать с этими приложениями.

Мы можем использовать библиотеки для различных типов структур данных, таких как Словарь, Массив, Стек и Очередь.

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

Мы можем создать эти объекты двумя способами:

  1. Раннее связывание
  2. Позднее связывание

Давайте посмотрим на это по очереди.

Раннее связывание

Раннее связывание означает, что мы добавляем справочный файл. Как только этот файл добавлен, мы можем рассматривать объект как объект модуля класса.

Мы добавляем ссылку, используя Tools-> Reference, а затем проверяем соответствующий файл в списке.

Например, чтобы использовать словарь, мы ставим флажок «Microsoft Scripting Runtime»

Как только мы добавим ссылку, мы можем использовать словарь как объект модуля класса

1

2

3

4

5

6

7

8

9

10

Sub RanSvyaz()

    ‘ Используйте только Dim

    Dim dict1 As New Dictionary

    ‘ Используйте Dim и Set

    Dim dict2 As Dictionary

    Set dict2 = New Dictionary

End Sub

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

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

Позднее связывание

Позднее связывание означает, что мы создаем объект во время выполнения.

Мы объявляем переменную как тип «Объект». Затем мы используем CreateObject для создания объекта.

1

2

3

4

5

6

Sub PozdSvyaz()

    Dim dict As Object

    Set dict = CreateObject(«Scripting.Dictionary»)

End Sub

Использование Dim с Arrays

В VBA есть два типа массивов:

  1. Статический — размер массива задается в операторе Dim и не может изменяться.
  2. Динамический — размер массива не указан в выражении Dim. Это устанавливается позже с помощью оператора ReDim

1

2

3

4

5

6

7

‘ Статический массив

‘ Магазины 7 длинных — от 0 до 6

Dim arrLong(0 To 6) As Long

‘ Магазины 7 длинных — от 0 до 6

Dim arrLong(6) As String

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

Мы объявляем динамический массив, используя инструкцию Dim, и устанавливаем размер позже, используя ReDim.

1

2

3

4

5

6

7

‘ Динамический массив

‘ Объявите переменную

Dim arrLong() As Long

‘ Установить размер

ReDim arrLong(0 To 6) As Long

Использование ReDim

Большая разница между Dim и ReDim заключается в том, что мы можем использовать переменную в выражении ReDim. В операторе Dim размер должен быть постоянным значением.

1

2

3

4

5

6

7

8

9

10

11

12

13

Sub IspSet()

    ‘ Объявите переменную

    Dim arrLong() As Long

    ‘ Спросите пользователя о размере

    Dim size As Long

    size = InputBox(«Пожалуйста, введите размер массива.», Default:=1)

    ‘ Установите размер на основе пользовательского ввода

    ReDim arrLong(0 To size) As Long

End Sub

На самом деле мы можем использовать оператор Redim без предварительного использования оператора Dim.

В первом примере вы можете видеть, что мы используем Dim:

1

2

3

4

5

6

7

8

9

10

11

Sub IspDimReDim()

    ‘ Использование Dim

    Dim arr() As String

    ReDim arr(1 To 5) As String

    arr(1) = «Яблоко»

    arr(5) = «Апельсин»

End Sub

Во втором примере мы не используем Dim:

1

2

3

4

5

6

7

8

9

Sub IspTolkoReDim ()

    ‘ Использование только ReDim

    ReDim arr(1 To 5) As String

    arr(1) = «Яблоко»

    arr(5) = «Апельсин»

End Sub

Преимущество состоит в том, что вам не нужно тусклое утверждение. Недостатком является то, что это может сбить с толку тех, кто читает ваш код. В любом случае это не имеет большого значения.

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

Вы можете найти все, что вам нужно знать о массивах в VBA здесь .

Устранение неполадок ошибок  Dim

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

Ошибка

Тип

Причина

Массив уже
рассчитан

Компиляция

Использование
Redim для
статического
массива.

Ожидаемый:
идентификатор

Синтаксис

Использование
зарезервированного слова в качестве
имени переменной.

Ожидаемый:
новый тип имени

Синтаксис

Тип отсутствует в
выражении Dim.

Переменная объекта или переменная
блока не
установлена

Время выполнения

New не был
использован для
создания объекта.

Переменная объекта или переменная
блока
не установлена

Время выполнения

Set не использовался для назначения
переменной объекта.

Пользовательский
тип не определен

Компиляция

Тип не распознан.
Это может
произойти, если
ссылочный файл не добавлен в меню
«Инструменты->
Ссылка» или имя
модуля класса
написано
неправильно.

Недопустимый
оператор вне блока
Type

Компиляция

Имя переменной
отсутствует в
выражении Dim

Переменная
не определена

Компиляция

Переменная
используется перед Dim-строкой.

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

Когда мы используем Dim в процедуре (то есть подпрограмме или функции), она считается локальной. Это означает, что это доступно только с этой процедурой.

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

В приведенном ниже коде мы объявили count как глобальную переменную:

1

2

3

4

5

6

7

8

‘ Глобальная

Dim count As Long

Sub UseCount1()

    count = 6

End Sub

Sub UseCount2()

    count = 4

End Sub

Что произойдет, если у нас будет глобальная переменная и локальная переменная с одинаковым именем?

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

1

2

3

4

5

6

7

8

9

10

11

‘ Глобальная

Dim count As Long

Sub UseCount()

    ‘ Локальная

    Dim count As Long

    ‘ Относится к локальному счету

    count = 6

End Sub

Подобная ситуация может привести только к проблемам, так как трудно отследить, какой счет используется.

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

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

Dim против Private

В VBA есть ключевое слово Private.

Если мы используем ключевое слово Private с переменной или подфункцией / функцией, то этот элемент доступен только в текущем модуле.

Использование Dim и Private для переменной дает тот же результат

1

2

3

4

5

6

7

8

9

10

11

‘ Доступно во всем этом модуле

Private priCount As Long

Dim dimCount As Long

Sub UseCount()

    ‘ Доступно только в этом разделе

    Private priName As String

    Dim dimName As String

End Sub

В VBA принято использовать Private для глобальных переменных и Dim для локальных

1

2

3

4

5

6

7

8

‘ Доступно во всем этом модуле

Private priCount As Long

Sub UseCount()

    ‘ Только локальный

    Dim dimName As String

End Sub

Local OnlyThere в VBA есть 2 других типа объявлений, которые называются Public и Global.

Ниже приводится краткое изложение всех 4 типов:

  1. Dim — используется для объявления локальных переменных, т. Е. В процедурах.
  2. Private — используется для объявления глобальных переменных и процедур. Эти переменные доступны только для текущего модуля.
  3. Public — используется для объявления глобальных переменных и процедур. Эти переменные доступны во всех модулях.
  4. Global — старая и устаревшая версия Public. Может использоваться только в стандартных модулях. Он существует только для обратной совместимости.

Заключение

На этом мы заканчиваем статью о VBA Dim Statement. Если у вас есть какие-либо вопросы или мысли, пожалуйста, дайте мне знать в комментариях ниже.

Источник

Понравилась статья? Поделить с друзьями:
  • Vba excel подчеркивание текста
  • Vba excel подсчет уникальных значений
  • Vba excel подсчет символов в строке
  • Vba excel подсчет количества строк
  • Vba excel подсчет количества значений