Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VBA For Excel Часть 01.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
1.16 Mб
Скачать

3.3.1 Изменение вида входного параметра при вызове подпрограммы

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

Пример:

‘Принудительный запрет ссылки от входного параметра для переменных A и С в функции

A1 = ИмяФункции( (А), B, (С) )

‘Принудительный запрет ссылки от входного параметра для переменных A и С в процедуре

ИмяПроцедуры (А), B, (С)

Указанный нами способ смены вида входного параметра при вызове подпрограммы применяют, например, в том случаи, если возникает конфликт типов входного параметра и переменной задающей ему значение. Или если не хотят получать значение от входного параметра объявленного как ByRef.

3.4 Описание событийной процедуры объекта

Событийная процедура не отличается по идеологии от обычной процедуры, но она, в отличии от обычной процедуры, выполнятся во время определенного события происходящего с объектом, формат ее описания следующий:

PRIVATE SUB ИМЯОбъекта_ИмяСобытия ( [ Входные параметры процедуры ] )

Тело процедуры

.

.

[Exit Sub]

.

.

END SUB

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

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

3.5 Рекурсивные подпрограммы (процедуры и функции)

Возможна рекурсия подпрограммы (процедуры или функции). Рекурсия подпрограммы происходит тогда, когда подпрограмма вызывает выполнение самой себя. Классическим примером рекурсии является функция вычисляющая факториал числа n (n!). Аргументом функции факториал может быть целое число большее или равное 0. Формула факториала следующая:

Пример вычисления факториала чисел 0,1,2,3 :

0! =1

1! =1

2! = 2 * 1 = 2

3! = 3 * 2 * 1 = 6

Для вычисления факториала в VBA применим следующую рекурсивную функцию:

Function fact(ByVal n As Byte) As Double

If n <= 2 Then

fact = n

Else

fact = fact(n - 1) * n

End If

End Function

Иногда, в данном примере, в операторе If устанавливают другое условие выполнения ( n <= 1), но это излишни, поскольку n*1 = n.

При вычислении факториала числа 3 указанной нами функции, с начало, переменная n будет равна 3 и произойдет первый рекурсивный запуск функции fact. При этом, значение переменой n=3 будет помещено в специальную область памяти, называемую стек. А переменная n примет значение n=2, после того, как функция fact будет вызвана снова. При n=2, как видно из программы, функция fact примет значение переменной n, т.е. fact = 2. Затем, будет вычислено произведение функции со всеми значениями переменной n находящимися в стеке. Т.е. значение функции fact станет fact = fact * 3 = 2 * 3 =6. В стек может помещаться несколько значений переменной, поэтому данной функцией можно вычислить факториал чисел 4, 5 и т.д.

Возможно переполнения стека. Но в нашем примере таково не произойдет, потому, что раньше произойдет переполнения разрядной сетки для типа функции Double. Не целый, числовой тип функции fact задан нами не случайно, если бы мы использовали тип Long, то данной функцией можно было бы вычислить факториал до числа 12, при использовании типа Double можно вычислить факториал до числа 170. Переполнение стека часто возникает из-за неправильно составленной программы. Возможна ситуация при которой процедура или функция будет вызывать себя постоянно, что вызовет переполнения стека. Например, если запустить процедуру, указанную нами ниже, то произойдет ошибка “недостаточно стековой памяти”, из-за того, что в стеке будет содержаться слишком много вызовов процедуры NN.

Sub NN()

NN

End Sub

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

Function SA( ParamArray V())

Dim n , D as long

SA = 1

D = 0

For Each n In V

SA = SA * n

D = D +1

Next n

SA = SA / D

End Function

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]