Функции, определённые пользователем
Функция, определённая пользователем, называемая также процедурой-функцией, – это особый вид процедуры VBA, возвращающей результат. Пользовательские процедуры-функции, как и встроенные функции VBA, могут иметь необязательные и именованные аргументы. Для записи процедуры-функции нельзя использовать макрорекордер, хотя можно редактировать записанный рекордером макрос и превращать его в процедуру-функцию.
Формат процедуры-функции:
Function Name([Arglist]) [As Type]
‘ VBA Statements
[Name = expression]
End Function
Function – ключевое слово, объявляющее начало функции.
Name – имя функции. Имена функций следуют тем же правилам, что и имена других идентификаторов VBA.
Arglist – список аргументов данной функции, необязательный элемент.
Type – любой тип возвращаемого значения функции. Если тип не определен, результат, который возвращает функция-процедура, имеет тип Variant.
Name = expression – присваивание функции выражения, значение которого возвращает функция, необязательный элемент. Тем не менее, всегда следует включать оператор присваивания в функции-процедуры.
End Function – ключевые слова, заканчивающие функцию.
Даже если функция не имеет аргументов (например, Now, Date) в объявлении функции необходимо использовать круглые скобки.
Основное различие между процедурой-функцией и другими процедурами, помимо того, что функции возвращают значение, а процедуры - нет, состоит в том, что в процедуре-функции используются ключевые слова Function и End Function.
Обычно функция предназначается для выполнения вычисления и для возвращения результата. При объявлении функции-процедуры указывается имя каждого аргумента, передаваемого функции. Имена аргументов в списке Arglist отделяются друг от друга запятой и должны следовать правилам, применяемым к любому идентификатору VBA.
Ниже приведён пример, в котором используется пользовательская функция, вычисляющая сумму комиссионных. Суть задачи состоит в следующем. В таблице Excel, приведённой ниже, требуется подсчитать суммы комиссионных и оплаты.
Суммы комиссионных подсчитываются в процедуре-функции Комиссионные, обращение к которой осуществляется в процедуре Расчёт_Комиссионных, при помощи инструкции
Cells(i, 3) = Комиссионные(Cells(i, 2)),
параметром которой, является сумма продаж, находящаяся в ячейках Excel B3÷B6 (Cells(3, 2) – это ячейка B3 и т.д.).
Подсчёт оплаты выполняется при помощи инструкции
Cells(i, 4) = Cells(i, 2) + Cells(i, 3)
в процедуре Расчёт_Комиссионных.
Sub Расчёт_Комиссионных()
Sheets("Лист1").Select
Dim i As Integer
i = 3
Do While Cells(i, 1) <> ""
Cells(i, 3) = Комиссионные(Cells(i, 2))
Cells(i, 4) = Cells(i, 2) + Cells(i, 3) ‘ Оплата
i = i + 1
Loop
End Sub
Function Комиссионные(Продажи As Double) As Double
Dim РасчётКом As Double, Надбавка As Double
РасчётКом = Продажи * 0.05
If Продажи > 5000 Then
Надбавка = 0.01 * (Продажи - 5000)
РасчётКом = РасчётКом + Надбавка
End If
If Продажи > 10000 Then
Надбавка = 0.02 * (Продажи - 10000)
РасчётКом = РасчётКом + Надбавка
End If
If Продажи > 15000 Then
Надбавка = 0.03 * (Продажи - 15000)
РасчётКом = РасчётКом + Надбавка
End If
Комиссионные = РасчётКом
End Function
VBA передает все аргументы в процедуру-функцию как типы Variant. Можно объявлять определенные типы данных для каждого аргумента в списке аргументов. Определение типов аргументов для процедуры-функции помогает пользователю при вызове функции вводить аргументы правильного типа в правильном порядке.
Упражнение 2
1. На листе Excel Лист1 создайте таблицу «Суммы комиссионных», представленную выше, подсчитайте суммы комиссионных и оплаты, выполнив процедуру Расчёт_Комиссионных, которая вызывает на выполнение процедуру-функцию Комиссионные. Проанализируйте результат.
2. Скопируйте Лист1, введите наименование нового листа Новый. Удалите с него подсчитанные суммы комиссионных и оплаты. Дополните произвольными исходными данными столбцы Компания и Продажи.
3. Выполните процедуру Расчёт_Комиссионных. В процедуре не забудьте изменить имя активного листа.
4. Создайте макрос, форматирующий таблицу таким образом, чтобы она выглядела так, как показано ниже. Назовите макрос Формат, проверьте его работу и отладьте в случае необходимости.
5. Вставьте вызов макроса перед инструкцией End Sub в процедуру Расчёт_Комиссионных.
6. Повторите пункты 2 и 3 с той лишь разницей, что копировать Лист1 нужно на другой новый лист, а дополнять таблицу нужно тем же количеством записей (можно их скопировать с листа Новый).
7. Составить пользовательскую функцию Комиссионные_2, в которой вместо инструкции If…Then использовать инструкцию Select Case. Из процедуры Расчёт_Комиссионных нужно обращаться к функции Комиссионные_2. Для проверки результата использовать новый лист с теми же исходными данными, что на листе Новый. Запустить процедуру Расчёт_Комиссионных на выполнение и отладить в случае необходимости.