Тверской государственный университет
Опубликован: 13.09.2006 | Доступ: свободный | Студентов: 3491 / 369 | Оценка: 4.65 / 4.29 | Длительность: 30:37:00
Специальности: Программист, Менеджер
Лекция 5:

Классы и объекты

< Лекция 4 || Лекция 5: 123456 || Лекция 6 >

Объекты и переменные

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

Dim X As T, Y As T1

то без контекста понять нельзя, что есть X и Y - "обычные" переменные или объекты. Например, если T - тип, заданный пользователем, а T1 - определенный им класс, то X - это переменная, а Y - объект. С нашей точки зрения, класс и тип - понятия, если не эквивалентные, то близкие по смыслу. Также близки понятия объекта и переменной. Класс - это специальная форма определения типа. Если есть тип T и класс T1, то можно объявить произвольное число экземпляров типа T и класса T1. Экземпляры типа T называются переменными, класса T1 - объектами. Класс задает свойства, методы и события своих объектов. Тип всегда задает свойства, неявно - методы, но никогда - события.

В объявлении: Dim Y As T1, где T1 - класс, объект Y мы часто называем переменной, говоря, что она имеет тип Object. Переменные типа Object рассматриваются как ссылки, задающие адрес памяти, где хранится объект. У них фиксированная длина 4 байта. При объявлении такой переменной память для самого объекта может и не отводиться в отличие от обычных переменных, поэтому не определено и значение ссылки. Задать ссылку - связать переменную с объектом - можно двумя путями:

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

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

Dim V As Object

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

Dim Петров As Личность, Козлов As Личность

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

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

  • объекты, чей класс определен пользователем в одном из модулей класса; например, объекты класса Личность, созданного в этой лекции;
  • объекты родового приложения (Excel, Word, PowerPoint), которому принадлежит проект и которые доступны по умолчанию;
  • ActiveX и Com AddIns -объекты, в частности, объекты других приложений Office 97 при их подключении к исходному приложению. Например, в Word можно подключить объекты Excel, а документы Word включить в рабочие листы Excel.

Объекты, класс которых определен пользователем.

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

{Dim | Private | Public | Static }<имя переменной> As New <имя типа>

Спецификатор New указывает, что в момент объявления нужно создать новый объект, то есть выделить ему память. В этот же момент ссылка на объект получает конкретное значение. Выделение памяти еще не означает инициализации значений свойств объекта. Инициализацию можно задать при определении события Initialize или в специально построенном методе Init, который следует запускать в начале работы с объектом. Вот пример создания объекта с последующей его инициализацией:

Public Sub MyCreateObject()
    'Нельзя создавать объекты собственного класса, используя CreateObject
    Dim Nemo As Личность
    'Set Nemo = CreateObject("Личность")
    'Можно их создавать, используя New
    Set Nemo = New Личность
    Nemo.InitPerson FN:="Prince", LN:="Dakar", DoB:=#1/23/1838#
    Nemo.PrintPerson
End Sub

Только метод New позволяет создать новый объект для классов, определенных программистом. Для этой цели нельзя, например, использовать метод CreateObject. Но, заметьте, спецификатор New не является обязательным, его можно опускать при объявлении таких переменных класса, которые в дальнейшем получат значение, благодаря ссылке на другие, ранее созданные объекты. Задать ссылку на существующий объект нельзя обычным оператором присвоения - для этого в VBA есть специальный оператор Set:

Set  <имя переменной - объекта> = {<объектное выражение>| Nothing }

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

Dim Q As Личность
Set Q = Nemo
Q.PrintPerson

В результате будет отпечатан следующий текст:

Prince Dakar родился 23.01.1838

Объекты "родного" приложения

Каждый VBA-проект погружен в "родное" приложение Office 97, объекты которого доступны в проекте. Для создания таких объектов не используется ни спецификатор New, ни метод CreateObject. Новые объекты, если и создаются, то специальными методами своего класса. Например, метод Add позволяет добавлять элементы в коллекции. При работе с объектами этой группы объявляются переменные соответствующего класса, затем они связываются с уже существующими объектами. Связывание выполняет оператор Set. Все примеры из первой лекции книги посвящены работе с объектами этой группы. Напомним тот, где участвует один из наиболее употребительных объектов - Range:

Public Sub FirstComment()
Dim myRange As Range
'Добавление комментария
With ActiveDocument
    Set myRange =.Paragraphs(1).Range
   .Comments.Add myRange, "Эта лекция рассказывает о классах объектов"
    'Передвигается объект Range
    myRange.Move Unit:=wdParagraph, Count:=2
End With

End Sub

