Файл: Освой самостоятельно программирование для MS Access 2002 за 24 часа [П.Киммел].pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 21.10.2020
Просмотров: 7867
Скачиваний: 25

Использование функций
и
можно отнести к образцам хорошего сти-
ля программирования, гарантирующего надежность и переносимость кода в условиях
динамического изменения размеров массивов. Даже если со временем понадобится ис-
править в программе конструкции объявлений массивов, циклы обновлять не придется.
Приведенный ниже листинг 12.4 иллюстрирует приемы циклической обработки
элементов многомерного массива. Следует отметить, что вполне допустимы операции
обращения к
любому
измерению массива, и, как правило, они связаны со значитель-
ными издержками в отношении скорости работы программы, поскольку циклы по не-
обходимости становятся вложенными. С увеличением числа измерений массива вы-
числительная сложность алгоритмов циклической обработки возрастает по экспонен-
циальному закону. Показатели быстродействия ухудшаются и при значительном росте
количества элементов в каждом измерении; в этом случае также существенно повы-
шаются требования к объему свободной памяти.
Предположим, что на обработку одного элемента массива затрачивается одна секунда
(разумеется, это условно). Если массив содержит два измерения по 100 элементов в каж-
дом, на выполнение операций со всеми элементами потребуется 10000 секунд. Добавление
в массив еще одного измерения той же "протяженности" приведет к возрастанию времени
обработки на два порядка, т.е. до 1000000 секунд. (Мы уже не упоминаем о затратах опера-
тивной памяти, необходимой для хранения такого числа объектов данных.) Решив объя-
вить многомерный массив, примите к сведению аргументы, изложенные выше.
В примере предыдущего абзаца единицы времени взяты условно. Кроме
того, существуют алгоритмы, обрабатывающие данные значительно эф-
фективнее, чем вложенные циклы.
Листинг 12.4. Пример процедуры обработки многомерного массива
Option Base
Sub
)
Dim
10) As String
Dim I As Integer, J As Integer
For I =
Two D Array, 1 ) To
Two_D_Array, 1 )
9
10:
11:
For J =
Two_D_Array, 2 ) To
J) = I &
& J
J)
Next J
Next I
End Sub
2
Строка З листинга 12.4 содержит объявление двухмерной матрицы разме-
рами 10x10. В строке 4 содержатся определения целочисленных перемен-
ных I и J, которые будут использоваться в качестве индексов. Буквы I, и
К традиционно применяются с подобной целью в математике, поэтому они
уместны и в тексте программы. (Следует напомнить: будьте последователь-
ны в своих действиях. Если вы использовали букву I в качестве индекса
первого измерения массива в одном месте программы, поступайте так и
впредь. Созидательную энергию лучше направить в более полезное русло.)
Строка 5 содержит заголовок внешнего цикла For
Next, а строка 6 -
внутреннего. В обоих случаях для определения границ интервалов измене-
ния индексов применяются функции Lbound и Ubound. Строка 6 иллюст-
рирует способ обращения к элементу двухмерного массива. Выражения
индексов в круглых скобках разделяются символом запятой.
Массивы с числом измерений, превышающим 1 или 2, используются относительно
редко и преимущественно в приложениях математического или технического характера.
час. Управление данными переменного объема
215

S
О
Функции для управления массивами
В VBA существует еще две нужные функции — Array и
Функция
Array возвращает массив, который построен на основании значений
элементов, переданных ей в виде списка аргументов. Синтаксис функции
Array таков:
Аргумент2 [,
[,
... ] )
Array возвращает массив, содержащий значения, переданные в виде па-
раметров. Если выражение вызова функции не содержит аргументов, воз-
вращается пустой массив.
Функция Erase присваивает каждому элементу массива пустое значение, равноцен-
ное null и зависящее от типа массива: для String это пустая строка, для чисел — зна-
чение 0, для Variant — Empty, а для массивов объектов — Nothing. После выполнения
операции Erase массивы всех типов, кроме Variant, по-прежнему допускают индекса-
цию. Листинг 12.5 содержит примеры использования функций Array и Erase.
Операции сравнения содержимого элементов массивов различных типов
выполняются по-разному. Функция Erase, примененная к массиву типа
Variant, приводит к полной очистке массива и присваиванию ему
единого значения Empty. При очистке массива объектов каждый элемент
получает значение Nothing; элементы массива строк становятся равными
а элементы числового
0. Конечно, все это не совсем
привлекательно (укоризненный взгляд в сторону Microsoft), но сейчас
положение дел именно таково. Поэтому, собираясь выяснять, пуст тот
или иной массив, не забывайте об указанных выше особенностях.
Листинг 12.5. Примеры использования функций Array и Erase
Sub
)
Dim
)
A = A r r a y ( 1, 2, 3, 4, 5 )
Dim I As Integer
For I =
A ) To
A )
Next I
Erase A
End Sub
Строка 2 листинга 12.5 содержит объявление пустого массива А типа Vari-
ant. В строке 3 массив заполняется значениями, указанными при вызове
функции Array: 1, 2, 3, 4 и 5. Строки
выглядят знакомым образом:
здесь объявляется целочисленная переменная цикла и выполняется цикли-
ческое отображение содержимого каждого элемента массива в окне
Immediate. Строка 8 содержит инструкцию очистки массива Erase, в ре-
зультате выполнения которой массиву присваивается значение Empty.
Если вы попытаетесь применить функции Lbound или Ubound по отно-
шению к массиву типа V a r i a n t , подвергшемуся операции Erase, от-
кроется окно сообщения об ошибке, показанное на рис. 12.2. Но для
работы с очищенными массивами всех других типов, включая пользо-
вательские, указанные функции могут применяться.
Часть IV. Определение типов данных. Использование массивов и коллекций

