Пакеты прикладных программ / Учебно-методический комплекс / Конспект лекций / Лабораторные работы / Дополнительные материалы / Список литературы

2.5.2. VBA. Организация циклов

VBA поддерживает циклические структуры двух видов:
  1. Циклы с фиксированным числом повторений ( циклы со счетчиком).
  2. Циклы с неопределенными числом повторений ( циклы с условием).
Для всех видов циклов используется понятие тело цикла, определяющее блок операторов, заключенных между начальным и конечным операторами цикла. Каждое повторение выполнения операторов тела цикла называется итерация.

Фиксированные циклы

VBA предоставляет две управляющие структуры для организации фиксированного цикла: For … Next (цикл со счетчиком) и For Each … Next (цикл с перечислением). Оператор For … Next это типовой цикл со счетчиком, выполняющий заданное число итераций. Синтаксис оператора For … Next:
 For <счетчик> = <начЗначение> То <конЗначение> [Step <приращение>]         <блок операторов>  Next [<счетчик>] 


Пример использования оператора For ... Next.

Листинг 9. Оператор For … Next

 ' ЗАДАЧА: Составить программу, которая получает два числа от пользователя. ' Складывает все числа в диапазоне, заданном этими двумя числами, а затем ' отображает результирующую сумму.  Sub sample7()         Dim i As Integer                ‘счетчик цикла         Dim sStart                      ‘начальное значение счетчика         Dim sEnd                        ‘конечное значение счетчика         Dim sSum As Long                ‘результирующая сумма         sStart = InputBox("Введите первое число:")         sEnd = InputBox("Введите второе число:")         sSum = 0         For i = CInt(sStart) To CInt(sEnd)                 sSum = sSum + i         Next i         MsgBox "Сумма чисел от " & sStart & " до " & sEnd & " равна: " & sSum End Sub 

Оператор цикла For Each … Next относится к категории операторов объектного типа, т.е. применяется в первую очередь к коллекциям объектов, а также к массивам. Тело цикла выполняется фиксированное число раз, соответствующее числу элементов массиве или коллекции. Формат оператора For Each … Next:

 For Each <элемент> In <группа>         <блок операторов>  Next [<элемент>]  
Циклы с условием используются в тех случаях, когда повторяющиеся действия нужно выполнять только при определенных условиях. Количество итераций не определено и в общем случае может быть равно нулю (в частности, для циклов с предусловием). VBA предлагает разработчикам несколько управляющих структур для организации циклов с условием: Цикл Do While … Loop - типичный цикл с предусловием. Условие проверяется до того, как выполняется тело цикла. Цикл продолжает свою работу, пока это <условие> выполняется (т.е. имеет значение True). Так как проверка выполняется в начале, то тело цикла может ни разу не выполниться. Формат цикла Do While … Loop:
 Do While <условие>         <блок операторов> Loop 

Листинг 10. Цикл Do While … Loop

 ' ЗАДАЧА: Составить программу, которая предусматривает ввод пользователем ' произвольной последовательности чисел. Ввод должен быть прекращен ' только после того, как сумма введенных нечетных чисел превысит 100. Sub sample8()         Dim OddSum As Integer   ‘сумма нечетных чисел         Dim OddStr As String    ‘строка с нечетными числами         Dim Num                 ‘для приема вводимых чисел         OddStr = ""                   ‘инициализация выходной строки         OddSum = 0                      ‘инициализация суммы OddSum         Do While OddSum < 100        ‘начало цикла                 Num = InputBox("Введите число: ")                 If (Num Mod 2) <> 0 Then  ‘проверка на четность                         OddSum = OddSum + Num   ‘изменение суммы OddSum                         OddStr = OddStr & Num & " "                 End If         Loop         'вывод строки с нечетными числами:         MsgBox prompt:="Нечетные числа: " & OddStr End Sub 