Здесь вначале объявляется объект myRange класса Range, что обеспечивает раннее связывание. Объектное выражение в правой части оператора Set возвращает ссылку на существующий объект (первый параграф активного документа), и эта ссылка становится значением myRange. А затем с этим объектом можно работать, используя свойства и методы соответствующего класса, в данном случае - Range. Его можно использовать, например, в методе Add при работе с коллекцией комментариев или вызвать метод Move для изменения области, отведенной объекту.

ActiveX-объекты

Технология ActiveX обеспечивает взаимодействие приложений - Автоматизацию (Automation), при которой одно приложение управляет работой другого. На этой технологии построено взаимодействие приложений Office 97. И хотя у нас уже были примеры на эту тему, позволим привести еще один.

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

Dim  <имя переменной>  As New  <имя приложения.имя класса>

По сравнению с обычной конструкцией оператора объявления здесь более сложно задается тип (класс) создаваемого объекта. Первая часть - имя_приложения - указывает приложение, создающее объект, и в то же время это имя библиотеки типов данного приложения - TypeLib. Приложение является сервером, который вызывается для обеспечения работы с объектом. Вторая часть - имя_класса - задает тот конкретный класс, определенный в сервере, экземпляр ActiveX -объекта которого будет создан. Библиотека типов подключаемого приложения должна быть видимой, для чего надо включить ссылку на нее в меню References. Повторим с небольшими вариациями наш старый пример, в котором Excel подключается в приложении Word:

Public Sub WorkWithActiveX()
    'Создание объекта Excel.Application при работе с документом Word
    Dim xlApp As Excel.Application
    'Set xlApp = CreateObject("Excel.Application.9")
    Set xlApp = New Excel.Application
    xlApp.Application.Visible = True
    'Добавить новую книгу
    xlApp.Workbooks.Add
    'Теперь можно работать и с ячейками данной книги
    xlApp.Workbooks(1).Activate
    xlApp.Range("A1:A2") = 2
    xlApp.Range("B1") = "=A1+A2"
    xlApp.Range("B2") = "=A1*A2"
    'Закрываем открытую книгу без сохранения изменений
    xlApp.Workbooks(1).Close SaveChanges:=False
    'Закрываем приложение
    xlApp.Quit
End Sub

Создание Excel приложения в данном случае возможно двумя способами - применением конструкции New или функции CreateObject. Однако, использование New для создания ActiveX -объектов не всегда возможно. Не все приложения допускают такой способ подключения, и не все объекты доступны, - например, недоступны внутренние ActiveX -объекты, которые совместно могут храниться в одном и том же файле. Более универсальный способ создания ActiveX -объектов - вызов специальных функций CreateObject и GetObject. Как правило, вызов этих функций помещается в правую часть оператора Set. В результате его выполнения объектное выражение возвращает ссылку на созданный объект, которая и становится значением переменной.

Синтаксис функции CreateObject таков:

CreateObject(<класс>)

Параметр класс - строка, задающая класс объекта, у которой две обязательные части: "имя_приложения.имя_класса"; ее вид совпадает с видом задания класса ActiveX -объектов в операторе объявления.

Функция GetObject имеет дополнительный параметр:

GetObject(<путь>, <класс>)

Параметр путь задает полный путь к файлу, содержащему ActiveX -объект. Этот объект и активизируется. Второй параметр при этом необязателен. Но если файл содержит группу ActiveX -объектов разных классов, задать его необходимо. Можно опустить и первый параметр, если ActiveX -объект этого класса уже создан, и тогда возвращается ссылка на активный объект заданного класса. Вот пример, в котором читается книга Excel, используя метод GetObject. Обратите внимание, книга создается без предварительного создания объекта Application:

Public Sub WorkWithGetObject()
    Const MY_PATH As String = "e:\O2000\CD2000\Ch4\"
    Dim myBook As Excel.Workbook
    Set myBook = GetObject(MY_PATH & "BookOne.xls")
    With myBook
       .Application.Visible = True
        'Чтобы увидеть книгу, включите ее в окне UnHide из меню Window
       .Charts("Динамика Продаж").Activate
        'Посмотрев на диаграмму, переключимся на рабочий лист
        MsgBox ("Вы можете перейти в Excel")
       .Worksheets(1).Activate
       .Worksheets(1).Range("A40") = 777
       .Save
       .Application.Quit
    End With
End Sub
< Лекция 4 || Лекция 5: 123456 || Лекция 6 >
полина есенкова
полина есенкова
Дмитрий Вологжин
Дмитрий Вологжин
Добрый день, прошел тесты с 1 по 9, 10 не сдал, стал читать лекцию и всё пройденные тесты с 1 по 9 сбросились, когда захотел пересдать 10 тест.