/22.
сообщения о выходе
значения индекса массива за допусти-
мые пределы
Проверка переменных с помощью
функции Array
Функция
в качестве аргумента принимает переменную любого типа и
возвращает булево значение, определяющее, является ли переменная массивом. В
функцию IsArray можно передавать и переменные, и литеральные значения. Данная
функция оказывается особенно полезной при работе с данными типа Variant, когда
реальный тип данных не очевиден. Пример использования функции IsArray приве-
ден в листинге 12.6.
Листинг 12.6. Использование функции
для проверки, является ли
переменная массивом
Dim
A
значение False
Dim
В ()
MsgBox
значение True
Dim С As Variant
С =
"В", "С")
MsgBox IsArray (С)
значение True
9
10:
11:
12
:
14:
15:
16:
17:
18:
19:
20:MsgBox
2,
значение True
B As Integer
MsgBox
(D)
значение F.alse
:
У As
значение False
A s String
!:MsgBox IsArray(F)
значение True
Настоятельно советуем избегать создания такого двусмысленного кода, в котором
требовалось бы использовать функции типа IsArray. Однако вы можете попасть в
ситуацию, когда без данной функции не обойтись. В этом случае еще раз пересмотри-
те код — возможно, его удастся переработать так, чтобы он стал более ясным.
12-й час. Управление данными переменного объема
217

Передача массивов параметров в процедуры
Последний аргумент процедуры можно объявить как параметр
(массив
значений типа Variant), что позволит передавать в процедуру набор значений, которые
будут преобразованы в массив. Как это сделать, показано в листинге 12.7.
Листинг 12.7. Использование параметра типа ParamArray
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sub
Call TestParamArray ("Paul
End Sub
"(517) 555-1234",
Sub
As String,
ParamArray
As Variant)
Dim S As String
S = ContactName
Dim I As Integer
For I =
To
S = S &
Next I
"Информация о
& S
End Sub
Тестирование процедуры начните с запуска CallTest. Эта процедура
вызывает подпрограмму TestParamArray с тремя аргументами. Как вид-
но из текста листинга, процедура TestParamArray имеет всего два аргу-
мента: ContactName и ParamArray. При тестировании аргументу Con-
tactName присваивается значение "Paul Kimmel", а два других аргумента
помещаются в массив ParamArray. В результате работы программы в ок-
не сообщений появится вся известная информация о пользователе, неза-
висимо от того, сколько аргументов передается в подпрограмму.
Программистам, использующим язык Ассемблер, наверное, будет легче
изучить массивы параметров, поскольку технология их применения
сходна с тем, как данные помещают в стековый фрейм перед вызовом
функции и получают из
при вызове функции. Всего несколько лет
назад программисты вручную управляли стековым фреймом, теперь его
обработка производится компиляторами.
ParamArray необходим по двум причинам. Язык программирования С поддержи-
вает переменное число аргументов функции, поэтому Visual Basic, вероятно, наследует
эту возможность. Такая техника работает, поскольку передаваемые в функцию данные
помещаются в стековый фрейм, который на самом деле является массивом данных.
Несмотря на то, что стековый фрейм управляется компьютером, в компилятор авто-
матически добавляется код обработки стекового фрейма, поэтому массив аргументов
может пригодиться. От разработчиков компиляторов потребуется больше усилий для
того, чтобы преобразовать данные из стека в специальную переменную, которая обес-
печивает доступ к стековому фрейму как к массиву.
Часть IV. Определение типов данных. Использование массивов и коллекций

Функции, возвращающие массивы
не дает возможности непосредственного возврата массива из функции. Впрочем,
один способ решения подобной задачи все-таки существует — он основан на "модели по-
ведения" функции Array, которая, по существу, возвращает значение типа Variant.
Поскольку возвращаемое значение имеет тип Variant, вероятно, придется
использовать функцию
Тип Variant представляет собой "обобщение" самых разнообразных типов дан-
ных. В программу,
обращения к элементам данных типа Variant, ком-
пилятор добавляет специальные фрагменты кода, которые позволяют определить (на
основе избранных вами способов инициализации переменных) действительные типы
значений, содержащихся в объектах Variant.
Если в ходе решения поставленной задачи потребуется функция, возвращающая
массив, обратитесь к типу Variant. В листинге 12.8 демонстрируется соответствую-
щий пример.
Листинг 12.8. Пример построения функции, возвращающей массив типа Variant
1: Function
) As Variant
2: Static Data (100) As Integer
3 : GetMyArray = Data
End Function
5:
6: Sub
)
Dim
As Variant
8: MyArray =
)
9: If
Then
10: MsgBox
11: End If
End Sub
Строки
листинга 12.8 содержат определение функции GetMyArray,
которая объявляет и возвращает статический массив. Локальные пере-
менные, которые должны быть использованы вне контекста их объявле-
ния, следует определять как статические, — в строке 2 мы так и поступи-
ли, чтобы гарантировать корректность обращения к данным после выхо-
да из функции, в которой они объявлены. В строках
приведен при-
мер подпрограммы, которая демонстрирует использование массива,
возвращенного функцией GetMyArray.
В данном случае можно говорить еще об одном ходе: зная, что данные нам пона-
добятся, мы объявили их не заблаговременно, а именно тогда, когда это оказалось не-
обходимым — т.е. внутри функции GetMyArray. На самом деле процедура размеще-
ния и инициализации массива — ни что иное, как конструктор.
Конструктор —
тер-
мин объектно-ориентированного профаммирования, и в данной части книги исполь-
зуется нечасто. Конструктор — это специальный метод класса, который выполняет
размещение и инициализацию класса (подробнее см. главу 21).
час. Управление данными переменного объема
219