В VВА возможно создание рекурсивных процедур, т. е. процедур, вызываюх самих себя. Стандартным примером рекурсивной процедуры является процедура вычисления факториала, т. е. функции, возвращающей результат произведения первых n натуральных чисел, где n — аргумент функции. Для этой функции имеется стандартное обозначение: Fact(n)=n!, где Fact (0) = 1. Ясно, что
Fact (n) = n Fact (n - 1)
Основываясь на данном соотношении, приводимая ниже рекурсивная функция вычисляет значение факториала.
Function Fact(n As Integer) As Integer
If n<l Then
Fact = 1
Else
Fact = Fact (n - 1) n End If End Function
Другим стандартным примером применения рекурсивных функций является нахождение наибольшего общего делителя двух целых чисел по алгоритму Евклида. Наибольший общий делитель (НОД) двух целых чисел — это наибольшее целое, на которое делятся оба числа. Например, НОД (10, 14) = 2 и НОД (15, 31) = 1.
Алгоритм Евклида состоит в следующем:
1. Если а делится на b, то НОД(а, b) = b
2. В противном случае — НОД(а, b) = НОД(b, a Mod b)
Приводимая ниже рекурсивная функция программирует алгоритм Евклида.
Function НОД(Целое1 As Long, Целое2 As Long) As Long
If Целое2 Mod Целое1 = О Then
НОД = Целое1
Else
НОД = НОД(Целое2, Целое! Mod Целое2)
End If
End Function
Несмотря на элегантность рекурсивных процедур, применять их надо с осторожностью,
т. к. неаккуратное использование может привести к проблемам с памятью — многократный вызов такой процедуры быстро исчерпывает стековую память.
Область определения переменной задает область, в которой может быть ис пользована переменная. В VBA имеется три соответствующих уровня переменных:
1 Переменные уровня процедуры используются только в процедуре, в которой они описаны при помощи инструкции Dim, размещенной в процедуре.
2 Переменные уровня модуля используются только в модуле, в котором они описаны при помощи инструкции Dim, размещенной в области описания модуля, т. е. перед описанием процедур.
3 Общие переменные, используемые во всех модулях данного проекта. Описываются при помощи инструкции Public, размещенной в области описания модуля.
Личная (Private) переменная сохраняет свое значение только пока выполняется процедура, в которой эта переменная описана. При завершении процедуры значение переменной теряется, и при повторном запуске процедуры его надо заново инициализировать. Переменные, описанные при помощи инструкции Static, сохраняют свое значение по выходу из процедуры, но пока работает программа.