Оператор Do … Loop While предназначен для организации цикла с постусловием. Условие проверяется после того, как тело цикла, будет выполнено хотя бы один раз. Цикл продолжает свою работу, пока <условие> остается истинным. Формат цикла Do … Loop While:

 Do         <блок операторов>  Loop While<условие> 

Листинг 11. Цикл с постусловием

 ' ЗАДАЧА: Составить программу игры "Угадай число". Программа должна случайным  ' образом генерировать число в диапазоне от 1 до 1000, пользователь должен  ' угадать это число. Программа на каждое вводимое число выводит подсказку  ' "больше" или "меньше". Sub sample8() Randomize Timer ' инициализация генератора случайных чисел Dim msg As String               ' строка сообщения Dim SecretNumber As Long, UserNumber As Variant Begin:         SecretNumber = Round(Rnd * 1000) ' число, сгенерированное компьютером         UserNumber = Empty                       ' число, вводимое пользователем  Do ' игровой процесс         Select Case True                 Case IsEmpty(UserNumber): msg = "Введите число"                 Case UserNumber > SecretNumber: msg = "Слишком много!"                 Case UserNumber < SecretNumber: msg = "Слишком мало!"          End Select         UserNumber = InputBox(prompt:=msg, Title:="Угадай число") Loop While UserNumber <> SecretNumber ' проверка  If MsgBox("Играть еще? ", vbYesNo + vbQuestion, "Вы угадали!") = vbYes Then          GoTo Begin End If End Sub 

Циклы Do Until … Loop и Do … Loop Until являются инверсиями ранее рассмотренных циклов с условием. В общем случае они работают аналогично, за исключением того, что тело цикла выполняется при ложном условии (т.е. <условие>=False). Формат цикла Do Until … Loop:

 Do Until <условие>         <блок операторов> Loop 

Формат цикла Do … Loop Until:

 Do         <блок операторов>  Loop Until<условие> 

Практическое задание: Перепишите программы из листингов 10 и 11 с использованием инвертированных операторов цикла.


Цикл While … Wend также относится к циклам с условием. Данный оператор полностью соответствует структуре Do While … Loop. Формат цикла While … Wend:

 While <условие>         <блок операторов> Wend 

Отличительной особенностью этого оператора является невозможность принудительного завершения (прерывания) тела цикла (оператор Exit Do не работает в цикле While … Wend).

Для досрочного завершения итерации и выхода из цикла применяется оператор Exit. Этот оператор применим в любой циклической структуре, кроме While ... Wend. Общий синтаксис использования Exit для прерывания цикла таков:
 <начало_цикла>                 [<блок операторов1>]                       Exit (For | Do)                 [<блок операторов2>]                 [Exit (For | Do)]                 ...  <конец_цикла> 

При выполнении оператора Exit цикл прерывается, и управление передается оператору, следующему за оператором <конец_цикла>. В теле цикла может присутствовать несколько операторов Exit.

Листинг 12. Принудительный выход из цикла

 Sub sample9()         For i = 1 To 10000000         If i = 10 Then Exit For ' выход из цикла, когда счетчик достигнет 10         Next End Sub 
VBA поддерживает два типа подпрограмм: процедуры и функции. Для объявления процедуры в VBA используется ключевое слово Sub:
 Sub <имяПроцедуры> [(<списокПараметров>)]         <операторы>  End Sub 
где:
<имяПроцедуры> – любой допустимый идентификатор VBA;
<списокПараметров> – список формальных параметров процедуры, если он пуст, то такая процедура является макросом;

<операторы> - любая последовательность операторов VBA.

Листинг №.13 Пример объявления процедуры

 ' Процедура выводит в отладчик максимальное из трех чисел Sub sMax3(A As Long, B As Long, C As Long)                 If (A > B) And (A > C) Then                                 Debug.Print "Max is "; A                 ElseIf (B > A) And (B > C) Then                                 Debug.Print "Max is "; B                 Else                                 Debug.Print "Max is "; C                 End If End Sub 

