Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Часть 2. Основы офисного программирования.doc
Скачиваний:
8
Добавлен:
01.05.2025
Размер:
4.04 Mб
Скачать

5.2.12. Рекурсивные вычисления

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

При описании процедур-функций приведен пример рекурсивного вычисления факториала.

5.2.13. Процедуры-подпрограммы

Подпрограмма представляет собой последовательность операторов языка Visual Basic, ограниченных инструкциями Sub и End Sub. Подпрограмма выполняет действия, заданные перечисленными в ней инструкциями, а результаты работы может вернуть, если это необходимо, через параметры, переданные ей при вызове по ссылке. Таким образом, эти процедуры нельзя вызывать при вычислении значений выражений, вызов подпрограмм осуществляется отдельными операторами (инструкциями). Если подпрограмма не имеет аргументов, инструкция Sub (заголовок процедуры) должна содержать пустые скобки вслед за именем, назначенным процедуре.

Правило записи процедуры-подпрограммы следующее:

Sub ИмяПодпрограммы (СписокФормальныхПараметров)

КодПодпрограммы

End Sub

В списке параметров перечисляются через запятую описания аргументов, передаваемых подпрограмме. Для каждого параметра указывается его имя (обязательно), способ передачи в подпрограмму, тип, а также является ли аргумент обязательным при вызове и следует ли упаковывать следующие аргументы в массив. Используемые в описании списка формальных параметров ключевые слова и их назначение описаны выше. Далее будут приведены примеры описаний подпрограмм. Перед ключевым словом Sub могут быть указаны ключевые слова Public Private, Static.

Чтобы вызвать процедуру-подпрограмму из другой процедуры, следует указать имя этой процедуры и значения для всех требуемых аргументов. Использование инструкции Call не обязательно, однако если она все же используется, аргументы должны быть заключены в скобки.

Выйти из подпрограммы можно «досрочно», не через конец, с помощью инструкции Exit Sub.

В следующем примере инструкция Sub (с парной ей инструкцией End Sub) описывает процедуру с именем ApplyFormat. Все инструкции, заключенные между Sub и End Sub выполняются всегда, когда вызывается или выполняется процедура ApplyFormat:

Sub ApplyFormat()

Const Limit As Integer = 33

Dim MyCell As Range

' Другие инструкции …

End Sub

В описанную выше процедуру при обращении к ней не передаются при вызове параметры.

В следующем примере процедура Main вызывает процедуру MultiBeep, передавая значение 56 для ее аргумента. По окончании работы MultiBeep управление возвращается к Main, и Main вызывает процедуру Message. Message показывает окно сообщения, когда пользователь выбирает мышью OK, управление возвращается к Main, и Main завершается.

Sub Main()

MultiBeep 56

Message

End Sub

Sub MultiBeep(numbeeps)

For counter = 1 To numbeeps

Beep Передача звукового сигнала через динамик

Next counter

End Sub

Sub Message()

MsgBox “Пора сделать перерыв!”

End Sub

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

Для передачи аргументов в процедуру может использоваться массив параметров. При описании процедуры не требуется указывать число элементов такого массива.

Для обозначения массива параметров используется ключевое слово ParamArray. Такой массив описывается как массив типа Variant и всегда представляет последние элементы из списка аргументов в описании процедуры. Этот способ передачи параметров может использоваться, когда может изменяться количество передаваемых в процедуру параметров. Ниже приводится пример описания процедуры с массивом параметров:

Sub AnyNumberArgs (strName As String, _ ParamArray intScores() As Variant)

Dim intI As Integer

Debug.Print strName; “ Дети:”

For intI = 0 To UBound(intScores())

Debug.Print " "; intScores(intI)

Next intI

End Sub

В следующих строках приведены примеры вызова этой процедуры с различным числом аргументов:

AnyNumberArgs “Иванов И.И.”, “Саша”, “Даша”

AnyNumberArgs “Петрова П.П.”, “Ася”, “Петя”, “Вася”, “Коля”

При вызове процедур Sub или Function возможна позиционная передача аргументов, т.е. в порядке следования в описании процедуры. Кроме того, аргументы могут передаваться по именам, вне зависимости от позиции. Именованный аргумент состоит из имени соответствующего формального параметра, за которым следует двоеточие со знаком равенства (:=) и значение передаваемого фактического параметра.

Именованные аргументы особенно полезны при вызове процедуры с необязательными аргументами (Optional). Если используются именованные аргументы, то запятые для обозначения отсутствующих параметров не нужны. С помощью именованных аргументов проще проследить, какие аргументы переданы, а какие опущены.

В описании процедуры перед необязательными аргументами должно стоять ключевое слово Optional. Кроме того, в описании процедуры можно присвоить значение необязательному аргументу, которое он принимает по умолчанию. Если при вызове процедуры с аргументом Optional этот аргумент не описан, то для него используется имеющееся значение по умолчанию. Если по умолчанию значение не присвоено, аргумент обрабатывается так же, как любая другая переменная указанного типа.

В следующей процедуре имеются необязательные параметры. Функция IsMissing определяет, были ли переданы в процедуру необязательные аргументы.

Sub OptionalArgs (strState As String, _ Optional intRegion As Integer, _

Optional strCountry As String = “USA”)

If IsMissing(intRegion) And IsMissing(strCountry) Then

Debug.Print strState

ElseIf IsMissing(strCountry) Then

Debug.Print strState, intRegion

ElseIf IsMissing(intRegion) Then

Debug.Print strState, strCountry

Else

Debug.Print strState, intRegion, strCountry

End If

End Sub

В эту процедуру можно передать, например, именованные аргументы:

OptionalArgs strCountry:=”USA”, strState:=”MD”

OptionalArgs strState:= “MD”, intRegion:=5

При передаче аргументов по занимаемой ими позиции на месте пропущенных параметров ставится обозначающая их позицию запятая.