Основы офисного программирования и язык VBA

       

Создание класса "Личность"


В предыдущей лекции о типах данных мы ввели пользовательский тип Person. Там же мы показали, что прямой доступ к полям записи позволяет программисту свободно работать с данными этого типа. И все же Person в чем-то "ущербен"... А не хватает ему собственных операций: если бы наши переменные Петров и Козлов имели тип, например, Integer, можно было бы их сравнивать, складывать и умножать, присваивать значения и многое другое. Понятно, что умножение данных типа Person вряд ли разумно, но зато для него можно определить свои операции. Вот, например, какие операции можно определить для этого типа:

  • InitPerson- инициализация полей записи;
  • PrintPerson- печать полей записи;
  • CopyPerson(Source As Person) - копирование источника (записи Source) - аналог оператора присвоения;
  • WhoIs - более специфическая операция, с определенной достоверностью определяющая пол, анализируя имя и фамилию.

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

Синтаксически классы в VBA оформляются в виде модуля класса . Поэтому начинать создание класса в Редакторе Visual Basic нужно с выбора в меню Insert пункта Class Module. Этот модуль имеет такую же структуру, как и стандартный модуль, о котором мы подробно уже рассказали. Модуль состоит из двух разделов - объявлений и методов. В первом из них естественным образом описываются свойства класса, а во втором - его методы. И здесь действуют спецификаторы области действия Public и Private. Public - свойства и Public -методы составляют интерфейс класса. Только к этим свойствам и методам можно обращаться при работе с объектами класса, объявленными в других модулях, где класс является видимым.

Мы расширили ранее созданный тип Person до класса, названного нами Личность, путем добавления операций над данными класса.
Часть из этих операций уже упомянута, другие ясны из контекста. Нам кажется разумным привести с самого начала полное описание класса, а потом уже, когда полная картина ясна, переходить к деталям. Создав модуль класса "Личность, мы поместили туда следующий текст:

Пример 4.1.

(html, txt)

Прокомментируем этот довольно длинный текст.

  • Первое, что мы сделали, - перешли на русский язык при задании имен свойств и методов.
  • С точностью до имен все свойства класса Личность совпадают с полями типа Person. Кстати, мы сделали все свойства закрытыми (Private), и теперь вне класса нет прямого доступа к его полям (свойствам).
  • В класс Личность добавлено 5 общих методов: InitPerson, PrintPerson, CopyPerson, WhoIs, SayWhoIs и по паре методов Get и Let на каждое закрытое свойство. В классе есть и закрытая для внешнего использования функция "ПоследняяБуква", и обработчик события Initialize.
  • Метод Init в том или ином виде должен быть определен в каждом классе. Это первый вызываемый метод объекта. Прежде чем начать работу с объектом, его нужно инициализировать. В нашем классе эту работу и делает метод InitPerson.
  • Метод Print также присутствует почти в каждом классе - нужно же распечатать информацию об объекте! - в PrintPerson вызывается метод WhoIs.
  • CopyPerson - еще один общий, часто необходимый метод, позволяющий реализовать настоящее присвоение, когда копируется не ссылка, а значения полей класса, что позволяет иметь не две ссылки на один объект, а два идентичных объекта.
  • Булева функция WhoIs - метод, специфический для нашей задачи. Это попытка определить пол по имени и фамилии. Применяется примитивный, но обеспечивающий высокую достоверность для русских имен и фамилий алгоритм. По ходу дела потребовалось ввести вспомогательную функцию "ПоследняяБуква".
  • Метод SayWhoIs вызывает WhoIs, дополнительно определяет возраст (только для мужчин) и выводит соответствующее сообщение в окно Message.
  • Закрытая для внешнего использования функция ПоследняяБуква возвращает в верхнем регистре последнюю букву слова.


    Эта задача решается двумя вызовами функций работы со строками Right и UСase. Первая возвращает "хвост" слова, вторая - преобразует результат в верхний регистр.
  • Подробнее скажем о закрытых свойствах и специальных методах Get и Let. Вообще говоря, свойства можно не закрывать, а специальные методы не вводить. Но VBA позволяет следовать традициям объектно-ориентированного программирования, согласно которым считается правильным не давать возможности непосредственного изменения свойств, поскольку иногда это может привести к некорректному состоянию объекта. Поэтому доступ к свойствам закрывается, для чего достаточно объявить их с атрибутом Private, но зато вводятся специальные методы Get (для получения значения свойства) и Let (для изменения значения на новое). Заготовки для этой пары свойств строятся автоматически, если Вы при вставке метода указали (пометив флажок Property), что он должен быть свойством.
  • С каждым из объектов созданного Вами класса связываются два события: Initialize и Terminate. Первое возникает при первоначальном обращении к объекту, второе - по окончании работы с ними. В нашем примере в методе Initialize даем объекту инициализацию, восходящую к "Адаму".


