Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОСНОВЫ ОФИСНОГО ПРОГРАММИРОВАНИЯ И ЯЗЫК VBA - 1....doc
Скачиваний:
59
Добавлен:
17.12.2018
Размер:
1.88 Mб
Скачать

Динамические массивы

Динамические массивы VBA это мощное средство, отсутствующее в таких известных языках как, например, С++ и Паскаль. Массив считается динамическим , если при первоначальном объявлении не указывается его размерность, но она может быть определена и переопределена в последующем оператором ReDim. Размерность определяется динамически в той процедуре и в тот момент, когда она становится фактически известной. Обратите внимание, в этом операторе границы изменения индексов можно задать не только как константы, но и как выражения, зависимые от переменных.

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

Рассмотрим пример. На уровне модуля объявим глобальный динамический массив Vector:

'Объявление динамического массива

Public Vector() As Integer

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

Public Sub DynArray()

'Определяется фактическая размерность массива Vector

Dim N As Byte, I As Byte

N = InputBox("Введите число элементов вектора")

ReDim Vector(1 To N)

For I = 1 To N

Vector(I) = 2 * I + 1

Next I

' Массив расширяется с сохранением ранее вычисленных элементов

ReDim Preserve Vector(1 To 2 * N + 1)

For I = N + 1 To 2 * N + 1

Vector(I) = 2 * I

Next I

'А теперь печать

Debug.Print "Элементы Vector:" & Chr(13)

For I = 1 To 2 * N + 1

Debug.Print Vector(I)

Next I

End Sub

При печати элементов этого массива будут напечатаны, как нетрудно понять вначале нечетные числа от 3 до 21, а затем четные от 22 до 42.

Динамические массивы с успехом можно применять там, где необходимы динамические структуры данных, например списки, стеки, очереди.

Записи и тип, определенный программистом

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

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

Что же мы имеем в 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#, - они автоматически были преобразованы в формальный вид.