Синтаксис объявления функции несколько сложнее, чем синтаксис процедуры:

 Function <имяФункции> [(<списокПараметров>)] [As <типФункции>]                 <операторы>                 . . .                  <имяФункции> = <возвращаемое_значение>                 [<операторы>]      End Function 
где:
<имяФункции> - любой допустимый идентификатор;
<списокПараметров> – список формальных параметров процедуры;
<типФункции> - имя любого поддерживаемого VBA типа данных;
<операторы> - любая последовательность операторов VBA.

<возвращаемое_значение> - результат, передаваемый в вызывающую программу.

Листинг №14. Пример объявления функции

 ' Функция возвращает максимальное из трех чисел Function fMax3(A As Long, B As Long, C As Long) As Long                 If (A > B) And (A > C) Then                                 fMax3 = A                 ElseIf (B > A) And (B > C) Then                                 fMax3 = B                 Else                                 fMax3 = C                 End If End Function 

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

 Function | Sub <имяПроцедуры> (<параметр1> As <тип>, _ <параметр2> As <тип>, ..., <параметрN> As <тип>) 

Если тип данных параметра не указан, то автоматически будет использован тип Variant. Список параметров может быть пустым как для процедуры, так и для функции. В этом случае после имени процедуры ставятся пустые круглые скобки. При передаче фактических параметров в подпрограмму может использоваться один из двух различных способов:

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

Способ передачи указывается при описании параметров в строке объявления подпрограммы. Имени параметра может предшествовать один из явных описателей способа передачи:

По умолчанию выполняется передача по ссылке.

Листниг 15. Передача параметров в подпрограмму

 ' sample10 - вызывающая программа (макрос) ' ByValByRefDemo - вызываемая процедура Sub sample10()                 Dim a As Long, b As Long, c As Long ' фактические параметры                 a = 10                 b = 10                 c = 10                 ByValByRefDemo a, b, c ' передача фактических параметров                 Debug.Print "2: " & "a = " & a & "; b = " & b & "; c = " & c End Sub Sub ByValByRefDemo(x As Long, ByVal y As Long, ByRef z As Long)                 ' выполнение действий над формальными параметрами                                x = x * 2                 y = y * 3                 z = z * 4                        Debug.Print "1: " & "x = " & x & "; y = " & y & "; z = " & z End Sub 

Здесь объявлены две процедуры: sample10 и ByValByRefDemo. Процедура sample10 вызывает процедуру ByValByRefDemo и передает ей предварительно инициализированные переменные a, b и c. Процедура ByValByRefDemo получает значения переменных a, b и c в виде формальных параметров x, y и z соответственно, выполняет над ними указанные действия, выводит результат и завершается. После возврата из подпрограммы процедура sample10 выводит значения переменных a, b, c в окно отладчика (рис. 4).

Рис. 4. Передача параметров в подпрограмму

Именованные параметры

При вызове подпрограмм в VBA параметры необходимо передавать в определенном порядке. Отсутствующие необязательные параметры отмечаются запятыми. Нарушение этого правила часто приводит к ошибкам – легко пропустить или поменять местами параметры. Чтобы избежать этих проблем, в VBA можно использовать именованные параметры функций. Для этого в вызове подпрограммы явно указываются имена параметров (как это было задано при объявлении подпрограммы), каждому из которых присваивается требуемое значение с помощью оператора ":=" ("двоеточие_равно"). При использовании именованных параметров можно не обозначать отсутствующие параметры и, кроме того, порядок перечисления параметров может быть произвольным.

Следующий пример показывает два обращения к функции MsgBox, которые имеют один и тот же результат:

 ' обычный вызов MsgBox "Здравствуй, мир!", , "Окно приветствия" ' вызов, с использованием именованных параметров MsgBox Prompt:= "Здравствуй, мир!", Title:= "Окно приветствия" 