Завершим изложение примером работы с объектами класса, его методами и свойствами:

Public Sub Знакомство() Dim UserOne As New Личность Dim UserTwo As New Личность Dim UserThree As New Личность Debug.Print UserOne.ВашеИмя UserOne.InitPerson FN:="Петр", LN:="Петров", DoB:=#1/23/1968# UserTwo.InitPerson FN:="Анна", LN:="Козлова", DoB:=#7/21/1968# UserOne.PrintPerson UserTwo.PrintPerson UserOne.SayWhoIs UserTwo.SayWhoIs UserTwo.ВашаФамилия = UserOne.ВашаФамилия & "а" Debug.Print UserOne.ВашаФамилия Debug.Print UserTwo.ВашаФамилия UserThree.InitPerson FN:="Анна", LN:="Керн", DoB:=#5/17/1803# UserThree.PrintPerson UserThree.SayWhoIs End Sub

Вот какие результаты отладочной печати будут выданы в окно Immediate (отладки):

Адам Петр Петров родился 23.01.68 Анна Козлова родилась 21.07.68 Петров Петрова Анна Петровна Керн родилась 17.05.1803

А такие окна сообщений появятся на экране, при уточнении данных о личности Анны Керн:


Рис. 4.1.  Отчество Анны Керн


Рис. 4.2.  Кто Анна?



Это попытка определить пол по имени и фамилии. Применяется примитивный, но обеспечивающий высокую достоверность для русских имен и фамилий алгоритм. По ходу дела потребовалось ввести вспомогательную функцию "ПоследняяБуква".
  • Метод SayWhoIs вызывает WhoIs, дополнительно определяет возраст (только для мужчин) и выводит соответствующее сообщение в окно Message.
  • Закрытая для внешнего использования функция ПоследняяБуква возвращает в верхнем регистре последнюю букву слова. Эта задача решается двумя вызовами функций работы со строками Right и UСase. Первая возвращает "хвост" слова, вторая - преобразует результат в верхний регистр.
  • Подробнее скажем о закрытых свойствах и специальных методах Get и Let. Вообще говоря, свойства можно не закрывать, а специальные методы не вводить. Но VBA позволяет следовать традициям объектно-ориентированного программирования, согласно которым считается правильным не давать возможности непосредственного изменения свойств, поскольку иногда это может привести к некорректному состоянию объекта. Поэтому доступ к свойствам закрывается, для чего достаточно объявить их с атрибутом Private, но зато вводятся специальные методы Get (для получения значения свойства) и Let (для изменения значения на новое). Заготовки для этой пары свойств строятся автоматически, если Вы при вставке метода указали (пометив флажок Property), что он должен быть свойством.
  • С каждым из объектов созданного Вами класса связываются два события: Initialize и Terminate. Первое возникает при первоначальном обращении к объекту, второе - по окончании работы с ними. В нашем примере в методе Initialize даем объекту инициализацию, восходящую к "Адаму".


  • Завершим изложение примером работы с объектами класса, его методами и свойствами:

    Public Sub Знакомство() Dim UserOne As New Личность Dim UserTwo As New Личность Dim UserThree As New Личность Debug.Print UserOne.ВашеИмя UserOne.InitPerson FN:="Петр", LN:="Петров", DoB:=#1/23/1968# UserTwo.InitPerson FN:="Анна", LN:="Козлова", DoB:=#7/21/1968# UserOne.PrintPerson UserTwo.PrintPerson UserOne.SayWhoIs UserTwo.SayWhoIs UserTwo.ВашаФамилия = UserOne.ВашаФамилия & "а" Debug.Print UserOne.ВашаФамилия Debug.Print UserTwo.ВашаФамилия UserThree.InitPerson FN:="Анна", LN:="Керн", DoB:=#5/17/1803# UserThree.PrintPerson UserThree.SayWhoIs End Sub

    Вот какие результаты отладочной печати будут выданы в окно Immediate (отладки):

    Адам Петр Петров родился 23.01.68 Анна Козлова родилась 21.07.68 Петров Петрова Анна Петровна Керн родилась 17.05.1803

    А такие окна сообщений появятся на экране, при уточнении данных о личности Анны Керн:


    Рис. 4.1.  Отчество Анны Керн


    Рис. 4.2.  Кто Анна?


    Содержание раздела