Записи и тип, определенный программистом
Наряду с массивами, представляющими объединение элементов одного типа, существует еще один способ создания сложного типа - запись (в языке Паскаль), или структура (в языке С). Запись представляет объединение элементов, каждый из которых может иметь свой тип. Элементы записи часто называют ее полями. С объектных позиций запись - частный случай класса, в котором заданы только свойства и не определяются методы и события. Это важный частный случай, и поэтому в "хорошем" языке должна быть возможность определения записей. Чтобы с записями было удобно работать, в языке надо предусмотреть средства для определения пользовательского типа. Тогда можно отделить процесс определения структуры записи - назвать это определением пользовательского типа, скажем Т, а затем в нужном месте и в нужном количестве объявлять переменные типа Т, представляющие собой конкретные записи.
Определение каждой записи можно рассматривать, как определение дерева, с корнем которого связана сама запись, а с вершинами - потомками связаны поля этой записи. Поскольку каждое поле может быть элементом произвольного типа, в том числе записью, такие вершины имеют потомков. Благодаря вложенности запись может задавать структуру сколь угодно сложно построенного дерева, у каждой вершины которого может быть произвольное число потомков. Это статическая структура, полностью определяемая в момент объявления записи.
Что же мы имеем в VBA? Формально здесь нет понятия запись или структура, или какого-либо эквивалента. Здесь есть только тип, определенный программистом. Но поскольку он позволяет определять запись, ничего больше и не нужно. Так что записи в VBA есть, но называются они типом, определенным программистом.
При определении типа программист дает ему имя, что позволяет затем определять переменные этого типа обычным способом. Поскольку все элементы совокупности именованы, возможен прямой доступ по имени к каждому из элементов. Ниже мы будем называть переменные такого типа записями, а элементы записи - полями.
Такая терминология общепринята и соответствует программистской традиции.
Синтаксис определения типа в VBA достаточно прозрачен:
[Private | Public] Type <имя типа> <имя элемента> [([<размерность массива>])] As <тип элемента> [<имя элемента> [([<размерность массива>])] As <тип элемента>] ... End Type
Определение типа дается на уровне модуля и, если оно является закрытым (Private), распространяется на один модуль, а для общих (Public) типов - на все. Мы ограничимся довольно стандартным примером, в котором определяются два типа (записи): Fam и Person, где одно из полей Person имеет тип Fam.
'Определение записей - пользовательских типов Type Fam firstName As String lastName As String End Type
Type Person Fio As Fam Birthdate As Date End Type
Эти объявления мы поместили в раздел объявлений модуля Father. Вот одна из его процедур, использующих эти типы данных:
Public Sub UserType() Dim Петров As Person Dim Козлов As Person Петров.Fio.firstName = "Петр" Петров.Fio.lastName = "Петров" Петров.Birthdate = #1/23/1961# Козлов.Fio.firstName = Петров.Fio.firstName Козлов.Fio.lastName = "Козлов" Козлов.Birthdate = #7/21/1966# MsgBox (Петров.Fio.firstName & " " & Петров.Fio.lastName _ & " родился " & Петров.Birthdate) MsgBox (Козлов.Fio.firstName & " " & Козлов.Fio.lastName _ & " родился " & Козлов.Birthdate) End Sub
Вот что будет напечатано в результате ее работы:
Петр Петров родился 23.01.61 Петр Козлов родился 21.07.66
VBA старается помочь при работе с записями, предоставляя возможность выбора полей записи из открывающегося списка. Пусть Вас не смущает форма записи дат рождения - при определении константы для дат можно задавать в более человечной форме. Например, здесь мы задавали их как #January 23, 1961# и #21 July, 66#, - они автоматически были преобразованы в формальный вид.