Вызов подпрограмм

Подпрограммы могут быть вызваны различными способами:

Листинг №16. Вызов процедуры

 Sub sample11() ' вызывающий макрос         Dim usr As String         usr = InputBox("Login")         Hello usr ' вызов процедуры Hello 
без Call          Call Hello(usr) ' использование инструкции Call End Sub ' процедура принимает один параметр, формирует строку сообщения,  ' выводит сообщение в окно отладчика  Sub Hello(usrname As String)          Debug.Print "Hello, " & usrname & "!" End Sub 

Если в проекте используется несколько подпрограмм с одинаковыми названиями (это возможно, если они в разных модулях), то при их вызове перед именем подпрограммы надо указывать (через точку) имя модуля, в котором процедура расположена:

 <имяМодуля>.<имяПроцедуры> <списокФактическихПараметров> 

Например

 MyModule.MySub fArg, sArg ' вызов процедуры из модуля MyModule 
Для вызова общих (Public) подпрограмм из другого проекта дополнительно к именам модуля и подпрограммы указывается имя проекта:
 <имяПроекта>.<имяМодуля>.<имяПроцедуры> <списокФактическихПараметров> 

Например

 someVal = MyProject.MyModule.MyFunc(fArg, sArg) ' вызов функции из проекта MyProject 

Прерывание подпрограммы

В случае необходимости, выполнение процедуры или функции может быть прервано досрочно. Для этого нужно использовать инструкцию прерывания Exit Sub. В этом случае синтаксис объявления примет следующий вид (на примере объявления процедуры):
 Sub <имяПроцедуры> [(<списокпараметров>)]         <операторы> Exit Sub         <операторы> End Sub 
Любая программа на VBA представлена в виде проекта. Проект - это совокупность программных модулей различных типов. В свою очередь модуль - это основная программная единица уровня проекта, в которой размещаются описания и реализация переменных, констант, типов, подпрограмм и т.д. Имеется три типа модулей:

Структура модуля VBA включает два неявных (т.е. не требующих специального описания) раздела: общий (General) и объявлений (Declarations). В общем разделе задаются параметры среды (Option Base, Option Explicit), приводятся описания глобальных переменных, констант и типов. Раздел объявлений предназначен для описания процедур и функций.

VBA поддерживает две области видимости для переменных и подпрограмм: локальную и глобальную.

Локальные переменные определены на уровне подпрограммы с помощью ключевых слов Dim или Static. Они доступны только внутри этой подпрограммы и по выходу из нее уничтожаются. Глобальные переменные объявляются на уровне модуля. Такие переменные доступны:

Подпрограммы VBA могут быть объявлены на двух уровнях – уровне проекта (Public) и уровне модуля (Private). Например:
 Public Sub Query(price, count) ' видимость на уровне проекта Private Sub Sub Query(price, count) ' видимость на уровне модуля 

По умолчанию используется уровень проекта.

При описании локальных переменных можно использовать ключевое слово Static. Такие переменные являются статическими и сохраняют значения между вызовами.

Встроенные функции VBA

В языке программирования VBA предусмотрено несколько десятков встроенных функций. Они доступны в любой программе на языке VBA, при этом безразлично, в среде какого программного продукта мы находимся — Excel, Word, Access или, к примеру, AutoCAD. Используются они очень активно, и во многих ситуациях без них не обойтись. Встроенные функции обычно группируют по назначению: математические, строковые, преобразования типов, логические и т.п. В справке по VBA имеется подробная информация о всех встроенных функциях. Здесь же приведем краткое описание только некоторых.

Функции приведения типов

Используются для конвертации типов данных. Вот перечень этих функций: CBool(), CByte(), CCur(), CDate(), CDbl(), CDec(), CInt(), CLng(), CSng(), CStr(), CVar(), CVDate(), CVErr() . Просмотреть, что в итоге получилось, можно при помощи функции TypeName() , например:
 nVar1 = CInt(InputBox("Введите значение"))  
