Использование объектов в программе
Выше уже говорилось, что, используя встроенные объекты, с помощью VBA мы можем управлять приложением. Прежде чем перейти к изучению встроенных объектов, надо понять, что же такое объект и как с ним работать. В объектно-ориентированном программировании объект обычно определяется через понятие класс. Класс – это сложный тип, объединяющий данные и код (программы) для их обработки, а объект – это переменная этого типа (экземпляр класса). Примерами объектов могут служить кнопка (объект класса CommandButton), рабочая книга (объект класса Workbook), форма (объект класса UserForm). В литературе обычно опускают слово класс и называют рабочую книгу объектом Workbook, а кнопку – объектом CommandButton.
Каждый объект имеет имя, с помощью которого иа него можно сослаться в тексте программы. У элементов управления и формы это значение свойства (Name). В отличие от других свойств, это свойство нельзя изменить во время выполнения программ.
Состояние объекта характеризуется текущим значением его атрибутов. Атрибутами могут быть не только простейшие величины, по и другие объекты. Атрибуты объекта называются свойствами. Свойства элементов управления и формы можно задать в Окне свойств. Для доступа к значению свойства в программе нужно указать имя объекта и, через точку, имя свойства. Если значение свойства в свою очередь является объектом, то нужно снова поставить точку и указать свойство этого свойства и т.д. Например:
Selection. Font.Bold = True
Объекты выполняют обработку данных с помощью методов. Метод – это процедура, связанная с объектом. Метод вызывается аналогично свойству. Если нужно, при вызове указываются значения фактических параметров:
Forml.Hide
Forml.Move 20, 20, 200, 100
Событие – это действие, распознаваемое объектом (например, щелчок мышью, нажатие клавиши или переход в другое окно). Возникают события в результате действий пользователя или программы, могут быть инициированы операционной системой. У каждого объекта свой набор событий, созданный разработчиком. Если вы хотите, чтобы при наступлении события ваша программа что-то сделала, напишите процедуру обработки события. Имя процедуры всегда состоит из имени объекта и имени события, между которыми ставится знак подчеркивания. Например, процедура cmdOK Click будет выполняться, когда пользователь нажмет на кнопку с именем cmdOK, так как в этот момент для нее возникнет событие Click. Для форм процедуры обработки событий имеют имена Form_событие, т.е. указывается не имя формы, а слово Form, например FormClick. Процедура обработки события размещается в том модуле, в котором используется объект.
Для создания процедуры обработки события перейдите в окно кода нужной формы, например с помощью кнопки View Code окна проекта. В верхней части окна имеются два списка. В левом списке выберите нужный объект, в правом – событие для этого объекта. Система автоматически создаст заготовку процедуры с именем процедуры в начале и инструкцией End Sub в конце. Допишите в нее нужные инструкции. Если процедура уже существует, она будет показана в окне. Не пишите заготовки процедур обработки событий вручную, так как некоторые события имеют параметры и вы можете ошибиться. Также имейте в виду, что двойной щелчок по форме или элементу управления приводит к переходу в окно кода формы и созданию процедуры обработки самого типичного события этого объекта (события по умолчанию).
Как мы уже выяснили, объект – это переменная специального типа. Работа с такими переменными в программе похожа на работу с переменными других типов: мы можем их объявлять, присваивать им значения, сравнивать, – но в то же время имеет свою специфику. На самом деле объектная переменная хранит ссылку на область памяти, в которой размещена вся информация, относящаяся к объекту. Поэтому любая объектная переменная всегда занимает 4 байта. Это определяется моделью памяти, а не классом. Используя объектную переменную, мы получаем доступ к свойствам, методам и событиям объекта.
Для описания объектной переменной используются обычные инструкции Dim, Public, Private или Static. В качестве типа можно указать Variant, Object или имя класса. Тип Object позволяет создать универсальную ссылку на любой объект. Он используется в том случае, если объектный тип не известен до выполнения процедуры. Например:
Dim 01 'Описывает 01 с типом Variant
Dim 02 As Object 'Описывает 02 с типом Object
Dim 03 As Font 'Описывает 03 с типом Font
Важно понимать, что описание объектной переменной не означает создание объекта. Чтобы переменная ссылалась на объект, объект нужно создать и присвоить эту ссылку в качестве значения переменной.
Присвоение значения объектной переменной выполняется с помощью инструкции Set:
Set Переменная = Выражение | New ИмяКласса | Nothing
Слева от знака "равно" может стоять в том числе имя свойства, если свойство является объектом. Выражение, стоящее справа, может быть именем другой переменной того же типа, функцией, методом или свойством, которые возвращают объект того же типа. Ключевое слово New используется для создания нового экземпляра объекта указанного класса. Присваивание Nothing (пустая ссылка) разрывает связь переменной с объектом. Когда переменная получает значение Nothing, все системные ресурсы и ресурсы памяти, выделенные для объекта, на который имелась ссылка, освобождаются, если никакие другие переменные на него не ссылаются.
При использовании инструкции Set копия объекта обычно не создается. Значением переменной является ссылка на объект. Следовательно, несколько объектных переменных могут ссылаться на один и тот же объект и любые изменения объекта отражаются на всех переменных, которые ссылаются на него.
В качестве примера рассмотрим создание нового рабочего листа (объекта Worksheet). В первом случае лист создается с помощью метода Add, который возвращает ссылку на новый лист, и эту ссылку мы присваиваем переменной newSheetl. Во втором случае лист создается с помощью New. Использовать переменные newSheetl и newSheet2 мы можем одинаково:
Set newSheetl = Worksheets.Add
newSheetl.Name = "Отчет"
Set newSheet2 = New Worksheet
newSheet2.Name = "Вычисления"
Для сравнения двух переменных, содержащих ссылки на объекты, нельзя использовать обычную операцию "равно". Для этих целей предназначена специальная операция Is. Если переменные содержат ссылки на один объект, результат имеет значение True, в противном случае результат имеет значение False.
В приведенном ниже примере выполняется поиск слова "Образец" в столбце В листа "Лист1". В случае обнаружения нужного слова метод Find вернет ссылку на найденную ячейку, в противном случае – пустую ссылку. Результат поиска сохраняется в переменной FC. Так мы можем проверить, чем закончился поиск:
Set FC = Worksheets("JlMCTl ").Columns("B").Rnd(O6pa3eH")
If FC Is Nothing Then
MsgBox "Слово не найдено"
Else
MsgBox "Слово находится в ячейке" & FC.Address
End If
Иногда во время выполнения программы требуется узнать класс объекта, на который ссылается переменная. В этом случае следует использовать операцию TypeOf. Так, например, мы можем проверить тип активного элемента управления в форме (TextBox, PictureBox – это имена классов, свойство ActiveControl хранит ссылку на активный объект):
If TypeOf UserForml.ActiveControl Is TextBox Then
'Активный элемент – TextBox
Elself TypeOf UserForml .ActiveControl Is PictureBox Then
'Активный элемент – PictureBox
Else
MsgBox "Другой тип данных"
End If
Инструкция With дает возможность выполнить последовательность действий над объектом, нс повторяя его имени. Обращение к свойствам и методам объекта внутри инструкции начинается с точки. Инструкция не только облегчает чтение и написание программы за счет уменьшения объема текста, по и позволяет транслятору создать более эффективный код, так как ссылка па объект вычисляется один раз. Синтаксис инструкции:
With Объект
[Инструкции]
EndWith
Пример использования инструкции:
With Worksheets("Листl").Range("A1:C10")
.Font.Bold = True .Interior.Color = RGB(255, 255, 0)
End With
В примере форматируются ячейки А1:С10 листа "Лист1" (шрифт – полужирный, цвет фона – желтый). Таким образом, ссылка на необходимый диапазон указывается один раз, хотя изменяются значения двух свойств объекта.
Отдельные объекты можно объединять в коллекции, подобно тому как из отдельных элементов можно создать массив. Коллекция – это специальный объект-контейнер, содержащий другие объекты. Создание коллекций, так же как и создание классов, выходит за рамки этого курса, поэтому нам нужно только научиться работать с существующими коллекциями. В приложениях Microsoft используется очень много коллекций, так как они позволяют легко обработать все объекты заданного класса.
Добавление, удаление и другие операции с элементами коллекции реализуются с помощью методов соответствующих классов. Доступ к конкретному элементу коллекции возможен по номеру или по ключу. Нумерация элементов начинается с единицы. При использовании номера нужно указать имя коллекции и в круглых скобках – номер элемента, например Worksheets(1). Доступ по ключу возможен в том случае, если при добавлении элемента в коллекцию ключ был задан. Ключ – это строка. В коллекции рабочих листов ключом является имя листа, поэтому мы можем обратиться к нужному листу, например, так: Worksheets("Peшение"). В данном случае совершенно не важно, какой помер у этого листа, тем более что номер во время выполнения программы может измениться из-за добавления или удаления листов. Количество элементов в коллекции всегда можно узнать с помощью свойства Count. Это свойство доступно только для чтения.
Перебор всех элементов коллекции удобно выполнять с помощью специальной разновидности цикла For Each ... Next, которая имеет следующий синтаксис:
For Each Переменная In ИмяКоллекции
[Инструкции]
[Exit For]
[Инструкции]
Next [Переменная]
Переменная цикла может иметь тип Variant, Object или тип конкретного объекта. Для досрочного выхода из цикла используется инструкция Exit For. Цикл выполняется для каждого элемента коллекции. Имя переменной после Next
рекомендуется указывать в тех случаях, когда используются вложенные циклы.
В качестве примера рассмотрим, как подсчитать количество пустых ячеек в выделенном диапазоне. В данном случае объект Selection – это коллекция, состоящая из объектов типа Range:
N = О
Dim с as Range
For Each c In Selection
If c.Value = "" Then N = N + 1
Next c