В Excel более 450 функций, и некоторые из них весьма полезны в вашей повседневной работе.
Но… Excel дает вам возможность создавать пользовательские функции с помощью VBA.
Да — да, вы не ослышались. Пользовательская функция.
И я могу сказать со 100%-ой уверенностью, что каждый начинающий пользователь VBA хочет научиться создавать пользовательские функции. Не так ли? Кивните, если вы один из них.
Итак, сегодня я собираюсь поделиться всем, что вам нужно знать о создании Пользовательской функции.
… так что оставайтесь со мной, вы станете рок-звездой VBA в ближайшие пару минут.
- Зачем вам создавать пользовательскую функцию Excel?
- Как создать свою первую пользовательскую функцию в Excel
- Как эта функция работает и возвращает значение в ячейке
- Как улучшить пользовательскую функцию?
- Как использовать пользовательскую функцию VBA
- Различные способы создания пользовательской функции VBA
- Область действия определяемой пользователем функции
- Ограничения пользовательской функции
- Заключение
Зачем вам создавать пользовательскую функцию Excel?
Как я уже сказал, в Excel много функций, которые могут помочь вам решить практически все проблемы и выполнить все виды расчетов. Но…
… Иногда в определенных ситуациях вам нужно создать пользовательскую.
Вот некоторые причины, почему вам нужно перейти к пользовательской функции.
1. Когда нет подходящей функции
Иногда бывает, что вам нужно что-то вычислить, и для этого нет подходящей встроенной функции.
Например, подсчет слов в ячейке, в этом случае пользовательская функция — идеальное решение.
Function MyWordCount(rng As Range) As Integer
MyWordCount = UBound(Split(rng.Value, " "), 1) + 1
End Function
2. Заменить сложную формулу
Если вы работаете с формулами, то вы знаете, что сложные формулы бывает трудно читать самому, а другим пользователем еще сложнее.
Пользовательская функция может решить эту проблему.
Такая функция поможет вам избежать долгих вычислений. Как только вы создадите функцию, вам не нужно будет писать эту сложную формулу снова и снова.
3. Когда вы не хотите использовать SUB
Хотя вы можете использовать код VBA для выполнения расчетов, но коды VBA не динамические.
Вам нужно снова запустить этот код, если вы хотите обновить свой расчет.
Но если вы преобразуете этот код в функцию, вам не нужно будет запускать этот код снова и снова.
Как создать свою первую пользовательскую функцию в Excel
Обычно для создания функции VBA необходимо выполнить следующие шаги:
- Объявить вашу процедуру как функцию
- Определить ее аргументы и их тип данных
- Добавить код для расчета желаемого значения
Позвольте мне привести вам простой пример.
Вам необходимо создать функцию, которая может возвращать название дня недели из значения даты.
Да, у нас есть функция, которая возвращает номер дня недели, но не название.
Итак, давайте создадим эту функцию VBA, используя следующие шаги.
- Прежде всего, откройте редактор VB с помощью сочетания клавиш ALT + F11 или перейдите на вкладку «Разработчик» и нажмите кнопку «Visual Basic».
- Вставка модуля: щелкните правой кнопкой мыши в окне проекта VBA, затем перейдите к Insert и после этого нажмите «Module».
- Следующим шагом является определение имени для функции, здесь я использую «myDayName». Поэтому вы должны написать «Function mydayName».
Почему «Function» перед именем?
Поскольку вы создаете функцию VBA, то используете слово «Function». Excel понимает, что этот код следует рассматривать как функцию
- После этого вам нужно определить аргументы для пользовательской функции. Поэтому вставьте начальные скобки и напишите «InputDate As Date».
- Здесь InputDate — имя аргумента, а date — его тип данных. Всегда лучше определить тип данных для аргумента.
- Теперь закройте скобки и напишите «As String». Здесь вы определяете тип данных результата, возвращаемого функцией. Так как вы хотите, чтобы название дня недели было текстовым, его тип данных должен быть «String».
- В конце нажмите ENTER.
На этом этапе имя вашей функции, ее аргумент, тип данных аргумента и тип данных функции определены, и у вы должны видеть что-то вроде этого в вашем модуле:
Теперь между «Function» и «End Function» вам нужно сделать расчет.
В Excel есть функция рабочего листа под названием «Text», давайте используем ее здесь. Для этого вам нужно написать следующий код:
myDayName = WorksheetFunction.Text (InputDate, "dddddd")
С помощью этого кода вы определяете значение, которое должно быть возвращено функцией.
- Теперь закройте редактор VB и вернитесь к рабочему листу.
- В ячейке B2 введите «= myDayName (A2)», нажмите Enter, и у вы увидите название дня недели.
Поздравляю! Вы только что создали свою первую пользовательскую функцию!
Как эта функция работает и возвращает значение в ячейке
Вы создали свою первую пользовательскую функцию, но дело в том, что нужно еще понять, как она работает.
Можно сказать в двух словах, это код VBA, но мы используем его как функцию. Давайте разбираться.
- Вы вводите код в ячейку как функцию и указываете ссылку на ячейку
- Excel запускает код функции и использует значение, которое вы указали
- Вы получаете результат в ячейке
А теперь детали: в тот момент, когда вы вводите код в ячейку и ссылаясь на другую, код выполняется, используя указанное вами значение для возврата результата.
Давайте чуть медленнее:
Есть код для функции, которую мы создали, и вы знаете, что в этом коде. Правильно?
Когда вы ссылаетесь на ячейку в вашей функции, этот блок кода работает для вычисления значения. Он берет дату из аргумента InputDate и возвращает название дня недели.
Важно: когда вы пишете код для пользовательской функции, вам нужно позаботиться о том, чтобы значение, возвращаемое этим кодом, было присвоено имени функции.
Как улучшить пользовательскую функцию?
Вы уже знаете, как создать пользовательскую функцию VBA. Но…
Есть одна вещь, о которой вы должны позаботиться: код, который вы используете должен быть достаточно хорош, чтобы использовать все возможности.
Если говорить о функции, которую вы только что написали выше, да вы можете вернуть название дня недели из даты. Но… Что если указанное вами значение не будет датой? А если указанная вами ячейка пуста?
Могут быть и другие проблемы, но я уверен, что вы поняли, о чем я.
Итак, давайте попробуем улучшить эту пользовательскую функцию, чтобы она смогла справиться с вышеуказанными проблемами.
Прежде всего, вам нужно изменить тип данных аргумента и использовать:
InputDate As Variant
Так ваша пользовательская функция сможет принимать любой тип данных в качестве входных данных.
Далее нам нужно использовать оператор VBA IF, чтобы проверить InputDate для некоторых условий. Первое условие — пустая ячейка или нет. И для этого вам нужно использовать следующий код:
If InputDate = "" Then
myDayName = ""
Функция ничего не будет возвращать, если указанная вами ячейка будет пустой. Одна проблема решена, давайте перейдем к следующей.
Помимо даты есть возможности, что значение может быть числом или текстом. Поэтому необходимо создать условие, которое будет проверять, является ли указанное значение действительной датой или нет. Код такой:
If IsDate (InputDate) = False Then
myDateName = ""
Примечание. Здесь я использую пробел для обоих условий, чтобы при наличии больших данных можно было легко отфильтровать значения, если входное значение недопустимо.
Таким образом, после добавления вышеуказанных условий код будет выглядеть так:
Функция myDayName (InputDate As Variant) в виде строки
Function myDayName(InputDate As Variant) As String
If InputDate = "" Then
myDayName = ""
Else
If IsDate(InputDate) = False Then
myDateName = ""
Else
myDayName = WorksheetFunction.Text(InputDate, "dddddd")
End If
End If
End Function
Я думаю, что вы можно внести еще некоторые изменения в эту функцию, но я уверен, что суть вы уловили.
Как использовать пользовательскую функцию VBA
Научившись создавать функцию VBA в Excel, нужно узнать, как вы можете ее использовать. И в этой части статьи я расскажу вам, как и где вы можете это делать.
Итак, давайте начнем.
1. На рабочем листе
Почему мы создаем пользовательскую функцию? Чтобы использовать ее на рабочем листе. Вы можете просто использовать ПФ на листе, используя знак равенства и введя имя функции, а затем указав ее аргументы.
Вы также можете ввести пользовательскую функцию из библиотеки функций.
Перейдите на вкладку «Формулы» ➜ «Вставить функцию» ➜ «Определенные пользователем».
Из списка можно выбрать функцию, которую хотите вставить.
2. Использование в других подпроцедурах и функциях
Вы также можете использовать функцию в других функциях или в процедуре «Sub».
Ниже приведен код VBA, в котором мы использовали функцию, чтобы получить название дня недели для текущей даты.
Sub todayDay()
MsgBox "Сегодня " & myDayName(Date)
End Sub
3. Доступ к функциям из другой книги
Если у вас есть ПФF в одной рабочей книге и вы хотите использовать его в другой или во всех рабочих книгах, вы делаете это путем создания надстройки для нее. Выполните следующие простые шаги:
- Прежде всего, вам нужно сохранить файл (в котором у вас есть код пользовательской функции) в виде надстройки.
- Для этого перейдите на вкладку «Файл» ➜ «Сохранить как» ➜ «Надстройки Excel (.xalm)».
- После этого дважды щелкните на надстройку и установите ее.
- нажмите добавить, чтобы добавить все определенные пользователем функции в другую книгу
Теперь вы можете использовать все свои функции VBA в любой книге.
Различные способы создания пользовательской функции VBA
Когда мы используем встроенные функции, они имеют разные типы аргументов. В этом разделе руководства вы узнаете, как создать ПФ с аргументами другого типа.
- без каких-либо аргументов
- только с одним аргументом
- с несколькими аргументами
- использование массива в качестве аргумента
1. Без каких-либо аргументов
Помните есть такие функции, как СЕЙЧАС и СЕГОДНЯ, в которых вам не нужно вводить какие-либо аргументы? Вы можете создать пользовательскую функцию, в которой вам тоже не нужно вводить аргумент. Сделаем это на примере:
Давайте создадим пользовательскую функцию, которая может возвращать местоположение текущего файла.
Вот код:
Function myPath() As String
Dim myLocation As String
Dim myName As String
myLocation = ActiveWorkbook.FullName
myName = ActiveWorkbook.Name
If myLocation = myName Then
myPath = "Файл еще не сохранен."
Else
myPath = myLocation
End If
End Function
Эта функция возвращает путь к месту, где хранится текущий файл, и, если рабочая книга нигде не сохранена, будет отображаться сообщение «Файл еще не сохранен».
Теперь, если вы обратите пристальное внимание на код этой функции, вы не увидите ни одного аргумента (в скобках). Вы определяете тип данных для результата функции. Основное правило создания функции без аргументов — это код, в который вам не нужно ничего вводить. Проще говоря, значение, которое вы хотите получить взамен функции, должно вычисляться автоматически.
Этот код «ActiveWorkbook.FullName» возвращает местоположение файла, а этот «ActiveWorkbook.Name» возвращает имя. Так что здесь вам не нужно ничего вводить.
2. Только с одним аргументом
Мы уже рассмотрели эту ситуацию, изучая, как создать пользовательскую функцию. Но давайте копнем немного глубже и создадим другую функцию.
Это функция нужна для извлечения URL-адреса из гиперссылки.
Function giveMeURL(rng As Range) As String
On Error Resume Next
giveMeURL = rng.Hyperlinks(1).Address
End Function
В этой функции у вас есть только один аргумент.
Когда вы напишите функцию, а затем укажите ячейку, в которой у вас есть гиперссылка, она вернет URL-адрес.
Теперь в этой функции основная работа выполняется:
rng.Hyperlinks (1) .Address
rng - это то, что вам нужно указать.
3. С несколькими аргументами
Обычно большинство встроенных функций Excel имеют несколько аргументов. Поэтому вам необходимо узнать, как создать пользовательскую функцию с несколькими аргументами. Давайте рассмотрим пример:
Вы хотите удалить определенные буквы из текстовой строки и получить оставшуюся часть. У вас есть такие функции, как RIGHT и LEN, которые вы собираетесь использовать в этой пользовательской функции. Но здесь они нам не понадобятся. Все, что нам нужно, это пользовательская функция, использующая VBA.
Итак, вот функция:
Function removeFirstC(rng As String, cnt As Long) As String
removeFirstC = Right(rng, Len(rng) - cnt)
End Function
Итак, посмотрим:
В этой функции у вас два аргумента:
- rng: в этом аргументе вам нужно указать ячейку, из которой вы хотите удалить символ текста.
- cnt: а в этом аргументе вам нужно указать количество символов для удаления (если вы хотите удалить более одного символа из текста).
Когда вы вводите ее в ячейку, она работает примерно так:
3.1 Создание пользовательской функции с необязательным и обязательным аргументом
Если говорить о функции, которую мы только что создали в приведенном выше примере, где у нас было два разных аргумента, то они оба обязательны. Если вы пропустите любой из них, вы получите такую ошибку.
Но можно сделать этот аргумент необязательным, чтобы он принимал значение по умолчанию. Чтобы сделать аргумент необязательным, вам просто нужно добавить «Optional» перед ним.
4. Использование массива в качестве аргумента
Есть несколько встроенных функций, которые могут принимать аргументы в виде массива, также вы можете сделать свою собственную функцию VBA. Давайте рассмотрим простой пример: вам нужно создать функцию, в которой вы суммируете значения из диапазона, в котором у вас есть числа и текст.
Function addNumbers(CellRef As Range)
Dim Cell As Range
For Each Cell In CellRef
If IsNumeric(Cell.Value) = True Then
Result = Result + Cell.Value
End If
Next Cell
addNumbers = Result
End Function
В приведенном выше коде функции мы использовали весь диапазон A1: A10 вместо одного значения или ссылки на ячейку.
Используем цикл FOR EACH, он проверяет каждую ячейку диапазона и суммирует значение, если в ячейке есть число.
Область действия определяемой пользователем функции
Проще говоря, область действия функции означает, может ли она вызываться из других процедур или нет. UDF может иметь два разных типа областей действия:
1. Public
Вы можете сделать свою пользовательскую функцию общедоступной, чтобы ее можно было вызывать во всех рабочих листах рабочей книги. Для этого вам просто нужно использовать слово «Public», как показано ниже.
Функция является Public по умолчанию, если вы не делаете ее Private. Во всех приведенных нами примерах все функции общедоступны.
2. Private
Когда вы делаете функцию Private, вы можете использовать ее в процедурах того же модуля.
Допустим, если у вас есть функция в «Module1», вы можете использовать ее только в процедурах, которые вы используете в «Module1». И она не появится в списке функций на рабочем листе (когда вы используете знак = и пытаетесь ввести имя), но вы все равно можете использовать ее, введя ее название полностью и указав аргументы.
Ограничения пользовательской функции
Пользовательские функции супер полезны. Но они ограничены в некоторых ситуациях. Вот несколько вещей, которые нужно записать и запомнить при создании пользовательской функции в VBA:
- Вы не можете изменять, удалять или форматировать ячейки и диапазон с помощью пользовательской функции.
- Также нельзя перемещать, переименовывать, удалять или добавлять рабочие листы в рабочую книгу.
- Не сможете вносить изменения в значение другой ячейки.
Есть ли разница между встроенной функцией и пользовательской функцией?
Чтобы ответить на этот вопрос, я хочу поделиться некоторыми моментами, которые, на мой взгляд, важны.
- Медленнее, чем встроенная. Если вы сравните скорость встроенных функций и функции VBA, вы обнаружите, что первые быстрее. Причина в том, что встроенные функции написаны с использованием C ++ или FORTRAN.
- Трудно обмениваться файлами. Мы часто обмениваемся файлами по электронной почте и в облаке, поэтому, если вы используете какую-либо из пользовательских функций, вам необходимо поделиться этим файлом в формате «xlam», чтобы другой человек также мог использовать вашу пользовательскую функцию.
Но все равно, есть ситуации, когда пользовательские функции будут незаменимы.
Заключение
Создать пользовательскую функцию просто.
Все, что вам нужно сделать, это использовать «Function» перед названием, чтобы определить его как функцию, добавить аргументы, определить тип данных аргументов, а затем определить тип данных для возвращаемого значения.
В конце добавьте код, чтобы вычислить значение, которое вы хотите получить от функции.
Это самое простое руководство, как создать пользовательскую функцию в VBA, и я надеюсь, вы нашли ее полезной.