MsgBox TypeName(nVar1)  

Кроме того, еще несколько полезных для конвертации функций:

Чтобы не возникло ошибок при конвертации, можно вначале проверять значения на возможность конвертации при помощи функций IsNumeric() и IsDate(). Для проверки на соответствие специальным значениям можно использовать функции IsArray(), IsEmpty(), IsError(), IsMissing(), IsNull() и IsObject(). Все эти функции возвращают True или False в зависимости от результатов проверки переданного им значения.

Строковые функции

Математические функции

Функций для работы с числовыми значениями в VBA очень много. Приведем только некоторые из них.

Функции для работы с датой и временем

Основные функции VBA для работы с датой/временем:

Функции взаимодействия с пользователем

Для организации диалога с пользователем VBA представляет две встроенные функции - MsgBox и InputBox. Окно сообщений MsgBox выводит сообщения для пользователя, а окно ввода InputBox обеспечивает возможность получения информации от пользователя.

Функция MsgBox() выводит на экран диалоговое окно, содержащее сообщение, устанавливает режим ожидания нажатия кнопки пользователем, а затем возвращает значение типа Integer, указывающее, какая кнопка была нажата.

Формат функции MsgBox:

 MsgBox (Prompt [, Buttons] [, Title] [, HelpFile, Context]) 

Назначение параметров:

Простой пример использования функции MsgBox:
 Sub sample3()         MsgBox "Видите ли вы две кнопки?", vbYesNo + vbInformation, "Сообщение" End Sub 

