Офисное программирование - Страница 10
Выбор размера массива может быть затруднен, если неизвестно, сколько данных будет введено в массив, или если объем данных, собираемых для массива, значительно меняется. Для подобных ситуаций VBA поддерживает особый тип массивов, называемый динамическим (dynamic) массивом.
Динамические массивы создаются с помощью оператора Dim, Private, Public или Static, причем список размерностей опускается, затем их размер устанавливается с помощью оператора ReDim во время выполнения процедуры.
Оператор ReDim имеет следующий синтаксис:
ReDim [Preserve] varname (subscripts) [As type] [, varname (subscripts) [As type]],
где необязательное ключевое слово Preserve приводит к тому, что VBA сохраняет данные в имеющемся массиве, когда изменяется размер массива с помощью ReDim;
varname – имя существующего массива;
subscripts – измерения массива (синтаксис для оператора subscripts в операторе ReDim такой же, как для оператора Dim);
type – любой тип VBA или определенный пользователем тип.
Необходимо использовать отдельный оператор As type для каждого массива, который вы определяете.
Примеры:
1) Dim Month() As String – объявляет динамический массив Month;
2) ReDim Month(1 to 30) – изменяет размер массива до 30 элементов;
3) ReDim Month(31) – изменяет размер массива до 31 элемента;
4) ReDim Preserv Month(1 to 31) – изменяет размер массива до 31 элемента, сохраняя содержимое;
5) Dim Table() As Integer – объявляет динамический массив;
6) ReDim Table(3, 15) – делает массив двумерным;
7) ReDim Table(4, 20) – изменяет размер двумерного массива;
8) ReDim Preserv Table(4, 25) – только изменяет последний размер массива;
9) Dim Mas as Variant – объявляет переменную типа Variant;
10) ReDim Mas(20) As Integer – создает массив 20 целых чисел в Variant.
Выводы:
1) можно изменять только последнее измерение многомерного массива, когда используется ключевое слово Preserv;
2) можно использовать ReDim для создания типизированного массива внутри переменной типа Variant.
Массив в программе можно также определить поэлементно. Например, следующий код
Dim B(l to 2, 1 to 2) as single
В(1,1)=2
В(1,2)=5
В(2,1)=4
В(2,2)=3
создает двумерную таблицу

