Пользовательское соглашение
Политика конфиденциальности
© Николай Павлов, Planetaexcel, 2006-2023
info@planetaexcel.ru
Использование любых материалов сайта допускается строго с указанием прямой ссылки на источник, упоминанием названия сайта, имени автора и неизменности исходного текста и иллюстраций.
Техническая поддержка сайта
ООО «Планета Эксел» ИНН 7735603520 ОГРН 1147746834949 |
ИП Павлов Николай Владимирович ИНН 633015842586 ОГРНИП 310633031600071 |
Хитрости »
1 Май 2011 52120 просмотров
Option Explicit — начинающие программировать в Visual Basic могут увидеть данную строку в чужом коде, либо случайно в своем. Хотя кто-то может быть уже знает, что это и зачем и использует данное объявление намеренно. Я же постараюсь максимально подробно описать смысл этой строки и её полезность для кода в первую очередь для тех, кто еще не знает для чего она.
Строка данная записывается в самом начале модуля, самой первой строкой. Перед этой строкой ничего более не может быть записано, кроме, разве что других подобных строк(есть еще другие :-))
Собственно что же делает эта строка? А делает она следующее: она принуждает Вас объявлять переменные(если не знаете смысл объявления переменных — читайте здесь). Если какая-либо переменная внутри выполняемой процедуры не объявлена — Вы увидите такое вот сообщение:
рис.1
так же редактор VBA выделит ту переменную, которая не объявлена. Первое время это может раздражать. Да и вообще: зачем это? Вы и без всех этих объявлений неплохо жили. А вот зачем
- во-первых: объявление переменных считается хорошим тоном при программировании
- во-вторых: правильное присвоение типов недурно экономит память
- ну и в-третьих(я бы даже сказал в главных): это помогает избежать неявных ошибок кода при несовпадении типов данных
А теперь перейдем к сути и попробуем разобраться в чем же польза от использования Option Explicit. Ниже приведен простой код:
Sub Check_Variables() Dim a As String a = "Привет от www.excel-vba.ru" MsgBox а, vbInformation End Sub
Выполните данный код без строки Option Explicit. Какое значение выдаст MsgBox? Ничего. Что за странность? Ведь явно видно, что переменной присвоено значение текста. Ничего больше не происходит. Но переменная все равно пуста. Мистика…А теперь запишите первой строкой в модуле Option Explicit:
Option Explicit Sub Check_Variables() Dim a As String a = "Привет от www.excel-vba.ru" MsgBox а, vbInformation End Sub
Запустите код. И что же видите? Видите сообщение, показанное на рис.1 и выделенную переменную «а», в последней строке. Что это означает? Это означает, что переменная «а» у нас не объявлена. А все потому, что первой строкой (Dim a As String) я объявил переменную на английском языке, а в последней строке я записал её на русском. А для кода это разные символы. Если разглядеть логику работы VBA — первую «а» он видит как переменную с присвоенным типом String. И ей мы задаем значение «Привет от www.excel-vba.ru». А вторую…Вторую он не находит в объявленных переменных, не находит в функциях и сам инициализирует её как новую переменную с типом данных Variant. И, что вполне логично, со значением Empty, т.е. ничего, т.к. этой переменной мы никаких значений не присваивали.
Еще один классический пример, когда Option Explicit спасет от лишних мозговых штурмов. Имеем простую функцию пользователя(UDF), которая берет указанную дату и возвращает её в заранее заданном формате в текстовом виде:
Function GetDateAsText(Optional ByVal Дата As Date) If Дата = 0 Then Дата = Date End If GetDataAsText = Format(Дата, "DD MMMM YYYY") End Function
Хоть функция и короткая, но даже в ней не сразу порой бросается в глаза опечатка(представим, если функция в реальности строк на 200). В итоге чаще всего автор функции не понимает, почему при записи её на листе она возвращает не дату вида «21 мая 2016», а 0 и начинает пошагово выполнять функцию, искать ошибки в логике кода и т.д. Но если поставить в начало модуля Option Explicit, то при первом же выполнении этой функции VBA подсветит нам «GetDataAsText = «, указывая тем самым, что GetDataAsText в чем-то отличается от заданного имени функции — GetDateAsText. Банальная опечатка: GetDataAsText — GetDateAsText.
А теперь представьте себе, что Вы написали кучу длинного кода, строк на 100 или более. Конечно, Option Explicit Вы не используете. И вот Вы тестируете код, но он работает как-то не так…Где-то что-то неверно выполняется. И Вы начинаете пошагово ковыряться в листинге и искать ошибку…А ведь все может быть и проще: где-то в коде Вы могли банально опечататься и присвоить таким образом значение переменной, на которую Вы и не рассчитывали. А если использовать Option Explicit, то такая опечатка будет сразу обнаружена еще до выполнения кода и, что немаловажно — подсвечена. Так что Вам даже не придется её искать, а останется лишь исправить ошибку.
Так же эта строка поможет избежать неявных ошибок и в других ситуациях. В частности, при обращении к другим приложениями(Word, Outlook и т.д.). Например, в Excel применяются именованные константы для многих задач. Одна из распространенных — поиск последней ячейки в столбце: llast = Cells(Rows.Count, 1).End(xlUp).Row
здесь xlUp является именованной константой, значение которой равно числу: -4162. В других приложениях такой же подход. Это избавляет от необходимости помнить на память все значения констант и обращаться к ним при помощи intellisense. Но действуют эти константы исключительно внутри своего приложения(можете обратить внимание, у Excel константы начинаются с xl, а у Word — с wd). И т.к. объявлены эти константы в других приложениях — Excel про них не знает(как и другие приложения не знают про константы Excel). Для примера возьмем простой и рабочий код замены в Word:
Dim wdDoc As Object Set wdDoc = objWordApp.ActiveDocument With wdDoc.Range.Find .Text = "привет" .Replacement.Text = "привет" .wrap = wdFindContinue .Execute Replace:=wdReplaceAll End With
Где wdFindContinue для Word-а равно 1, а wdReplaceAll = 2. Но это происходит только при выполнении изнутри самого Word-а(или при раннем связывании через Tools —References. Подробнее про это можно почитать в статье: Как из Excel обратиться к другому приложению).
Если же скопировать и выполнять данный код из Excel, то работать он будет не так как задумали. Дело в том, что Вы считаете, что Excel работает с обозначенными константами(wdFindContinue, wdReplaceAll) наравне с Word-ом. Но Excel на самом деле про них ничего не знает. И если директива Option Explicit будет отключена, то Excel просто назначает им значение по умолчанию — Empty. Которое преобразуется в 0. А это совсем иной поиск получается, т.к. должны быть значения 1 и 2. А если бы Option Explicit была включена, то Excel выделил бы их и указал, что они не объявлены. И тогда можно было бы сделать либо так:
Dim wdDoc As Object Const wdFindContinue As Long = 1 Const wdReplaceAll As Long = 2 Set wdDoc = objWordApp.ActiveDocument With wdDoc.Range.Find .Text = "привет" .Replacement.Text = "привет" .wrap = wdFindContinue .Execute Replace:=wdReplaceAll End With
либо так(что удобнее, на мой взгляд):
Dim wdDoc As Object Set wdDoc = objWordApp.ActiveDocument With wdDoc.Range.Find .Text = "привет" .Replacement.Text = "привет" .wrap = 1 .Execute Replace:=2 End With
Так что думаю, не стоит недооценивать значимость строки Option Explicit при написании кодов. В довершение хотелось бы Вас обрадовать, что вписывание данной строки в начало каждого модуля можно сделать автоматическим: поставить в опциях редактора галочку: Tools—Options-вкладка Editor—Require Variable Declaration. Теперь во всех новых созданных модулях строка Option Explicit будет создаваться самим редактором VBA автоматически. К сожалению, в уже имеющихся модулях Вам придется проставить данную строку самим вручную. Но это того стоит, поверьте.
Так же см.:
Что такое переменная и как правильно её объявить?
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
Хитрости »
1 Май 2011 50924 просмотров
Option Explicit — начинающие программировать в Visual Basic могут увидеть данную строку в чужом коде, либо случайно в своем. Хотя кто-то может быть уже знает, что это и зачем и использует данное объявление намеренно. Я же постараюсь максимально подробно описать смысл этой строки и её полезность для кода в первую очередь для тех, кто еще не знает для чего она.
Строка данная записывается в самом начале модуля, самой первой строкой. Перед этой строкой ничего более не может быть записано, кроме, разве что других подобных строк(есть еще другие :-))
Собственно что же делает эта строка? А делает она следующее: она принуждает Вас объявлять переменные(если не знаете смысл объявления переменных — читайте здесь). Если какая-либо переменная внутри выполняемой процедуры не объявлена — Вы увидите такое вот сообщение:
рис.1
так же редактор VBA выделит ту переменную, которая не объявлена. Первое время это может раздражать. Да и вообще: зачем это? Вы и без всех этих объявлений неплохо жили. А вот зачем
- во-первых: объявление переменных считается хорошим тоном при программировании
- во-вторых: правильное присвоение типов недурно экономит память
- ну и в-третьих(я бы даже сказал в главных): это помогает избежать неявных ошибок кода при несовпадении типов данных
А теперь перейдем к сути и попробуем разобраться в чем же польза от использования Option Explicit. Ниже приведен простой код:
Sub Check_Variables() Dim a As String a = "Привет от www.excel-vba.ru" MsgBox а, vbInformation End Sub
Выполните данный код без строки Option Explicit. Какое значение выдаст MsgBox? Ничего. Что за странность? Ведь явно видно, что переменной присвоено значение текста. Ничего больше не происходит. Но переменная все равно пуста. Мистика…А теперь запишите первой строкой в модуле Option Explicit:
Option Explicit Sub Check_Variables() Dim a As String a = "Привет от www.excel-vba.ru" MsgBox а, vbInformation End Sub
Запустите код. И что же видите? Видите сообщение, показанное на рис.1 и выделенную переменную «а», в последней строке. Что это означает? Это означает, что переменная «а» у нас не объявлена. А все потому, что первой строкой (Dim a As String) я объявил переменную на английском языке, а в последней строке я записал её на русском. А для кода это разные символы. Если разглядеть логику работы VBA — первую «а» он видит как переменную с присвоенным типом String. И ей мы задаем значение «Привет от www.excel-vba.ru». А вторую…Вторую он не находит в объявленных переменных, не находит в функциях и сам инициализирует её как новую переменную с типом данных Variant. И, что вполне логично, со значением Empty, т.е. ничего, т.к. этой переменной мы никаких значений не присваивали.
Еще один классический пример, когда Option Explicit спасет от лишних мозговых штурмов. Имеем простую функцию пользователя(UDF), которая берет указанную дату и возвращает её в заранее заданном формате в текстовом виде:
Function GetDateAsText(Optional ByVal Дата As Date) If Дата = 0 Then Дата = Date End If GetDataAsText = Format(Дата, "DD MMMM YYYY") End Function
Хоть функция и короткая, но даже в ней не сразу порой бросается в глаза опечатка(представим, если функция в реальности строк на 200). В итоге чаще всего автор функции не понимает, почему при записи её на листе она возвращает не дату вида «21 мая 2016», а 0 и начинает пошагово выполнять функцию, искать ошибки в логике кода и т.д. Но если поставить в начало модуля Option Explicit, то при первом же выполнении этой функции VBA подсветит нам «GetDataAsText = «, указывая тем самым, что GetDataAsText в чем-то отличается от заданного имени функции — GetDateAsText. Банальная опечатка: GetDataAsText — GetDateAsText.
А теперь представьте себе, что Вы написали кучу длинного кода, строк на 100 или более. Конечно, Option Explicit Вы не используете. И вот Вы тестируете код, но он работает как-то не так…Где-то что-то неверно выполняется. И Вы начинаете пошагово ковыряться в листинге и искать ошибку…А ведь все может быть и проще: где-то в коде Вы могли банально опечататься и присвоить таким образом значение переменной, на которую Вы и не рассчитывали. А если использовать Option Explicit, то такая опечатка будет сразу обнаружена еще до выполнения кода и, что немаловажно — подсвечена. Так что Вам даже не придется её искать, а останется лишь исправить ошибку.
Так же эта строка поможет избежать неявных ошибок и в других ситуациях. В частности, при обращении к другим приложениями(Word, Outlook и т.д.). Например, в Excel применяются именованные константы для многих задач. Одна из распространенных — поиск последней ячейки в столбце: llast = Cells(Rows.Count, 1).End(xlUp).Row
здесь xlUp является именованной константой, значение которой равно числу: -4162. В других приложениях такой же подход. Это избавляет от необходимости помнить на память все значения констант и обращаться к ним при помощи intellisense. Но действуют эти константы исключительно внутри своего приложения(можете обратить внимание, у Excel константы начинаются с xl, а у Word — с wd). И т.к. объявлены эти константы в других приложениях — Excel про них не знает(как и другие приложения не знают про константы Excel). Для примера возьмем простой и рабочий код замены в Word:
Dim wdDoc As Object Set wdDoc = objWordApp.ActiveDocument With wdDoc.Range.Find .Text = "привет" .Replacement.Text = "привет" .wrap = wdFindContinue .Execute Replace:=wdReplaceAll End With
Где wdFindContinue для Word-а равно 1, а wdReplaceAll = 2. Но это происходит только при выполнении изнутри самого Word-а(или при раннем связывании через Tools —References. Подробнее про это можно почитать в статье: Как из Excel обратиться к другому приложению).
Если же скопировать и выполнять данный код из Excel, то работать он будет не так как задумали. Дело в том, что Вы считаете, что Excel работает с обозначенными константами(wdFindContinue, wdReplaceAll) наравне с Word-ом. Но Excel на самом деле про них ничего не знает. И если директива Option Explicit будет отключена, то Excel просто назначает им значение по умолчанию — Empty. Которое преобразуется в 0. А это совсем иной поиск получается, т.к. должны быть значения 1 и 2. А если бы Option Explicit была включена, то Excel выделил бы их и указал, что они не объявлены. И тогда можно было бы сделать либо так:
Dim wdDoc As Object Const wdFindContinue As Long = 1 Const wdReplaceAll As Long = 2 Set wdDoc = objWordApp.ActiveDocument With wdDoc.Range.Find .Text = "привет" .Replacement.Text = "привет" .wrap = wdFindContinue .Execute Replace:=wdReplaceAll End With
либо так(что удобнее, на мой взгляд):
Dim wdDoc As Object Set wdDoc = objWordApp.ActiveDocument With wdDoc.Range.Find .Text = "привет" .Replacement.Text = "привет" .wrap = 1 .Execute Replace:=2 End With
Так что думаю, не стоит недооценивать значимость строки Option Explicit при написании кодов. В довершение хотелось бы Вас обрадовать, что вписывание данной строки в начало каждого модуля можно сделать автоматическим: поставить в опциях редактора галочку: Tools—Options-вкладка Editor—Require Variable Declaration. Теперь во всех новых созданных модулях строка Option Explicit будет создаваться самим редактором VBA автоматически. К сожалению, в уже имеющихся модулях Вам придется проставить данную строку самим вручную. Но это того стоит, поверьте.
Так же см.:
Что такое переменная и как правильно её объявить?
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
Hi I develop the first time using VBA (Was using vb.net etc. before).
I always get the error
Variable is not defined
when running the code.
On calling the method writeHeaders
the program always quits.
Some help would be highly appreciated, this thing drives me nuts atm.
Option Explicit
Sub exportToAPplus()
Dim applusImport As Workbook
Set applusImport = createFile
writeHeaders applusImport
End Sub
Function createFile() As Workbook
Dim dateiName As String
dateiName = Application.GetSaveAsFilename()
If dateiName <> "Falsch" And dateiName <> "False" Then
Dim applusImport As Workbook
dateiName = dateiName + "xlsx"
Set applusImport = Workbooks.Add
Application.DisplayAlerts = False
applusImport.SaveAs dateiName, FileFormat:=xlOpenXMLWorkbook
Application.DisplayAlerts = True
Set createFile = applusImport
Else
MsgBox ("Sie haben keinen Dateinamen ausgewählt, es wurde nichts
gespeichert.")
End If
End Function
Sub writeHeaders(applusImport As Workbook)
Dim headers() As Variant
headers() = Array("DATUM", "AUFTRAG", "PERSONAL", "KSTR", "INNENAUFTRAG", "POSITION", "AG", "KAPAST", "MASCHINENGRUPPE", "START", "ENDE", "DAUER", "BESCHREIBUNG")
Application.ScreenUpdating = False
For i = LBound(headers()) To UBound(headers()) Step 1
.Cells(1, 1 + i).Value = headers(i)
Next i
applusImport.Save
Application.ScreenUpdating = True
End Sub
Hi I develop the first time using VBA (Was using vb.net etc. before).
I always get the error
Variable is not defined
when running the code.
On calling the method writeHeaders
the program always quits.
Some help would be highly appreciated, this thing drives me nuts atm.
Option Explicit
Sub exportToAPplus()
Dim applusImport As Workbook
Set applusImport = createFile
writeHeaders applusImport
End Sub
Function createFile() As Workbook
Dim dateiName As String
dateiName = Application.GetSaveAsFilename()
If dateiName <> "Falsch" And dateiName <> "False" Then
Dim applusImport As Workbook
dateiName = dateiName + "xlsx"
Set applusImport = Workbooks.Add
Application.DisplayAlerts = False
applusImport.SaveAs dateiName, FileFormat:=xlOpenXMLWorkbook
Application.DisplayAlerts = True
Set createFile = applusImport
Else
MsgBox ("Sie haben keinen Dateinamen ausgewählt, es wurde nichts
gespeichert.")
End If
End Function
Sub writeHeaders(applusImport As Workbook)
Dim headers() As Variant
headers() = Array("DATUM", "AUFTRAG", "PERSONAL", "KSTR", "INNENAUFTRAG", "POSITION", "AG", "KAPAST", "MASCHINENGRUPPE", "START", "ENDE", "DAUER", "BESCHREIBUNG")
Application.ScreenUpdating = False
For i = LBound(headers()) To UBound(headers()) Step 1
.Cells(1, 1 + i).Value = headers(i)
Next i
applusImport.Save
Application.ScreenUpdating = True
End Sub
ГЛАВНАЯ
ТРЕНИНГИ
Быстрый старт
Расширенный Excel
Мастер Формул
Прогнозирование
Визуализация
Макросы на VBA
КНИГИ
Готовые решения
Мастер Формул
Скульптор данных
ВИДЕОУРОКИ
ПРИЕМЫ
Бизнес-анализ
Выпадающие списки
Даты и время
Диаграммы
Диапазоны
Дубликаты
Защита данных
Интернет, email
Книги, листы
Макросы
Сводные таблицы
Текст
Форматирование
Функции
Всякое
PLEX
Коротко
Подробно
Версии
Вопрос-Ответ
Скачать
Купить
ПРОЕКТЫ
ОНЛАЙН-КУРСЫ
ФОРУМ
Excel
Работа
PLEX
© Николай Павлов, Planetaexcel, 2006-2022
info@planetaexcel.ru
Использование любых материалов сайта допускается строго с указанием прямой ссылки на источник, упоминанием названия сайта, имени автора и неизменности исходного текста и иллюстраций.
Техническая поддержка сайта
ООО «Планета Эксел» ИНН 7735603520 ОГРН 1147746834949 |
ИП Павлов Николай Владимирович ИНН 633015842586 ОГРНИП 310633031600071 |
На чтение 25 мин. Просмотров 11k.
Алан Перлис
Постоянная одного человека — переменная другого
Эта статья содержит полное руководство по работе с переменными и использованию VBA Dim.
Первый раздел содержит краткое руководство по использованию оператора
Dim, включая примеры и формат оператора Dim.
Остальная часть поста содержит наиболее полное руководство, которое вы
найдете в VBA Dim Statement.
Если вы заинтересованы в объявлении параметров, вы можете прочитать о
них здесь.
Содержание
- Краткое руководство по использованию VBA Dim Statement
- Полезные ссылки
- Что такое VBA Dim Statement?
- Формат VBA Dim Statement
- Как использовать Dim с несколькими переменными
- Где я должен поместить Dim Statement?
- Использование Dim в циклах
- Могу ли я использовать Dim для присвоения значения?
- Dim действительно требуется?
- Использование Dim с Basic Variables
- Использование Dim с Variants
- Использование Dim с Objects
- Использование Dim с Arrays
- Устранение неполадок ошибок Dim
- Локальные и глобальные переменные
- Заключение
Краткое руководство по использованию 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. Все они очень похожи по синтаксису.
Вот они:
- Basic variable
- Variant
- Object
- Array
Ниже приводится краткое описание каждого типа
- Basic variable — этот тип переменной содержит одно значение. Это такие типы, как Long, String, Date, Double, Currency.
- Variant — VBA решает во время выполнения, какой тип будет использоваться. Вы должны избегать вариантов, где это возможно, но в некоторых случаях требуется их использование.
- Object — это переменная, которая может иметь несколько методов (то есть подпрограмм / функций) и несколько свойств (то есть значений). Есть 3 вида:
Объекты Excel, такие как объекты Workbook, Worksheet и Range.
Пользовательские объекты, созданные с использованием модулей классов.
Внешние библиотеки, такие как Словарь. - 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 утверждений, вы можете сделать это двумя основными способами. Вы можете разместить все свои 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. В этом случае переменная автоматически будет типом
варианта.
Это может привести к таким проблемам, как
- Все переменные являются вариантами (проблемы с
этим см. В разделе «Варианты»). - Некоторые переменные ошибки останутся
незамеченными.
Из-за этих проблем рекомендуется сделать использование Dim
обязательным в нашем коде. Мы делаем это с помощью оператора Option Explicit.
Option Explicit
Мы можем сделать Dim
обязательным в модуле, набрав «Option Explicit» в верхней части модуля.
Мы можем сделать это автоматически в каждом новом модуле,
выбрав Tools-> Options из меню и отметив флажок «Требовать декларацию
переменной». Затем, когда вы вставите новый модуль, «Option Explicit» будет
автоматически добавлен в начало.
Давайте посмотрим на некоторые ошибки, которые могут
остаться незамеченными, если мы не будем использовать 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 не была определена.
Это действительно полезно, так как помогает нам найти
ошибку, которая в противном случае осталась бы незамеченной.
Ошибка в ключевом слове
Вот второй пример, который более тонкий.
Когда следующий код выполняется, он должен изменить шрифт в
ячейке 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
Однако использование вариантов является плохой практикой, и
вот почему:
- VBA
не будет замечать неправильных ошибок типа (т. Е. Несоответствие данных). - Вы не можете получить доступ к Intellisense.
- 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 на скриншоте ниже
Если вы используете Variant как тип, то Intellisense будет
недоступен
Это потому, что VBA не будет знать тип переменной до времени
выполнения.
Использование Dim с Objects
Если вы не знаете, что такое Objects, вы можете прочитать
мою статью об VBA Objects здесь.
Есть 3 типа объектов:
- Объекты Excel
- Объекты модуля класса
- Внешние объекты библиотеки
Примечание. Объект 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.
Вот пример реальной версии, основанной на данных ниже:
' 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) и многих других задач.
Мы можем создать эти объекты двумя способами:
- Раннее связывание
- Позднее связывание
Давайте посмотрим на это по очереди.
Раннее связывание
Раннее связывание означает, что мы добавляем справочный
файл. Как только этот файл добавлен, мы можем рассматривать объект как объект
модуля класса.
Мы добавляем ссылку, используя Tools-> Reference, а затем
проверяем соответствующий файл в списке.
Например, чтобы использовать словарь, мы ставим флажок
«Microsoft Scripting Runtime»
Как только мы добавим ссылку, мы можем использовать словарь
как объект модуля класса
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 есть два типа массивов:
- Статический — размер массива задается в
операторе Dim и не может изменяться. - Динамический — размер массива не указан в
выражении 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 типов:
- Dim
— используется для объявления локальных переменных, т. Е. В процедурах. - Private
— используется для объявления глобальных переменных и процедур. Эти переменные
доступны только для текущего модуля. - Public
— используется для объявления глобальных переменных и процедур. Эти переменные
доступны во всех модулях. - Global
— старая и устаревшая версия Public.
Может использоваться только в стандартных модулях. Он существует только для обратной
совместимости.
Заключение
На этом мы заканчиваем статью о VBA Dim Statement. Если у вас есть
какие-либо вопросы или мысли, пожалуйста, дайте мне знать в комментариях ниже.
При выполнении макросов Excel могут возникнуть ошибки, которые в VBA делят на три категории:
- Ошибки компиляции
- Ошибки выполнения
- Логические ошибки (баги)
Далее мы поговорим о каждом из трёх типов ошибок VBA подробно.
Содержание
- Ошибки компиляции
- Ошибки выполнения
- Перехват ошибок выполнения
- Логические ошибки
Ошибки компиляции
Компилятор VBA рассматривает ошибки компиляции как недопустимые и выделяет их в коде ещё до того, как дело дойдёт до запуска макроса.
Если при написании кода допущена синтаксическая ошибка, то редактор VBA сигнализирует об этом немедленно: либо при помощи окна с сообщением, либо выделяя ошибку красным цветом, в зависимости от статуса режима Auto Syntax Check.
Примечание: При включённом режиме Auto Syntax Check каждый раз, при появлении в редакторе Visual Basic во введённом коде синтаксической ошибки, будет показано соответствующее сообщение. Если же этот режим выключен, то редактор VBA продолжит сообщать о синтаксических ошибках, просто выделяя их красным цветом. Опцию Auto Syntax Check можно включить/выключить в меню Tools > Options редактора Visual Basic.
В некоторых случаях ошибка компиляции может быть обнаружена при выполнении компиляции кода, непосредственно перед тем, как макрос будет выполнен. Обычно ошибку компиляции несложно обнаружить и исправить, потому что компилятор VBA даёт информацию о характере и причине ошибки.
Например, сообщение «Compile error: Variable not defined» при попытке запустить выполнение кода VBA говорит о том, что происходит попытка использовать или обратиться к переменной, которая не была объявлена для текущей области (такая ошибка может возникнуть только если используется Option Explicit).
Ошибки выполнения
Ошибки выполнения возникают в процессе выполнения кода и приводят к остановке выполнения программы. Этот тип ошибок VBA, как правило, также не сложно обнаружить и исправить, так как сообщается информация о характере ошибки и место в коде, где произошла остановка.
Примером такой ошибки может служить попытка выполнить деление на ноль. В результате будет показано сообщение «Run-time error ’11’: Division by zero«.
В зависимости от структуры проекта VBA, может быть предложено выполнить отладку кода (как показано на рисунке ниже). В этом случае при нажатии на кнопку Debug (в окне сообщения о необходимости отладки) будет выделена цветом строка кода, которая стала причиной ошибки VBA.
Получив такое сообщение и видя выделенную строку кода, как в приведённом выше примере, обнаружить причину ошибки будет совсем не сложно.
В случае если код сложнее, чем в нашем примере, то, чтобы получить больше информации о причине возникновения ошибки VBA, можно проверить значения используемых переменных. В редакторе VBA для этого достаточно навести указатель мыши на имя переменной, или можно открыть окно отслеживания локальных переменных (в меню редактора View > Locals Window).
Коды различных ошибок выполнения расшифрованы на сайте Microsoft Support (на английском). Наиболее часто встречающиеся ошибки VBA перечислены в этой таблице:
5 | Недопустимый вызов процедуры (Invalid procedure call) |
7 | Недостаточно памяти (Out of memory) |
9 | Индекс вне заданного диапазона (Subscript out of range)
Эта ошибка возникает при попытке обратиться к элементу массива за пределами заданного размера массива – например, если объявлен массив с индексами от 1 до 10, а мы пытаемся обратиться к элементу этого же массива с индексом 11. |
11 | Деление на ноль (Division by zero) |
13 | Несоответствие типа (Type mismatch)
Эта ошибка возникает при попытке присвоить переменной значение не соответствующего типа – например, объявлена переменная i типа Integer, и происходит попытка присвоить ей значение строкового типа. |
53 | Файл не найден (File not found)
Иногда возникает при попытке открыть не существующий файл. |
Перехват ошибок выполнения
Не все ошибки выполнения бывают вызваны недочётами в коде. Например, ошибки VBA не удастся избежать, если для работы макроса необходимо открыть файл с данными, а этого файла не существует. В таких случаях признаком профессионализма будет перехват ошибок и написание кода VBA, который будет выполняться при их возникновении. Таким образом, вместо неприятных сбоев будет происходить изящное завершение работы макроса.
Для того, чтобы помочь справиться с возникающими ошибками, VBA предоставляет разработчику операторы On Error и Resume. Эти операторы отслеживают ошибки и направляют выполнение макроса в специальный раздел кода VBA, в котором происходит обработка ошибки. После выполнения кода обработки ошибки, работа программы может быть продолжена с того места, где возникла ошибка, или макрос может быть остановлен полностью. Далее это показано на примере.
'Процедура Sub присваивает переменным Val1 и Val2 значения, 'хранящиеся в ячейках A1 и B1 рабочей книги Data.xlsx расположенной в каталоге C:Documents and Settings Sub Set_Values(Val1 As Double, Val2 As Double) Dim DataWorkbook As Workbook On Error GoTo ErrorHandling 'Открываем рабочую книгу с данными Set DataWorkbook = Workbooks.Open("C:Documents and SettingsData") 'Присваиваем переменным Val1 и Val2 данные из рабочей книги DataWorkbook Val1 = Sheets("Лист1").Cells(1, 1) Val2 = Sheets("Лист1").Cells(1, 2) DataWorkbook.Close Exit Sub ErrorHandling: 'Если файл не найден, предлагаем пользователю разместить его в 'нужном месте и продолжить работу MsgBox "Рабочая книга не найдена! " & _ "Пожалуйста добавьте книгу Data.xlsx в каталог C:Documents and Settings и нажмите OK." Resume End Sub
В этом коде производится попытка открыть файл Excel с именем Data. Если файл не найден, то пользователю будет предложено поместить этот файл в нужную папку. После того, как пользователь сделает это и нажмёт ОК, выполнение кода продолжится, и попытка открыть этот файл повторится. При желании вместо попытки открыть нужный файл, выполнение процедуры Sub может быть прервано в этом месте при помощи команды Exit Sub.
Логические ошибки
Логические ошибки (или баги) возникают в процессе выполнения кода VBA, но позволяют ему выполняться до самого завершения. Правда в результате могут выполняться не те действия, которые ожидалось, и может быть получен неверный результат. Такие ошибки обнаружить и исправить труднее всего, так как компилятор VBA их не распознаёт и не может указать на них так, как это происходит с ошибками компиляции и выполнения.
Например, при создании макроса в процедуре случайно были просуммированы не те переменные, которые требовалось просуммировать. Результат будет ошибочным, но макрос будет продолжать выполняться до завершения.
Редактор Excel VBA предоставляет набор инструментов отладки, которые помогут найти и исправить логические ошибки в коде VBA. В данной статье мы не будем рассматривать подробно эти инструменты. Любознательный пользователь может найти обзор инструментов отладки VBA на сайте Microsoft Help & Support (на английском).
Оцените качество статьи. Нам важно ваше мнение:
Работа с переменными
Автор Дмитрий Якушев На чтение25 мин. Просмотров271
Алан Перлис
Постоянная одного человека — переменная другого
Эта статья содержит полное руководство по работе с переменными и использованию VBA Dim.
Первый раздел содержит краткое руководство по использованию оператора Dim, включая примеры и формат оператора Dim.
Остальная часть поста содержит наиболее полное руководство, которое вы найдете в VBA Dim Statement.
Если вы заинтересованы в объявлении параметров, вы можете прочитать о них здесь.
Содержание
- Краткое руководство по использованию VBA Dim Statement
- Полезные ссылки
- Что такое VBA Dim Statement?
- Формат VBA Dim Statement
- Как использовать Dim с несколькими переменными
- Где я должен поместить Dim Statement?
- Использование Dim в циклах
- Могу ли я использовать Dim для присвоения значения?
- Dim действительно требуется?
- Option Explicit
- Ошибки Переменной
- Ошибка в ключевом слове
- Использование Dim с Basic Variables
- Фиксированный тип строки
- Использование Dim с Variants
- Тип ошибки
- Доступ к Intellisense
- Использование Dim с Objects
- Объекты Excel
- Использование Dim с Class Module Objects
- Объекты из внешней библиотеки
- Раннее связывание
- Позднее связывание
- Использование Dim с Arrays
- Использование ReDim
- Устранение неполадок ошибок Dim
- Локальные и глобальные переменные
- Dim против Private
- Заключение
Краткое руководство по использованию VBA Dim Statement
Описание |
Формат |
Пример |
Базовая |
Dim [имя |
Dim count As Long |
Фиксированная |
Dim [имя |
Dim s As String * 4 |
Вариант |
Dim [имя |
Dim var As Variant |
Объект |
Dim [имя |
Dim coll As New |
Объект |
Dim [имя |
Dim coll As Collection |
Статический |
Dim [имя |
Dim arr(1 To 6) |
Динамический |
Dim [имя |
Dim arr() As Long |
Внешняя |
Dim [имя |
Dim dict |
Внешняя |
Dim [имя |
Dim dict As Dictionary |
Внешняя |
Dim [имя |
Dim dict As Object |
* Примечание. Для раннего связывания необходимо добавить справочный файл с помощью меню «Инструменты» -> «Ссылки». Смотрите здесь, как добавить ссылку на Dictonary.
Полезные ссылки
- Объявление параметров в подпрограмме или функции
- Использование объектов в VBA
- Массивы VBA
- Коллекции VBA
- Словарь VBA
- VBA Workbook
- VBA Worksheet
Что такое VBA Dim Statement?
Ключевое слово Dim — это сокращение от Dimension. Он используется для объявления переменных в VBA.
Объявление означает, что мы говорим VBA о переменной, которую будем использовать позже.
Существует четыре типа Dim Statement. Все они очень похожи по синтаксису.
Вот они:
- Basic variable
- Variant
- Object
- Array
Ниже приводится краткое описание каждого типа
- Basic variable — этот тип переменной содержит одно значение. Это такие типы, как Long, String, Date, Double, Currency.
- Variant — VBA решает во время выполнения, какой тип будет использоваться. Вы должны избегать вариантов, где это возможно, но в некоторых случаях требуется их использование.
- Object — это переменная, которая может иметь несколько методов (то есть подпрограмм / функций) и несколько свойств (то есть значений). Есть 3 вида:
Объекты Excel, такие как объекты Workbook, Worksheet и Range.
Пользовательские объекты, созданные с использованием модулей классов.
Внешние библиотеки, такие как Словарь. - 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. В этом случае переменная автоматически будет типом варианта.
Это может привести к таким проблемам, как
- Все переменные являются вариантами (проблемы с этим см. В разделе «Варианты»).
- Некоторые переменные ошибки останутся незамеченными.
Из-за этих проблем рекомендуется сделать использование 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 |
Long — это |
Currency |
8 байт |
от -1,79769313486231E308 |
Аналогично |
Double |
8 байт |
от -922,337,203,685,477.5808 |
|
Date |
8 байт |
С 1 января 100 |
|
String |
меняется |
От 0 до примерно |
Содержит |
* Первоначально мы использовали бы тип 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 |
Однако использование вариантов является плохой практикой, и вот почему:
- VBA не будет замечать неправильных ошибок типа (т. Е. Несоответствие данных).
- Вы не можете получить доступ к Intellisense.
- 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 типа объектов:
- Объекты Excel
- Объекты модуля класса
- Внешние объекты библиотеки
Примечание. Объект 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) и многих других задач.
Мы можем создать эти объекты двумя способами:
- Раннее связывание
- Позднее связывание
Давайте посмотрим на это по очереди.
Раннее связывание
Раннее связывание означает, что мы добавляем справочный файл. Как только этот файл добавлен, мы можем рассматривать объект как объект модуля класса.
Мы добавляем ссылку, используя 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 есть два типа массивов:
- Статический — размер массива задается в операторе Dim и не может изменяться.
- Динамический — размер массива не указан в выражении 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 для объяснения различных типов ошибок.
Ошибка |
Тип |
Причина |
Массив уже |
Компиляция |
Использование |
Ожидаемый: |
Синтаксис |
Использование |
Ожидаемый: |
Синтаксис |
Тип отсутствует в |
Переменная объекта или переменная |
Время выполнения |
New не был |
Переменная объекта или переменная |
Время выполнения |
Set не использовался для назначения |
Пользовательский |
Компиляция |
Тип не распознан. |
Недопустимый |
Компиляция |
Имя переменной |
Переменная |
Компиляция |
Переменная |
Локальные и глобальные переменные
Когда мы используем 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 типов:
- Dim — используется для объявления локальных переменных, т. Е. В процедурах.
- Private — используется для объявления глобальных переменных и процедур. Эти переменные доступны только для текущего модуля.
- Public — используется для объявления глобальных переменных и процедур. Эти переменные доступны во всех модулях.
- Global — старая и устаревшая версия Public. Может использоваться только в стандартных модулях. Он существует только для обратной совместимости.
Заключение
На этом мы заканчиваем статью о VBA Dim Statement. Если у вас есть какие-либо вопросы или мысли, пожалуйста, дайте мне знать в комментариях ниже.
Источник
5.4. Преимущества объявления переменных
Как вы уже знаете, в VBA переменные можно использовать без предварительного объявления и указания типа. Но такой подход допустим лишь при разработке небольших программ, состоящих буквально из пары десятков строк. Когда программа увеличивается, контролировать работу с переменными, которые спонтанно появляются в коде, становится сложно.
Необъявленные переменные могут вызывать трудно диагностируемые ошибки. Например, рассмотрим такой код (листинг 5.2.):
txt_CompanyName = "Типография" MsgBox (txt_CompanyName)
Листинг
5.2.
Пример работы с переменной
Как вы думаете, что получится при его исполнении? Очевидно, должно вывестись окно сообщения с текстом «Типография». Но это далеко не факт. По внешнему виду переменных можно предположить, что их имена написаны латинскими буквами. Предположим, что в строке, где мы присваиваем переменной значение «Типография», это так и есть. А во второй строке мы ошиблись — и вместо латинской написали русскую букву «С» (они и на клавиатуре занимают одну клавишу, а внешне различить их просто невозможно). Как результат – совершенно непонятная ошибка – все выглядит правильно, а работать не хочет.
Если бы редактор кода не давал нам пользоваться необъявленными переменными — подобного рода ошибки были бы пресечены на корню. Чтобы заставить редактор автоматически требовать объявление переменных, можно поступить одним из двух способов. Первый — вставить в раздел объявлений модуля (то есть — вне кода процедур и обработчиков событий) команду Option Explicit. Второй — включить запрещение работы с необъявленными переменными в настройках редактора. Для этого выполните команду главного меню Tools • Options (Инструменты • Опции) и в появившемся диалоговом окне на вкладке Editor (Редактор) включите параметр Require Variable Declaration (Требовать объявление переменных ).
5.5. Объявляем переменные: Dim и Static
05-02-Dim и Static.docm — пример к п. 5.5.
Лучше всего объявлять переменные перед использованием. Так вы избежите ненужных ошибок, и, при работе с объектными переменными, сможете получать подсказки при их использовании.
Рассмотрим пример. Объявление переменной с именем num_MyAge типа Byte выглядит так (листинг 5.3.):
Dim num_MyAge As Byte num_MyAge = 23
Листинг
5.3.
Объявление переменной и работа с ней
Этот код можно перевести так: «Объявить переменную типа Byte с именем num_MyAge и сделать ее доступной в модуле, в котором она объявлена». Второй строкой мы присваиваем переменной число 23.
Доступность переменной, или, как говорят, область видимости, задается ключевым словом Dim. Оно означает, что мы сможем пользоваться объявленной переменной только внутри того модуля, в котором она объявлена.
Обратите внимание на то, что если вы присваиваете значение строковой переменной — передаваемое ей значение должно быть заключено в кавычки. При присваивании значений даты соответствующим переменным, эти значения должны быть заключены в значки #. Например, так (листинг 5.4.):
Dim str_MyName as String Dim date_MyBirthDate as Date str_MyName = "Alexander" date_MyBirthDate = #January 1, 2007#
Листинг
5.4.
Работа с переменными типа String и Date
Помимо ключевого слова Dim могут использоваться и другие слова. В частности, нам будет полезна команда Static — переменная, объявленная с использованием этой команды, будет хранить свое значение между вызовами процедуры, область ее видимости аналогична переменной, объявленной с Dim. Такую переменную можно использовать для накопления каких-либо значений.
Рассмотрим пример. Создайте новый документ Microsoft Word, добавьте в него две кнопки. В обработчике события Click одной из них с именем cmd_Dim, на которой будет написано Dim, напишите такой код (листинг 5.5.)
Dim num_Counter As Integer num_Counter = num_Counter + 1 MsgBox (num_Counter)
Листинг
5.5.
Обработчик события Click кнопки cmd_Dim
Здесь мы сначала объявляем переменную типа Integer, потом присваиваем этой переменной ее же значение, увеличенное на 1, а дальше — выводим переменную в окне сообщения.
Сколько бы вы не нажимали на эту кнопку — всякий раз в окне сообщения будет выводиться единица. Ведь каждый раз, когда запускается обработчик, все происходит как бы в первый раз — информация об изменениях переменной не сохраняется при выходе из обработчика.
Вторую кнопку назовите cmd_Static, подпишите ее как Static, и в обработчик нажатия добавьте следующее (листинг 5.6.):
Static num_Counter As Integer num_Counter = num_Counter + 1 MsgBox (num_Counter)
Листинг
5.6.
Обработчик события Click кнопки cmd_Static
Единственное отличие этого текста от предыдущего — ключевое слово Static вместо Dim. Но благодаря такому объявлению, переменная хранит свое значение между запусками обработчика. Попробуйте несколько раз нажимать на кнопку Static — каждый раз вы будете видеть в окне сообщения число, увеличенное на 1.
5.6. Арифметические операторы и работа с числовыми переменными
05-03-Операторы, конкатенация.docm — пример к пп. 5.6.-5.7.
Операторы — это команды, которые используются в VBA для работы с данными. Если вы программировали когда-нибудь, например, на Basic’e или на каком-нибудь другом языке, вам уже знакомы основные операторы. Ну а если вы раньше не сталкивались с операторами в программировании, то уж со школьным курсом математики вы сталкивались точно. Большинство операторов VBA действуют точно так же, как знакомые всем арифметические операторы. В табл. 5.3. вы можете видеть описание арифметических операторов, применимых в VBA
Таблица
5.3.
Арифметические операторы VBA
Оператор | Описание |
---|---|
+ | Сложение. Например, в результате вычисления выражения 4+3 получится 7. |
– | Вычитание. |
* | Умножение |
/ | Деление |
^ | Возведение в степень, 5^2 равняется 25 |
Целочисленное деление. От результата деления отбрасывается дробная часть. Например, 10 3 равняется 3. | |
mod | Деление по модулю. Возвращает остаток от деления. Например, 10 mod 3 равняется 1 |
В VBA применяется тот же порядок обработки выражений, который принят в математике. Например, результат вычисления 2*3+7 равняется 13-ти. Так же, в математических выражениях могут использоваться круглые скобки. Однако, круглые скобки могут встретиться вам не только в математических выражениях. Скобки, как вы могли заметить из примеров, которые мы рассматривали выше, часто употребляются при вызове функций VBA, при работе с объектами и т.д.
Если снова вернуться к математике, нельзя не заметить, что редкая математическая запись обходится без знака =. Этот знак используется в VBA в нескольких ролях.
Во-первых, это оператор присваивания. Вы уже сталкивались с ним, когда присваивали какие-то значения свойствам элементов управления или переменным. Например, такая запись: num_a = 10 + 2 означает: «Присвоить переменной num_a результат сложения чисел 10 и 2 » или, проще, «а равно 10+2». Вторая роль оператора = заключается в том, что он используется в командах сравнения выражений — о них мы поговорим в следующей главе.
5.7. Конкатенация
Несколько ролей и у оператора +. Во-первых — это арифметический оператор сложения. А во-вторых — оператор конкатенации строк. Конкатенация — это нечто вроде «склеивания» строк. В качестве оператора конкатенации можно использовать и оператор &. Считается, что & использовать предпочтительнее так как он в любом случае обрабатывает операнды как строковые данные.
Давайте рассмотрим пример, который охватывает арифметические операции и конкатенацию строк.
Напишем программу, которая запрашивает имя пользователя и два числа, после чего выводит такой текст в окне сообщения (если имя введено как «Александр», первое число 2, второе – 21): «Здравствуйте, Александр. Вы ввели числа 2 и 21, их сумма равняется 23.»
Добавим кнопку в документ Microsoft Word, назовем ее cmd_Experiments, надпишем ее как Работа с операторами.
Теперь решим, какие переменные нам нужны.
Для имени пользователя это переменная типа String. Дадим ей имя str_UserName. Для чисел нам понадобится пара переменных одного из числовых типов.
Какие числа введет пользователь? Этого мы не знаем. Конечно, можно ограничить ввод проверками, но это дела будущих примеров. Предполагается, что пользователь может ввести практически любое число — целое или дробное, положительное или отрицательное. Поэтому воспользуемся типом Double. Назовем пару числовых переменных num_First и num_Second.
Создадим отдельную переменную того же типа Double для хранения суммы введенных значений – назовем ее num_Summ.
В условии нашей задачи присутствует требование вывести все введенные данные в строку, скомбинировав с определенными словами. Нам понадобится переменная типа String для хранения этой строки. Назовем ее str_Result.
Также добавим в обработчик нажатия кнопки команду Option Explicit — тогда система запретит использование необъявленных переменных.
Вы уже знакомы с функцией InputBox, которая выводит окно для ввода данных пользователем. Как вы могли убедиться, InputBox отлично справляется со вводом строковых значений. А как насчет чисел? Можем ли мы написать что-то вроде:
num_First = InputBox("Введите первое число")
Вполне можем.
Пожалуй, сейчас для вас самое сложное — это построить строку вывода, однако пользуйтесь следующими правилами и вы всегда будете правильно и быстро строить подобные строки.
Во-первых — помните, что все, что вы хотите вывести в виде неизменного текста, должно быть включено в кавычки, а имена переменных, наоборот, пишутся без кавычек. Во-вторых — используйте оператор & при «склеивании» отдельных частей строки или оператор + и функцию Str (о ней вы прочтете ниже), которая конвертирует числовые переменные в строки. Так вы будете гарантированы от неожиданностей и ошибок.
Например, пусть в переменной str_UserName хранится имя пользователя «Александр», а переменная str_Result должна содержать результат вывода. Напишем код, помещающий в str_Result строку «Привет, Александр»:
str_Result = "Привет, " & str_UserName
Видите? Ничего сложного, правда?
Обратите внимание на то, как реагирует система на использование необъявленных переменных при добавленной в модуль команде Option Explicit (рис. 5.3.).
Рис.
5.3.
Реакция системы на необъявленную переменную
Здесь вместо str_UserName мы ошибочно использовали str_UserNane. Но благодаря Option Explicit появление необъявленных переменных воспринимается как ошибка. При попытке запуска программы мы видим сообщение об ошибке: «Variable not defined» — «Переменная не определена».
Однако вернемся к нашей задаче. Мы определились с особенностями работы наиболее сложных ее частей, в итоге у нас получилось следующее (листинг 5.7.):
Dim str_UserName As String Dim str_Result As String Dim num_First As Double Dim num_Second As Double Dim num_Summ As Double str_UserName = InputBox("Введите ваше имя") num_First = InputBox("Введите первое число") num_Second = InputBox("Введите второе число") num_Summ = num_First + num_Second str_Result = "Здравствуйте, " & str_UserName _ & ". Вы ввели числа " & num_First & " и " & num_Second _ & ". Их сумма равняется " & num_Summ MsgBox (str_Result)
Листинг
5.7.
Обработчик события Click кнопки cmd_Experiments
Обратите внимание на то, что строку сборки строки вывода str_Result мы разбили на несколько частей оператором переноса строки.
0 / 0 / 0
Регистрация: 18.06.2016
Сообщений: 5
1
Ошибка компиляции: переменная, не определена
29.06.2016, 16:08. Показов 1388. Ответов 1
Вылезает ошибка при запуске программы: «Ошибка компиляции: переменная, не определена», как решить проблему?
Visual Basic | ||
|
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
title | keywords | f1_keywords | ms.prod | ms.assetid | ms.date | ms.localizationpriority |
---|---|---|---|---|---|---|
Variable not defined |
vblr6.chm1011191 |
vblr6.chm1011191 |
office |
4d8fdcc2-e4a9-7eb5-e0d4-f7a8e47b7431 |
06/08/2017 |
high |
Variable not defined
You use the Option Explicit statement to protect your modules from having undeclared variables and to eliminate the possibility of inadvertently creating new variables when typographical errors occur. This error has the following cause and solution:
- You used an Option Explicit statement to require the explicit declaration of variables, but you used a variable without declaring it. Explicitly declare the variable, or change the spelling of the variable to match that of the intended variable.
For additional information, select the item in question and press F1 (in Windows) or HELP (on the Macintosh).
[!includeSupport and feedback]
Хитрости »
1 Май 2011 51046 просмотров
Option Explicit — начинающие программировать в Visual Basic могут увидеть данную строку в чужом коде, либо случайно в своем. Хотя кто-то может быть уже знает, что это и зачем и использует данное объявление намеренно. Я же постараюсь максимально подробно описать смысл этой строки и её полезность для кода в первую очередь для тех, кто еще не знает для чего она.
Строка данная записывается в самом начале модуля, самой первой строкой. Перед этой строкой ничего более не может быть записано, кроме, разве что других подобных строк(есть еще другие :-))
Собственно что же делает эта строка? А делает она следующее: она принуждает Вас объявлять переменные(если не знаете смысл объявления переменных — читайте здесь). Если какая-либо переменная внутри выполняемой процедуры не объявлена — Вы увидите такое вот сообщение:
рис.1
так же редактор VBA выделит ту переменную, которая не объявлена. Первое время это может раздражать. Да и вообще: зачем это? Вы и без всех этих объявлений неплохо жили. А вот зачем
- во-первых: объявление переменных считается хорошим тоном при программировании
- во-вторых: правильное присвоение типов недурно экономит память
- ну и в-третьих(я бы даже сказал в главных): это помогает избежать неявных ошибок кода при несовпадении типов данных
А теперь перейдем к сути и попробуем разобраться в чем же польза от использования Option Explicit. Ниже приведен простой код:
Sub Check_Variables() Dim a As String a = "Привет от www.excel-vba.ru" MsgBox а, vbInformation End Sub
Выполните данный код без строки Option Explicit. Какое значение выдаст MsgBox? Ничего. Что за странность? Ведь явно видно, что переменной присвоено значение текста. Ничего больше не происходит. Но переменная все равно пуста. Мистика…А теперь запишите первой строкой в модуле Option Explicit:
Option Explicit Sub Check_Variables() Dim a As String a = "Привет от www.excel-vba.ru" MsgBox а, vbInformation End Sub
Запустите код. И что же видите? Видите сообщение, показанное на рис.1 и выделенную переменную «а», в последней строке. Что это означает? Это означает, что переменная «а» у нас не объявлена. А все потому, что первой строкой (Dim a As String) я объявил переменную на английском языке, а в последней строке я записал её на русском. А для кода это разные символы. Если разглядеть логику работы VBA — первую «а» он видит как переменную с присвоенным типом String. И ей мы задаем значение «Привет от www.excel-vba.ru». А вторую…Вторую он не находит в объявленных переменных, не находит в функциях и сам инициализирует её как новую переменную с типом данных Variant. И, что вполне логично, со значением Empty, т.е. ничего, т.к. этой переменной мы никаких значений не присваивали.
Еще один классический пример, когда Option Explicit спасет от лишних мозговых штурмов. Имеем простую функцию пользователя(UDF), которая берет указанную дату и возвращает её в заранее заданном формате в текстовом виде:
Function GetDateAsText(Optional ByVal Дата As Date) If Дата = 0 Then Дата = Date End If GetDataAsText = Format(Дата, "DD MMMM YYYY") End Function
Хоть функция и короткая, но даже в ней не сразу порой бросается в глаза опечатка(представим, если функция в реальности строк на 200). В итоге чаще всего автор функции не понимает, почему при записи её на листе она возвращает не дату вида «21 мая 2016», а 0 и начинает пошагово выполнять функцию, искать ошибки в логике кода и т.д. Но если поставить в начало модуля Option Explicit, то при первом же выполнении этой функции VBA подсветит нам «GetDataAsText = «, указывая тем самым, что GetDataAsText в чем-то отличается от заданного имени функции — GetDateAsText. Банальная опечатка: GetDataAsText — GetDateAsText.
А теперь представьте себе, что Вы написали кучу длинного кода, строк на 100 или более. Конечно, Option Explicit Вы не используете. И вот Вы тестируете код, но он работает как-то не так…Где-то что-то неверно выполняется. И Вы начинаете пошагово ковыряться в листинге и искать ошибку…А ведь все может быть и проще: где-то в коде Вы могли банально опечататься и присвоить таким образом значение переменной, на которую Вы и не рассчитывали. А если использовать Option Explicit, то такая опечатка будет сразу обнаружена еще до выполнения кода и, что немаловажно — подсвечена. Так что Вам даже не придется её искать, а останется лишь исправить ошибку.
Так же эта строка поможет избежать неявных ошибок и в других ситуациях. В частности, при обращении к другим приложениями(Word, Outlook и т.д.). Например, в Excel применяются именованные константы для многих задач. Одна из распространенных — поиск последней ячейки в столбце: llast = Cells(Rows.Count, 1).End(xlUp).Row
здесь xlUp является именованной константой, значение которой равно числу: -4162. В других приложениях такой же подход. Это избавляет от необходимости помнить на память все значения констант и обращаться к ним при помощи intellisense. Но действуют эти константы исключительно внутри своего приложения(можете обратить внимание, у Excel константы начинаются с xl, а у Word — с wd). И т.к. объявлены эти константы в других приложениях — Excel про них не знает(как и другие приложения не знают про константы Excel). Для примера возьмем простой и рабочий код замены в Word:
Dim wdDoc As Object Set wdDoc = objWordApp.ActiveDocument With wdDoc.Range.Find .Text = "привет" .Replacement.Text = "привет" .wrap = wdFindContinue .Execute Replace:=wdReplaceAll End With
Где wdFindContinue для Word-а равно 1, а wdReplaceAll = 2. Но это происходит только при выполнении изнутри самого Word-а(или при раннем связывании через Tools —References. Подробнее про это можно почитать в статье: Как из Excel обратиться к другому приложению).
Если же скопировать и выполнять данный код из Excel, то работать он будет не так как задумали. Дело в том, что Вы считаете, что Excel работает с обозначенными константами(wdFindContinue, wdReplaceAll) наравне с Word-ом. Но Excel на самом деле про них ничего не знает. И если директива Option Explicit будет отключена, то Excel просто назначает им значение по умолчанию — Empty. Которое преобразуется в 0. А это совсем иной поиск получается, т.к. должны быть значения 1 и 2. А если бы Option Explicit была включена, то Excel выделил бы их и указал, что они не объявлены. И тогда можно было бы сделать либо так:
Dim wdDoc As Object Const wdFindContinue As Long = 1 Const wdReplaceAll As Long = 2 Set wdDoc = objWordApp.ActiveDocument With wdDoc.Range.Find .Text = "привет" .Replacement.Text = "привет" .wrap = wdFindContinue .Execute Replace:=wdReplaceAll End With
либо так(что удобнее, на мой взгляд):
Dim wdDoc As Object Set wdDoc = objWordApp.ActiveDocument With wdDoc.Range.Find .Text = "привет" .Replacement.Text = "привет" .wrap = 1 .Execute Replace:=2 End With
Так что думаю, не стоит недооценивать значимость строки Option Explicit при написании кодов. В довершение хотелось бы Вас обрадовать, что вписывание данной строки в начало каждого модуля можно сделать автоматическим: поставить в опциях редактора галочку: Tools—Options-вкладка Editor—Require Variable Declaration. Теперь во всех новых созданных модулях строка Option Explicit будет создаваться самим редактором VBA автоматически. К сожалению, в уже имеющихся модулях Вам придется проставить данную строку самим вручную. Но это того стоит, поверьте.
Так же см.:
Что такое переменная и как правильно её объявить?
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
nicex Пользователь Сообщений: 167 |
#1 12.07.2019 15:15:57 Добрый день!, выдает ошибку Compile error: variable not defined
Я поменял местаим части кода
Подскажите корректно макрос будет работать ? |
||||
Nordheim Пользователь Сообщений: 3154 |
У вас таблица заполнена не полностью? почему в двух циклах последняя заполненная строка ищется по разным столбцам? Изменено: Nordheim — 12.07.2019 15:25:00 «Все гениальное просто, а все простое гениально!!!» |
nicex Пользователь Сообщений: 167 |
Nordheim, это только часть макроса |
Sanja Пользователь Сообщений: 14837 |
#4 12.07.2019 15:42:43
А самому попробовать? Согласие есть продукт при полном непротивлении сторон. |
||
Nordheim Пользователь Сообщений: 3154 |
#5 12.07.2019 15:49:14
Я вижу, это не ответ на вопрос, если нужна последняя строка диапазона, то я не вижу смысла в двух циклах, «Все гениальное просто, а все простое гениально!!!» |
||
nicex Пользователь Сообщений: 167 |
Sanja, я попробовал, работает, но проблема проверить результат, опасаюсь что в макросе что то не корректно обрабатывается, поэтому хочу понять не приведет ли такая замена на обум к ошибкам Nordheim, мои возможности только методом тыка адаптировать готовый код |
Nordheim Пользователь Сообщений: 3154 |
#7 12.07.2019 16:02:16
Вы не знаете как ответить на вопрос
или не хотите, меня не интересовало полный это макрос или часть, я это и так вижу.
про ваши методы я так же не спрашивал. Вопрос тут в таком случае такой, а вы уверены что код вообще работает правильно, коли вы не знаете почему определение последней заполненной строки производится по разным столбцам? «Все гениальное просто, а все простое гениально!!!» |
||||||
nicex Пользователь Сообщений: 167 |
Nordheim, я объединил два разных макроса. перед второй частью макроса : ////// iLastRow = Cells(Rows.Count, «B»).End(xlUp).Row For i = iLastRow To 1 Step -1 происходит перестановка колонок и еще какие то замены и тп и тд |
Sanja Пользователь Сообщений: 14837 |
Ошибка исчезла? Значит решение задачи, вынесенной в название Темы получено. Все остальное ЭТОЙ темы не касается. Согласие есть продукт при полном непротивлении сторон. |
Jack Famous Пользователь Сообщений: 10490 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
#10 12.07.2019 16:41:01
объявите переменную. Для того, чтобы в будущем этого избежать, прочтите инструкцию Прикрепленные файлы
Изменено: Jack Famous — 12.07.2019 16:41:33 Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
||
nicex Пользователь Сообщений: 167 |
Jack Famous, спасибо Sanja, как изменить тему на: Я поменял местаим части кода будет ли корректно макрос работать ? |
vikttur Пользователь Сообщений: 47199 |
Такая ошибка может возникнуть в тысячах разных кодов. |
название темы:
что значит сообщение Compile error: variable not defined при попытке выполнить макрос? ответ: в сообщении все сказано: Ошибка компилятора: неопределенная переменная! решение: 1. удалите строку Option Explicit Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете! |
|
RAN Пользователь Сообщений: 7081 |
Вить, коды-то разные, причина одна. этого , или этого |
vikttur Пользователь Сообщений: 47199 |
Андрей, одна в Курилке, по второй более-менее понятно по названию. |
Dima S Пользователь Сообщений: 2063 |
#16 13.07.2019 01:53:01
Dim |
||
- Remove From My Forums
-
Question
-
Hi,
very old code with many-many colons….
' COMPILE: Variable not defined......>vbCrLf<.................FALSE /Compile Error !!! ' COMPILE: Variable not defined......>gkxPAC_NAME_SHRT<.......TRUE
Option Compare Database Option Explicit '-------------------------------- 'Private Const gkxPAC_NAME_SHRT = "" 'Private Const gkxPACAppMainVersion = "" 'Private Function APP_QUIT(Optional cMsg$ = "") 'On Error GoTo xPAC_CHYBA 'Dim lc__proc_meno$, lc__proc_ErrUSR$, ln__proc_err& 'lc__proc_meno$ = "APP_QUIT" 'If Len(cMsg) > 0 Then MsgBox cMsg & vbCrLf & String(50, "-") & vbCrLf & gkxPAC_NAME_SHRT & " " & gkxPACAppMainVersion, vbExclamation + vbSystemModal, gkxPAC_NAME_SHRT & ", " & lc__proc_meno 'LBL_EXIT: 'Application.Quit 'xPAC_KONIEC: 'Exit Function 'xPAC_CHYBA: 'MsgBox "Err: " & Err.Number & "," & Err.Description & vbCrLf & String(50, "-") & vbCrLf & gkxPAC_NAME_SHRT & " " & gkxPACAppMainVersion, vbCritical + vbSystemModal, gkxPAC_NAME_SHRT & ", " & lc__proc_meno & ", E" & "rr" & "or !" 'Resume LBL_EXIT 'End Function '-------------------------------- ' COMPILE: Variable not defined......>vbCrLf<.................FALSE /Compile Error !!! ' COMPILE: Variable not defined......>gkxPAC_NAME_SHRT<.......TRUE Private Function APP_QUIT(Optional cMsg$ = ""): On Error GoTo xPAC_CHYBA: Dim lc__proc_meno$, lc__proc_ErrUSR$, ln__proc_err&: lc__proc_meno$ = "APP_QUIT": If Len(cMsg) > 0 Then MsgBox cMsg & vbCrLf & String(50, "-") & vbCrLf & gkxPAC_NAME_SHRT & " " & gkxPACAppMainVersion, vbExclamation + vbSystemModal, gkxPAC_NAME_SHRT & ", " & lc__proc_meno LBL_EXIT: Application.Quit xPAC_KONIEC: Exit Function xPAC_CHYBA: MsgBox "Err: " & Err.Number & "," & Err.Description & vbCrLf & String(50, "-") & vbCrLf & gkxPAC_NAME_SHRT & " " & gkxPACAppMainVersion, vbCritical + vbSystemModal, gkxPAC_NAME_SHRT & ", " & lc__proc_meno & ", E" & "rr" & "or !": Resume LBL_EXIT End Function
dBase,FoxPro,MS Access 2003,(2010=Not rec.),Office 2010+ACC.2013 ,Symbian C++, AC.2013.SystemResource.GetCurrentFreeSize=?
Answers
-
Hi PACALA_BA,
>> the main point is NOT „Variable not defined“
Did you mean that you could make your code work, and you are wondering why the Selected undefined variable is wrong if you did not define the gkxPAC_NAME_SHRT?
I have made a test with your code, and I could reproduce your issue. If I test with the code below, the error message with the selected is correct.
Option Compare Database Option Explicit '-------------------------------- 'Private Const gkxPAC_NAME_SHRT = "" 'Private Const gkxPACAppMainVersion = "" 'Private Function APP_QUIT(Optional cMsg$ = "") 'On Error GoTo xPAC_CHYBA 'Dim lc__proc_meno$, lc__proc_ErrUSR$, ln__proc_err& 'lc__proc_meno$ = "APP_QUIT" 'If Len(cMsg) > 0 Then MsgBox cMsg & vbCrLf & String(50, "-") & vbCrLf & gkxPAC_NAME_SHRT & " " & gkxPACAppMainVersion, vbExclamation + vbSystemModal, gkxPAC_NAME_SHRT & ", " & lc__proc_meno 'LBL_EXIT: 'Application.Quit 'xPAC_KONIEC: 'Exit Function 'xPAC_CHYBA: 'MsgBox "Err: " & Err.Number & "," & Err.Description & vbCrLf & String(50, "-") & vbCrLf & gkxPAC_NAME_SHRT & " " & gkxPACAppMainVersion, vbCritical + vbSystemModal, gkxPAC_NAME_SHRT & ", " & lc__proc_meno & ", E" & "rr" & "or !" 'Resume LBL_EXIT 'End Function '-------------------------------- ' COMPILE: Variable not defined......>vbCrLf<.................FALSE /Compile Error !!! ' COMPILE: Variable not defined......>gkxPAC_NAME_SHRT<.......TRUE 'Private Function APP_QUIT(Optional cMsg$ = ""): On Error GoTo xPAC_CHYBA: Dim lc__proc_meno$, lc__proc_ErrUSR$, ln__proc_err&: lc__proc_meno$ = "APP_QUIT": If Len(cMsg) > 0 Then MsgBox cMsg & vbCrLf & String(50, "-") & vbCrLf & gkxPAC_NAME_SHRT & " " & gkxPACAppMainVersion, vbExclamation + vbSystemModal, gkxPAC_NAME_SHRT & ", " & lc__proc_meno 'LBL_EXIT: Application.Quit 'xPAC_KONIEC: Exit Function 'xPAC_CHYBA: MsgBox "Err: " & Err.Number & "," & Err.Description & vbCrLf & String(50, "-") & vbCrLf & gkxPAC_NAME_SHRT & " " & gkxPACAppMainVersion, vbCritical + vbSystemModal, gkxPAC_NAME_SHRT & ", " & lc__proc_meno & ", E" & "rr" & "or !": Resume LBL_EXIT 'End Function Private Function test() MsgBox "Hello" & vbCrLf & undefinedVariable End Function
To be honesty, I do not know why this happened, I used the Editor for developer, but I did not know the details achievement of it.
I suggest you define all the variable you will use in the code, write the correct code.
Best Regards,
Edward
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click
HERE to participate the survey.-
Marked as answer by
Tuesday, August 25, 2015 1:10 PM
-
Marked as answer by
При выполнении макросов Excel могут возникнуть ошибки, которые в VBA делят на три категории:
- Ошибки компиляции
- Ошибки выполнения
- Логические ошибки (баги)
Далее мы поговорим о каждом из трёх типов ошибок VBA подробно.
Содержание
- Ошибки компиляции
- Ошибки выполнения
- Перехват ошибок выполнения
- Логические ошибки
Ошибки компиляции
Компилятор VBA рассматривает ошибки компиляции как недопустимые и выделяет их в коде ещё до того, как дело дойдёт до запуска макроса.
Если при написании кода допущена синтаксическая ошибка, то редактор VBA сигнализирует об этом немедленно: либо при помощи окна с сообщением, либо выделяя ошибку красным цветом, в зависимости от статуса режима Auto Syntax Check.
Примечание: При включённом режиме Auto Syntax Check каждый раз, при появлении в редакторе Visual Basic во введённом коде синтаксической ошибки, будет показано соответствующее сообщение. Если же этот режим выключен, то редактор VBA продолжит сообщать о синтаксических ошибках, просто выделяя их красным цветом. Опцию Auto Syntax Check можно включить/выключить в меню Tools > Options редактора Visual Basic.
В некоторых случаях ошибка компиляции может быть обнаружена при выполнении компиляции кода, непосредственно перед тем, как макрос будет выполнен. Обычно ошибку компиляции несложно обнаружить и исправить, потому что компилятор VBA даёт информацию о характере и причине ошибки.
Например, сообщение «Compile error: Variable not defined» при попытке запустить выполнение кода VBA говорит о том, что происходит попытка использовать или обратиться к переменной, которая не была объявлена для текущей области (такая ошибка может возникнуть только если используется Option Explicit).
Ошибки выполнения
Ошибки выполнения возникают в процессе выполнения кода и приводят к остановке выполнения программы. Этот тип ошибок VBA, как правило, также не сложно обнаружить и исправить, так как сообщается информация о характере ошибки и место в коде, где произошла остановка.
Примером такой ошибки может служить попытка выполнить деление на ноль. В результате будет показано сообщение «Run-time error ’11’: Division by zero«.
В зависимости от структуры проекта VBA, может быть предложено выполнить отладку кода (как показано на рисунке ниже). В этом случае при нажатии на кнопку Debug (в окне сообщения о необходимости отладки) будет выделена цветом строка кода, которая стала причиной ошибки VBA.
Получив такое сообщение и видя выделенную строку кода, как в приведённом выше примере, обнаружить причину ошибки будет совсем не сложно.
В случае если код сложнее, чем в нашем примере, то, чтобы получить больше информации о причине возникновения ошибки VBA, можно проверить значения используемых переменных. В редакторе VBA для этого достаточно навести указатель мыши на имя переменной, или можно открыть окно отслеживания локальных переменных (в меню редактора View > Locals Window).
Коды различных ошибок выполнения расшифрованы на сайте Microsoft Support (на английском). Наиболее часто встречающиеся ошибки VBA перечислены в этой таблице:
5 | Недопустимый вызов процедуры (Invalid procedure call) |
7 | Недостаточно памяти (Out of memory) |
9 | Индекс вне заданного диапазона (Subscript out of range)
Эта ошибка возникает при попытке обратиться к элементу массива за пределами заданного размера массива – например, если объявлен массив с индексами от 1 до 10, а мы пытаемся обратиться к элементу этого же массива с индексом 11. |
11 | Деление на ноль (Division by zero) |
13 | Несоответствие типа (Type mismatch)
Эта ошибка возникает при попытке присвоить переменной значение не соответствующего типа – например, объявлена переменная i типа Integer, и происходит попытка присвоить ей значение строкового типа. |
53 | Файл не найден (File not found)
Иногда возникает при попытке открыть не существующий файл. |
Перехват ошибок выполнения
Не все ошибки выполнения бывают вызваны недочётами в коде. Например, ошибки VBA не удастся избежать, если для работы макроса необходимо открыть файл с данными, а этого файла не существует. В таких случаях признаком профессионализма будет перехват ошибок и написание кода VBA, который будет выполняться при их возникновении. Таким образом, вместо неприятных сбоев будет происходить изящное завершение работы макроса.
Для того, чтобы помочь справиться с возникающими ошибками, VBA предоставляет разработчику операторы On Error и Resume. Эти операторы отслеживают ошибки и направляют выполнение макроса в специальный раздел кода VBA, в котором происходит обработка ошибки. После выполнения кода обработки ошибки, работа программы может быть продолжена с того места, где возникла ошибка, или макрос может быть остановлен полностью. Далее это показано на примере.
'Процедура Sub присваивает переменным Val1 и Val2 значения, 'хранящиеся в ячейках A1 и B1 рабочей книги Data.xlsx расположенной в каталоге C:Documents and Settings Sub Set_Values(Val1 As Double, Val2 As Double) Dim DataWorkbook As Workbook On Error GoTo ErrorHandling 'Открываем рабочую книгу с данными Set DataWorkbook = Workbooks.Open("C:Documents and SettingsData") 'Присваиваем переменным Val1 и Val2 данные из рабочей книги DataWorkbook Val1 = Sheets("Лист1").Cells(1, 1) Val2 = Sheets("Лист1").Cells(1, 2) DataWorkbook.Close Exit Sub ErrorHandling: 'Если файл не найден, предлагаем пользователю разместить его в 'нужном месте и продолжить работу MsgBox "Рабочая книга не найдена! " & _ "Пожалуйста добавьте книгу Data.xlsx в каталог C:Documents and Settings и нажмите OK." Resume End Sub
В этом коде производится попытка открыть файл Excel с именем Data. Если файл не найден, то пользователю будет предложено поместить этот файл в нужную папку. После того, как пользователь сделает это и нажмёт ОК, выполнение кода продолжится, и попытка открыть этот файл повторится. При желании вместо попытки открыть нужный файл, выполнение процедуры Sub может быть прервано в этом месте при помощи команды Exit Sub.
Логические ошибки
Логические ошибки (или баги) возникают в процессе выполнения кода VBA, но позволяют ему выполняться до самого завершения. Правда в результате могут выполняться не те действия, которые ожидалось, и может быть получен неверный результат. Такие ошибки обнаружить и исправить труднее всего, так как компилятор VBA их не распознаёт и не может указать на них так, как это происходит с ошибками компиляции и выполнения.
Например, при создании макроса в процедуре случайно были просуммированы не те переменные, которые требовалось просуммировать. Результат будет ошибочным, но макрос будет продолжать выполняться до завершения.
Редактор Excel VBA предоставляет набор инструментов отладки, которые помогут найти и исправить логические ошибки в коде VBA. В данной статье мы не будем рассматривать подробно эти инструменты. Любознательный пользователь может найти обзор инструментов отладки VBA на сайте Microsoft Help & Support (на английском).
Оцените качество статьи. Нам важно ваше мнение:
0 / 0 / 1 Регистрация: 23.10.2012 Сообщений: 135 |
|
1 |
|
04.01.2013, 00:34. Показов 17035. Ответов 3
всем привет, у меня выскочила ошибка и я не знаю что делать, подскажите как исправить Миниатюры
__________________ 0 |
Dragokas 17955 / 7592 / 889 Регистрация: 25.12.2011 Сообщений: 11,323 Записей в блоге: 17 |
||||
04.01.2013, 00:47 |
2 |
|||
Уберите в самом верху кода обязательную декларацию переменных:
или задавайте типизацию с помощью команды Dim 0 |
Казанский 15131 / 6405 / 1730 Регистрация: 24.09.2011 Сообщений: 9,999 |
||||
04.01.2013, 01:18 |
3 |
|||
Сообщение было отмечено как решение РешениеПри чем тут типизация? Просто переменная не объявлена. Обявите ее сразу после заголовка процедуры
, а в процедуре можете называть ее просто i без указания типа. 6 |
Заблокирован |
|
04.01.2013, 16:55 |
4 |
Казанский, И в правду тебе нет цены ! 0 |
-
#2
Welcome to the Forum!
Does you new workbook have sheets with codenames Sheet7 and Sheet9?
-
#3
MAybe this
Rich (BB code):
Option Explicit
Dim rx, cx, cxDeliverable, cxLoc, rxCode, rz, czDeliverable, czLoc, czCode, czSubtotal As Integer
Dim shx, shz As Worksheet
Sub Matrix2DB()
Set shx = Sheets("Sheet7")
Set shz = Sheets("Sheet9")
cxDeliverable = 1
cxLoc = 2
rxCode = 7
rz = 1
czDeliverable = 1
czLoc = 2
czCode = 3
czSubtotal = 4
For rx = 9 To 613
For cx = 3 To 54
If shx.Cells(rx, cx) > 0 Then
shz.Cells(rz, czDeliverable) = shx.Cells(rx, cxDeliverable)
shz.Cells(rz, czLoc) = shx.Cells(rx, cxLoc)
shz.Cells(rz, czCode) = shx.Cells(rxCode, cx)
shz.Cells(rz, czSubtotal) = shx.Cells(rx, cx)
rz = rz + 1
End If
Next cx
Next rx
End Sub
-
#4
sweet jesus it looks like that worked. thankyou stephencrump and Michael m.
I renamed the relevant sheets to «sheet 7» and «sheet 9» as suggested, saved, re-opened and re-ran the macro and she seems to be up and running.
May I ask if anyone knows why it initially suggested my «sub» needed to be declared as a variable ???
-
#5
Because you have Option Explicit (good coding practice!) execution won’t proceed with an undefined variable.
So execution stops at the first line Sub Matrix2DB() which will show yellow.
However, the first offending undefined variable should also be highlighted?
-
#6
@jalberthenet, you might also want to review how you declare your variables.
As you have it currently written
rx, cx, cxDeliverable, cxLoc, rxCode, rz, czDeliverable, czLoc, czCode and shx are all declared as Variant in VBA, which I don’t think is what you intended.
In VBA if you omit the As Type clause in a variable declaration then it is declared as Variant, Variant is the default type.
-
#7
Ah MARK858 has beaten me to the punch, but just to add,
The way you’re declaring your variables only the last one is being declared as the type you define as an integer or worksheet. To see this run this simple code which shows the variable type (
click here for a list of variable types and their associated number) from this:
Code:
MsgBox VarType(rx)
MsgBox TypeName(czSubtotal)
rx is actually a variant variable — the most expensive type of variable. You need «As Integer» after each of the other nine variables in that row (assuming you want them all to be integers).
Regards,
Robert