В данном примере MsgBox применяется не в виде функции, а в виде процедуры (т.е. не возвращает никакого значения). Следовательно, код выбранной кнопки нигде не сохраняется и не может быть использован. Чтобы определить, какая кнопка была нажата, MsgBox необходимо вызвать как функцию, т.е. сохранить возвращаемое значение в переменную (Листинг 17.

Листинг 17. Использование MsgBox

 Sub sample4()         Dim res ' объявляем переменную         ' вызываем MsgBox и сохраняем значение в переменной         res = MsgBox("Видите ли вы две кнопки?", vbYesNo + vbInformation, "Сообщение")         Debug.Print res ' печатаем полученное значение End Sub 

При выполнении этого макроса, когда пользователь выбирает кнопку Yes или No в переменной res сохраняется число, соответствующее выбранной кнопке.

Вместо возвращаемых функцией MsgBox целочисленных значений удобнее пользоваться предопределенными константами VBA. В таб. 11 приведены возвращаемые значения констант функции MsgBox.

Таблица 11. Возвращаемые значения функции MsgBox

Константа Означает, что пользователь нажал кнопку
vbAbort Стоп (Abort)
vbCancel Отмена (Cancel)
vbIgnore Пропустить (Ignore)
vbNo Нет (No)
vbOk Ок
vbRetry Повтор (Retry)
vbYes Да (Yes)
Дополним код листинга 17 проверкой возвращенного значения (листинг 18).

Листинг 18. Проверка возращаемого значения MsgBox

 Sub sample5()                 ' вызываем MsgBox и сохраняем значение в переменной                 res = MsgBox("Видите ли вы две кнопки?", vbYesNo + vbInformation, "Сообщение")                               ' проверяем, какая кнопка нажата                                 If res = vbYes Then : MsgBox "Вы нажали Yes", , "Результат выбора"                 Else : MsgBox "Вы нажали No", , "Результат выбора"                 End If   End Sub 

Функция InputBox() выводит на экран диалоговое окно, содержащее сообщение и поле ввода, устанавливает режим ожидания ввода текста, а затем возвращает значение типа String, содержащее текст, введенный в поле. Формат функции InputBox:

 InputBox (Prompt [, Title] [, Default] [, XPos] [, Ypos] [, HelpFile, Context]) 

Назначение параметров:

Приведем пример использования функции InputBox для получения имени пользователя.
 Sub sample6()         Dim username As String          username = InputBox("Введите ваше имя ", "Пример 6")         MsgBox ("Здравствуйте, "+username) End Sub 

В результате выполнения этого макроса на экран последовательно выводятся диалоговые окна ввода и вывода (рис. 5).



Рис. 5 Интерактивные функции VBA

Структурные типы данных

Кроме простых типов VBA предоставляет возможность создавать и использовать структурные типы данных. Структурный тип данных – это тип данных, который позволяет в одной величине хранить одновременно несколько значений. К структурным типам данных VBA относятся массивы и пользовательские типы данных. Массив – это упорядоченная совокупность данных одного типа. Порядок элементов массива задается индексами его элементов. Количество элементов определяет размер массива, а количество индексов (в VBA - до 60) - его размерность. VBA поддерживает статические и динамические массивы.

Статический массив имеет фиксированный размер и размерность, заданные при объявлении и неизменяемые в ходе выполнения программы. Синтаксис объявления статического массива:

 (Public | Private | Dim) <имяМассива> (<размер1>, <размер2>, ..., <размер N>) As <типДанных> 

Указанные в скобках величины <размер1>, <размер2>, …, <размер N> задают количество индексов и максимально допустимое значение для каждого конкретного индекса (его верхняя граница). Таким образом, определяются размерность массива (количество индексов) и размер массива – количество элементов данного массива. При этом индексирование элементов массива по умолчанию начинается с нуля. Так, объявление

 Dim Array1 (9) As Integer, 

определяет одномерный массив из 10 целых чисел, а объявление

 Dim Array3 (4, 9) As Variant, 

определяет двумерный массив из пятидесяти (5х10) элементов типа Variant.

В VBA имеется возможность изменить индекс нижней границы с помощью оператора Option Base (указание Option Base 1 или Option Base 0 в общем разделе модуля). Более того, при объявлении массива можно явно указать и верхнюю, и нижнюю границы. Синтаксис оператора объявления массива с указанием границ для индексов:

 Dim <имяМассива> (<мин1> To <макс1>[, ..., <минN> To <максN>]) As <типДанных> 

Примеры:

 Dim A (1 To 3, 1 To 3) As Single Dim B (1 To 12) As Integer 

Правила инициализации элементов массива такие же, как и для переменных того типа, который использован при объявлении массива. Доступ к элементам массива выполняется по индексу. Листинг 19 иллюстрирует работу с одномерным массивом.

Листинг 19. Обращение к элементам массива

 ' ЗАДАЧА: Сгенерировать 10 случайных целых чисел от 0 до 100,  ' записать их в массив и вывести в окно отладчика Sub sample14()                 Randomize Timer ' запуск генератора случайных чисел                 Dim myarr(1 To 10) As Long ' объявление массива                                  ' запись чисел в массив                 For i = 1 To 10                         myarr(i) = Round(Rnd * 100)                 Next                                  ' чтение элементов массива и вывод значений в отладчик                 For i = 1 To 10                         Debug.Print myarr(i)                 Next End Sub 

Удобным способом определения одномерных массивов является функция Array, преобразующая список элементов, разделенных запятыми, в массив из этих значений:

 Dim A As Variant A = Array (10, 20, 30) B = A(2) 

В данном примере переменная А создается как одномерный массив, состоящий из трех элементов (10, 20, 30), а переменная В принимает значение второго элемента массива А (20).

VBA поддерживает использование динамических массивов, размер и размерность которых может изменяться во время выполнения программы. Объявление динамического массива аналогично объявлению статического, но при этом не задаются ни размер, ни размерность:

 Dim <имяМассива> () As <типДанных> 

Для указания и изменения размеров такого массива используется специальный оператор - ReDim:

 ReDim <имяМассива> (<размер1>, <размер2>, ..., <размер N>) 

Размерность и размер определяется динамически в той процедуре и в тот момент, когда они становится фактически известной. Обратите внимание, в этом операторе границы изменения индексов можно задать не только как константы, но и как выражения, зависимые от переменных.

Для повторных изменений массива можно снова использовать оператор переопределения ReDim. При каждом переопределении динамического массива все его значения теряются. Чтобы сохранить все ранее полученные элементы необходимо использовать ключевое слово Preserve при переопределении.

Листинг 20 демонстрирует работу с динамическим массивом (нумерация строк приведена только для удобства пояснений).

Листинг20. Работа с динамическим массивом

 1: Public Vector() As Integer 2: Public Sub DMassiv() 3:      Dim N As Byte, I As Byte 4:       5:      N = InputBox("Введите фактическую размерность вектора") 6:      ReDim Vector(N) 7:      For I = 1 To N 8:              Vector(I) = 2 * I + 1 9:      Next I 10:      11:     'Массив расширяется с сохранением ранее вычисленных элементов 12:     ReDim Preserve Vector(2 * N + 1) 13:     For I = N + 1 To 2 * N + 1 14:             Vector(I) = 2 * I 15:     Next I 16:     Debug.Print "Элементы массива Vector:" & Chr(13) 17:     For I = 1 To 2 * N + 1 18:             Debug.Print Vector(I) 19:     Next I 20: End Sub 

Поясним приведенный код. Сначала на уровне модуля объявляется глобальный динамический массив Vector (строка 1). В момент объявления размерность динамического массива не указывается, соответственно не выделяется память. Все это произойдет позже, в процессе выполнения программы. Далее приводится одна из возможных процедур, работающая с этим массивом Vector. В строке 12 массив переопределяется (увеличивается его размер) с сохранением предыдущих значений. Затем массив расширяется (цикл в строках 13-15). В последнем цикле (строки 17-19) значения элементов сформированного массива выводятся в окно отладки (Immediate).

В рассмотренном примере изменялся размер динамического массива, но не его размерность (массив оставался одномерным). Приведем фрагмент кода программы, в котором изменяются и размер, и размерность динамического массива:

 1: Sub sample22 () 2:       Dim dArray ( ) As Variant 3:       ReDim dArray(1,2) 4:       dArray(0,0) = 2 5:       dArray(0,1) = 3 6:       k = dArray(0,0) + dArray (0,1) 7:       ReDim dArray(k) 8:       dArray(0) = "Строка1" 9: End Sub 

В этом примере массив dArray сначала определяется как двумерный массив из шести элементов (2x3) (строка 3), а затем переопределяется как одномерный массив, причем верхняя граница индекса задается значением k (строка 7).

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

VBA поддерживает возможность создавать пользовательские типы данных на основе ранее определенных типов. Такой тип в VBA называется User-defined type (UDT) - тип, определенный пользователем. Это соответствует понятиям типа данных record (запись) в языке Pascal или struct (структура) в языке С/С++. Для создания пользовательского типа предназначен оператор Type. Он позволяет на уровне модуля определить структуру данных, включающую другие разнородные, но логически связанные переменные различных типов. После описания типа на его основе можно создавать и использовать переменные.

Синтаксис оператора Type:

 Type <имяТипа>          <имяЭлемента1> As <тип>          <имяЭлемента2> As <тип> End Type 
где:
<имяТипа> – имя пользовательского типа данных;

<имяЭлемента> – имя структуры, составляющей новый тип данных.

С помощью ключевых слов Private и Public можно задать область видимости создаваемого типа. Опции Private и Public указываются в строке объявления типа перед ключевым словом Type.

Листинг 21. Пример использования пользовательского типа

 ' Тип TStudent хранит информацию о студенте. Public Type TStudent         ID As Long 'идентификатор         LastName As String 'фамилия         FirstName As String 'имя          MiddleName As String 'отчество         BirthDay As Date 'дата рождения End Type ' Учебная группа Public Type TGroup         Num As String * 10 'номер группы         Students() As TStudent 'список (массив) студентов End Type ' Объявления переменных Private stud As TStudent ' студент  Public group As TGroup 'группа 

Для обращения к элементам пользовательского типа (полям структуры) используется точечная нотация:

 <имяПеременнойUDT>.<имяЭлемента> 

Листинг22. Работа с переменными пользовательского типа

 Sub sample20()         ReDim group.Students(10)         group.Num = "АС-1234"                  group.Students(0).LastName = "Петров"         group.Students(0).FirstName = "Иван"                   Debug.Print group.Num & group.Students(0).LastName & " " & group.Students(0).FirstName  End Sub 

Широкие возможности, представляемые программисту пользовательским типом имеют ограничение: все операции должны выполняться на уровне полей. Единственная разрешенная операция — присваивание (листинг 23).

Листинг 23. Операции над пользовательским типом

 Sub sample21()                 Dim group1 As TGroup, group2 As TGroup                 ReDim group1.Students(25)                 ReDim group2.Students(28)                 group1.Num = "AS-1234"                 group2.Num = "AS-5678"                 Debug.Print "1: "; group1.Num, group2.Num                 ' If group2 > group1 Then ... - Это вызовет ошибку                 If UBound(group2.Students) > UBound(group1.Students) Then ' Так можно                         group1 = group2 ' Так тоже можно                 End If                 Debug.Print "2: "; group1.Num, group2.Num              End Sub 

← 2.5.1 VBA. Ветвления ↑ 2.5.2. VBA. Организация циклов Тема 2.6 Объектно-ориентированное программирование в VBA →

Рекомендуемая литература

Хорев В.Д.
Самоучитель программирования на VBA в Microsoft Office
Сохранить файл
Книга адресована широкому кругу пользователей Microsoft Office, желающих автоматизировать свою работу при помощи Visual Basic for Application (VBA). Она является практическим руководством для пользователей любой квалификации и предлагает множество работающих примеров и практических советов.

Р.Холи, Д.Холи
Excel. Трюки. 100 профессиональных примеров
Сохранить файл
Книга «Excel. Трюки» помогает читателю сразу же перейти к практическим инструментам и методам анализа, обработки и представления данных. В издании рассматриваются методы наиболее эффективной обработки данных, которые позволяют быстро добиться необходимых результатов. Книга предназначена для всех пользователей, применяющих Excel для обработки данных.

Г.З. Гарбер
Основы программирования на Visual Basic и VBA в Excel 2007
Сохранить файл
В книге рассматриваются основы разработки приложений в среде Excel на языках Visual Basic и VBA (Visual Basic for Application). Продемонстрированы приемы разработки пользовательского интерфейсаа, работы с отладчиком, макрорекордером, разработки справочной системы. Книга ориентирована на преподавателей информатики и студентов.

Н.С. Медведева, О.И. Москалева, А.М. Полонский,
Основы администрирования в среде 1С:Предприятие
Сохранить файл
Н.С. Медведева, О.И. Москалева, А.М. Полонский, Описываются концепция администрирования программы 1С:Предприятие 7.7 в основных конфигурациях. Методические указания содержат необходимые теоретические сведения и описание лабораторной работы, целью которых является изучение и приобретение практических навыков по администрированию среды 1С:Предприятие.

Митичкин С.
Практика программирования в среде 1С:Предприятие
Сохранить файл
Книга предназначена для программистов, желающих освоить принципы разработки прикладных программ и программных комлексов в среде 1С:Предприятие. Первая чать книги содержит теоретический материал для освоения этой прикладной платформы. Во второй части на простых примерах демонстрируются приемы разработки на встроенном языке 1С:Предприятие и решения прикладных задач.

См. также