При работе с массивами бывает полезно применять следующие функции и процедуры.
1. Array (списокАргументов)
Создает массив типа Variant. Аргумент в скобках представляет разделенный запятыми список значений, присваиваемых элементам массива.
Пример:
Dim День As Variant
День=Array(«Пн»,"вт","ср",….)
2. VBA имеет две функции, которые отслеживают верхний и нижний индексы предела массива, – функции Lbound и ubound. Эти функции возвращают нижнее и верхнее граничные значения индексов статического или динамического массива.
Синтаксис:
Lbound (имяМассива [, размерность])
Ubound (имяМассива [, размерность]),
где ИмяМассива – имя переменной массива;
Размерность – целое число, указывающее размерность массива, нижнюю или верхнюю границу которой возвращает функция. Для первой размерности следует указать 1, для второй – 2 и т. д. Если аргумент размерность опущен, подразумевается значение 1.
3. Использование оператора Erase для очистки или удаления массивов.
Оператор Erase позволяет выполнять одну из двух задач в зависимости от того, каким массивом манипулирует пользователь – статическим или динамическим. В случае статических массивов Erase позволяет очищать все элементы массива, в основном переустанавливая массив в то же самое состояние, какое он имел, когда VBA создавал его в оперативной памяти. В случае динамических массивов Erase позволяет полностью удалять массив и его содержимое из оперативной памяти.
VBA удаляет из памяти массивы, объявляемые локально в процедуре (так же, как и любые другие локальные переменные), каждый раз, когда процедура прекращает выполняться. Однако массивы, объявляемые на модульном уровне, существуют, пока любая процедура в этом модуле выполняется. Если программа большая, можно восстановить ресурс памяти, используемой динамическими массивами модульного уровня. Оператор Erase позволяет делать именно это.
Оператор Erase имеет следующий синтаксис:
Erase array1 [, array2, …]
Здесь array1 и array2 представляют любое допустимое имя массива VBA.
Оператор Erase удаляет из памяти динамические массивы, освобождая область памяти, ранее используемую этим массивом. При удалении динамического массива с помощью оператора Erase необходимо повторно создать массив с помощью оператора ReDim перед тем, как можно будет использовать этот определенный динамический массив снова. При попытке доступа к элементам в динамическом массиве, для которого был использован оператор Erase, без его переопределения, VBA отображает сообщение об ошибке.
Обычно в VBA используются массивы с нулевой базой. В системе нумерации с нулевой базой индекс для первого элемента в любом измерении массива является равным 0; массив с 10 элементами имеет индексы от 0 до 9.
Было бы гораздо удобнее, если бы элементы массива нумеровались начиная с 1, а не с 0. VBA позволяет задавать начальное число для элементов массива, используя директиву компилятора Option Base для указания того, должна ли нумерация индексов начинаться с 0 или с 1.
Директива компилятора Option Base имеет следующий синтаксис:
Option Base 0 | 1
Если оператор Option Base не используется, VBA начинает нумерацию индексов массива с 0 (по умолчанию). Необходимо помещать оператор Option Base в область объявлений модуля перед объявлениями любых переменных, констант или процедур. Нельзя помещать оператор Option Base внутри процедуры. Можно иметь только один оператор Option Base в модуле; оператор Option Base влияет на все массивы, объявляемые в модуле, независимо от того, являются ли они локальными в процедуре или объявляются на модульном уровне.
Например:
Option Base 0 'установка по умолчанию с нуля
Option Base 1 'индексы массивов начинаются с 1
Пример 11. Создать программу, организующую три двумерных массива. Первые два массива определены поэлементно в программе. Третий массив А организуется путем суммирования соответствующих членов массивов В и С (рис. 24).
Результаты организации массивов выведены в соответствующие метки на форме после нажатия на кнопку Массив.
Листинг примера 11
Private Sub CommandButton1_Click()
Dim B(1 To 2, 1 To 2) As Integer
Dim c(1 To 2, 1 To 2) As Integer
Dim A(1 To 2, 1 To 2) As Integer
B(1, 1) = 5
B(1, 2) = 4
B(2, 1) = 8
B(2, 2) = 10
c(1, 1) = 0
c(1, 2) = 1
c(2, 1) = 5
c(2, 2) = 10
For i = 1 To 2
For j = 1 To 2
A(i, j) = B(i, j) + c(i, j)
Next j
Next i
Label1.Caption = «a(1,1)=» & A(1, 1) & « a(1,2)=» & A(1, 2)& « a(2,1)=» & A(2, 1) & « a(2,2)=» & A(2, 2) Label2.Caption = «b(1,1)=» & B(1, 1) & « b(1,2)=» & B(1, 2) & « b(2,1)=» & B(2, 1) & « b(2,2)=» & B(2, 2)
Label3.Caption = «c(1,1)=» & c(1, 1) & « c(1,2)=» & c(1, 2) & « c(2,1)=» & c(2, 1) & « c(2,2)=» & c(2, 2)
End Sub

Рис. 24. Форма примера 11 в режиме конструктора и в рабочем состоянии
Пример 12. Создать программу, создающую два двумерных массива: один массив вводом числовых элементов в соответствующие текстовые поля формы, второй – вводом четырех произвольных фамилий в соответствующие текстовые поля формы (рис. 25, 26). В результате все элементы первого массива увеличиваются на 10 и выводятся в соответствующую метку на форме. Элементы же второго строкового массива организуют вывод предложений типа: работник фамилия Иванов, где Иванов (например) берется из строкового массива, введенного в соответствующие текстовые поля. Данные результаты получаются после нажатия на кнопку Вывод пользовательского диалогового окна.