Стандартный набор функций Microsoft Excel покрывает 90% задач пользователей, но иногда требуется что-то уникальное: расчёт сложных процентов по нестандартной формуле, обработка текста с учётом специфических правил или интеграция с внешними данными. В таких случаях на помощь приходят пользовательские функции — инструмент, который позволяет расширить возможности программы под свои нужды.
Создать собственную функцию в Excel можно несколькими способами: через встроенный редактор VBA (для настольной версии), с помощью Office Scripts (для Excel Online) или используя Power Query для трансформации данных. Каждый метод имеет свои нюансы: VBA требует базовых знаний программирования, но даёт максимальную гибкость; Office Scripts проще в освоении, но работает только в облаке; Power Query идеален для работы с большими массивами данных. Выбор зависит от вашей версии Excel, задач и уровня подготовки.
В этой статье мы разберём все три метода с практическими примерами, предостережём от типичных ошибок и покажем, как оптимизировать пользовательские функции для ускорения работы таблиц. А если вы никогда не писали код — не беспокойтесь: мы начнём с азов и постепенно перейдём к более сложным приёмам.
1. Создание функции через VBA: классический способ
Редактор Visual Basic for Applications (VBA) — самый универсальный инструмент для добавления пользовательских функций в настольные версии Excel (2010–2026). Функции, написанные на VBA, становятся доступны в таблице как стандартные формулы (например, =МОЯФУНКЦИЯ(A1)) и могут использоваться в любых ячейках.
Чтобы начать, откройте редактор VBA сочетанием клавиш Alt + F11 (или через меню Разработчик → Visual Basic). Если вкладки Разработчик нет, включите её в настройках: Файл → Параметры → Настройка ленты. В редакторе выберите Insert → Module, и перед вами откроется чистый лист для кода.
Синтаксис пользовательской функции минималистичен:
Function ИМЯ_ФУНКЦИИ(аргумент1 As Тип, аргумент2 As Тип) As Тип_результата
' Логика функции
ИМЯ_ФУНКЦИИ = результат
End Function
Например, функция для расчёта НДС 20% с учётом округления до копеек будет выглядеть так:
Function НДС20(Сумма As Double) As Double
НДС20 = Round(Сумма * 0.2, 2)
End Function
После ввода кода закройте редактор — функция сразу появится в списке автозаполнения. Теперь в любой ячейке можно написать =НДС20(A1), и Excel рассчитает налог автоматически.
⚠️ Внимание: Функции VBA не работают в Excel Online и мобильных версиях. Также они могут блокироваться макросами безопасности — перед использованием проверьте настройки в Файл → Параметры → Центр управления безопасностью.
- 📌 Плюсы VBA: максимальная гибкость, поддержка сложных вычислений, работа с диапазонами ячеек.
- ⚠️ Минусы: требует базовых знаний программирования, не кросс-платформенный, может замедлять большие файлы.
- 🔄 Альтернатива: для облачных версий используйте Office Scripts (см. следующий раздел).
2. Office Scripts: функции для Excel Online
Office Scripts — это современная замена VBA для веб-версии Excel. Скрипты пишутся на TypeScript (упрощённая версия JavaScript) и позволяют автоматизировать задачи прямо в браузере. В отличие от VBA, функции Office Scripts сохраняются в файле и доступны только в нём.
Чтобы создать скрипт, откройте Excel Online, перейдите на вкладку Автоматизация и выберите Новый скрипт. В редакторе введите код функции. Например, вот скрипт для извлечения домена из email:
function main(workbook: ExcelScript.Workbook, email: string) {
let domain = email.split('@')[1];
return domain;
}
Чтобы использовать эту функцию в таблице, вернитесь на лист, выделите ячейку и в строке формул введите =OFFSCRIPT("ИмяСкрипта", A1), где A1 — ячейка с email. Office Scripts поддерживает работу с диапазонами, циклами и даже API, но имеет ограничения: например, нельзя создавать модальные окна, как в VBA.
| Критерий | VBA | Office Scripts |
|---|---|---|
| Поддержка версий | Excel 2010–2026 (Windows/Mac) | Только Excel Online |
| Язык программирования | Visual Basic | TypeScript (JavaScript) |
| Работа с диапазонами | Да, полная поддержка | Да, но медленнее |
| Интеграция с API | Ограниченно | Да, через fetch |
⚠️ Внимание: Скрипты Office Scripts выполняются в облаке Microsoft, поэтому чувствительные данные (пароли, финансовая информация) лучше обрабатывать локально через VBA или Power Query.
3. Power Query: функции для трансформации данных
Power Query (или Get & Transform в новых версиях Excel) — это инструмент для импорта, очистки и преобразования данных. Здесь тоже можно создавать пользовательские функции, но они предназначены не для ячеек, а для этапов обработки данных в редакторе запросов.
Чтобы создать функцию в Power Query:
- Перейдите на вкладку
Данныеи выберитеПолучить данные → Другие источники → Пустой запрос. - В редакторе запросов нажмите
Дополнительно → Добавить функцию. - Введите код на языке M (пример ниже).
- Сохраните и используйте функцию в других запросах.
Пример функции для приведения текста к заглавному регистру (каждое слово с большой буквы):
(text as text) as text =>
let
SplitText = Text.Split(text, " "),
CapitalizeEach = List.Transform(SplitText, each Text.Proper(_)),
CombineText = Text.Combine(CapitalizeEach, " ")
in
CombineText
Эту функцию можно применить к столбцу с данными через меню Добавить столбец → Вызвать функцию. Power Query идеален для обработки больших массивов: например, вы можете написать функцию для парсинга JSON, очистки адресов или расчёта сложных метрик по продажам.
- 🔍 Где использовать: очистка данных, ETL-процессы, подготовка отчётов.
- ❌ Не подходит для: динамических расчётов в ячейках (как в VBA).
- ⚡ Преимущество: функции работают одинаково в Excel и Power BI.
Как ускорить работу функций в Power Query?
1. Избегайте вложенных циклов — используйте List.Generate или Table.ExpandListColumn.
2. Преобразуйте данные в бинарный формат (BinaryFormat.Text) для ускорения загрузки.
3. Отключите фоновую загрузку в настройках запроса, если работаете с большими файлами.
4. Отладка и оптимизация пользовательских функций
Даже простая функция может тормозить Excel, если она неправильно написана или используется в большом диапазоне. Вот ключевые правила оптимизации:
- Минимизируйте обращения к ячейкам. Каждое чтение данных из листа (
Range("A1").Value) замедляет выполнение. Лучше передавать значения как аргументы функции. - Используйте массивы. В VBA обрабатывайте диапазоны как массивы:
Function SumArray(rng As Range) As DoubleDim arr() As Variant, i As Long
arr = rng.Value ' Загружаем данные в массив
For i = LBound(arr) To UBound(arr)
SumArray = SumArray + arr(i, 1)
Next i
End Function
- Отключайте автоматический пересчёт. Для сложных функций используйте:
Application.Calculation = xlManual' ... ваш код ...
Application.Calculation = xlAutomatic
Для отладки в VBA используйте:
- 🐞
Debug.Print— выводит значения в окноImmediate(открывается черезCtrl + G). - 🛠
F8— пошаговое выполнение кода. - 📊
Watch— отслеживание переменных (добавляется через правый клик на переменной).
⚠️ Внимание: Функции VBA, которые изменяют другие ячейки (например, записывают данные вRange("B1")), могут вызывать циклические ссылки и крах Excel. Всегда возвращайте результат через имя функции (ИМЯ_ФУНКЦИИ = результат).
Отключен ли автоматический пересчёт (если функция сложная)?|Проверены ли граничные значения (ноль, пустые ячейки, текст)?|Есть ли обработка ошибок (On Error Resume Next)?|Функция возвращает ожидаемый тип данных?
-->
5. Примеры полезных пользовательских функций
Вот несколько готовых функций, которые пригодятся в повседневной работе:
1. Поиск ближайшего значения в массиве
Ищет в диапазоне число, наиболее близкое к заданному:
Function NearestValue(LookupValue As Double, LookupRange As Range) As Double
Dim r As Range, minDiff As Double, currentDiff As Double
minDiff = Abs(LookupRange(1).Value - LookupValue)
NearestValue = LookupRange(1).Value
For Each r In LookupRange
currentDiff = Abs(r.Value - LookupValue)
If currentDiff < minDiff Then
minDiff = currentDiff
NearestValue = r.Value
End If
Next r
End Function
2. Проверка валидности ИНН
Проверяет контрольную сумму ИНН (для российских компаний):
Function ValidateINN(inn As String) As Boolean
Dim weights10() As Integer, weights12() As Integer
weights10 = Array(2, 4, 10, 3, 5, 9, 4, 6, 8)
weights12 = Array(7, 2, 4, 10, 3, 5, 9, 4, 6, 8)
If Len(inn) = 10 Then
ValidateINN = (Checksum(inn, weights10) = Right(inn, 1))
ElseIf Len(inn) = 12 Then
ValidateINN = (Checksum(inn, weights12) = Right(inn, 2))
Else
ValidateINN = False
End If
End Function
Private Function Checksum(inn As String, weights() As Integer) As String
Dim i As Integer, sum As Integer
For i = 0 To UBound(weights)
sum = sum + Val(Mid(inn, i + 1, 1)) * weights(i)
Next i
Checksum = Right(CStr((sum Mod 11) Mod 10), 1)
End Function
3. Извлечение всех ссылок из текста (Office Scripts)
Находит в тексте все URL и возвращает их список:
function main(workbook: ExcelScript.Workbook, text: string) {
let urlRegex = /https?:\/\/[^\s]+/g;
let urls = text.match(urlRegex);
return urls ? urls.join(", ") : "Ссылок не найдено";
}
Важно: Функция для ИНН работает только с числовыми значениями. Если в ячейке текст (например, с пробелами), используйте =ValidateINN(ТЕКСТ(A1)).
6. Типичные ошибки и как их избежать
Даже опытные пользователи сталкиваются с проблемами при создании функций. Вот самые распространённые ошибки и их решения:
| Ошибка | Причина | Решение |
|---|---|---|
#ИМЯ? в ячейке |
Опечатка в имени функции или несохранённый модуль VBA. | Проверьте регистр (Excel чувствителен к нему) и сохраните файл как .xlsm. |
#ЗНАЧ! при вычислении |
Функция возвращает неверный тип данных (например, текст вместо числа). | Используйте CInt(), CDbl() для явного приведения типов. |
| Excel "зависает" при пересчёте | Слишком много вызовов функции или рекурсия. | Ограничьте диапазон применения функции или оптимизируйте код (см. раздел 4). |
| Функция не обновляется | Отключён автоматический пересчёт или кэширование. | Нажмите F9 или включите Формулы → Параметры вычислений → Автоматически. |
Ещё одна частая проблема — утечка памяти в VBA. Если ваша функция создаёт объекты (например, Worksheet или Chart), не забывайте их удалять:
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Лист1")
' ... код ...
Set ws = Nothing ' Освобождаем память
⚠️ Внимание: Функции Office Scripts могут конфликтовать с VBA в одном файле. Если после добавления скрипта перестали работать макросы, сохраните файл в формате .xlsx (без макросов) и перенесите логику в скрипты.
7. Как сохранить и перенести функции в другой файл
Пользовательские функции хранятся внутри файла Excel, поэтому при копировании документа они переносятся автоматически. Однако есть нюансы:
- 📁 VBA: Сохраняйте файл в формате
.xlsm(с поддержкой макросов). Чтобы перенести функцию в другой файл, экспортируйте модуль: в редакторе VBA кликните правой кнопкой на модуле →Export File→ сохраните как.bas. В новом файле импортируйте его черезImport File. - ☁️ Office Scripts: Скрипты привязаны к файлу. Чтобы перенести, скопируйте код вручную в новый файл через
Автоматизация → Просмотреть скрипты. - 🔄 Power Query: Запросы сохраняются в файле. Чтобы перенести, скопируйте текст функции из
Дополнительно → Дополнительный редактор.
Если вы часто используете одни и те же функции, создайте шаблон:
- Создайте файл с нужными функциями.
- Сохраните его как
Шаблон Excel (*.xltm)черезФайл → Сохранить как. - При создании нового файла выберите ваш шаблон — все функции будут уже подгружены.
Для командной работы удобно хранить функции в общей библиотеке. В VBA это можно сделать через надстройки (Add-ins):
- Создайте файл с функциями и сохраните как
.xlam(надстройка). - Установите её через
Файл → Параметры → Надстройки → Перейти. - Теперь функции доступны во всех файлах Excel на вашем компьютере.
8. Альтернативы: когда не нужно писать код
Не всегда требуется создавать функцию с нуля. В некоторых случаях можно обойтись стандартными инструментами Excel:
- 🔢 Именованные формулы: Создайте именованный диапазон с формулой (например,
НДС = *0,2) и используйте его как=A1*НДС. Подходит для простых расчётов. - 📊 Таблицы подстановки: Для сложных зависимостей (например, налоговые ставки по категориям) используйте
ВПРилиXLOOKUP. - 🤖 Лямбда-функции (Excel 365): В новых версиях можно создавать функции прямо в ячейках без VBA:
=ЛЯМБДА(x, x*0.2)(A1) ' Аналог функции НДС20 - 🔌 Надстройки: Готовые решения (например, Power Tools или Kutools) содержат сотни дополнительных функций.
Если ваша задача — одноразовая обработка данных, рассмотрите использование Python в Excel (доступно в бета-версии Excel 365). Например, для анализа текста или машинного обучения:
=PY("import pandas as pd; pd.Series([1,2,3]).sum()")
Это позволяет использовать всю мощь библиотек pandas, numpy и других прямо в таблицах.
FAQ: Ответы на частые вопросы
Можно ли создать функцию, которая будет работать в Google Sheets?
Да, в Google Sheets для этого используются пользовательские функции на Google Apps Script (аналог VBA). Код пишется на JavaScript. Пример функции для расчёта НДС:
function НДС20(сумма) {
return Math.round(сумма 0.2 100) / 100;
}
Чтобы добавить её, откройте Расширения → Apps Script, вставьте код и сохраните. Функция станет доступна в таблице как =НДС20(A1).
Почему моя функция в VBA работает медленно?
Чаще всего тормоза вызваны:
- Чтением/записью в ячейки внутри цикла (используйте массивы).
- Отсутствием обработки ошибок (например, деление на ноль блокирует выполнение).
- Слишком большим диапазоном применения (ограничьте функцию только нужными ячейками).
Для ускорения:
- Отключите обновление экрана:
Application.ScreenUpdating = False. - Используйте
With ... End Withдля работы с объектами.
Можно ли создать функцию, которая изменяет формат ячейки?
Нет, пользовательские функции (UDF) в Excel могут только возвращать значение, но не изменять формат, цвет или содержимое других ячеек. Для этого нужна процедура VBA (не функция), которая запускается вручную или по событию (например, при изменении данных).
Пример процедуры для окраски ячейки:
Sub PaintCell()
If Range("A1").Value > 100 Then
Range("A1").Interior.Color = RGB(255, 0, 0) ' Красный цвет
End If
End Sub
Как сделать так, чтобы функция работала во всех файлах автоматически?
Есть два способа:
- Личная книга макросов:
- Создайте файл
Personal.xlsb(открывается автоматически при запуске Excel). - Добавьте функции в этот файл — они будут доступны во всех документах.
- Создайте файл
.xlam):
- Сохраните файл с функциями как надстройку.
- Установите её через
Файл → Параметры → Надстройки.
Оба метода требуют, чтобы Excel доверял макросам (настройки в Центре управления безопасностью).
Можно ли в функции VBA использовать данные из интернета?
Да, но для этого нужны дополнительные библиотеки. Пример функции, которая получает курс доллара с сайта ЦБ РФ:
Function GetUSDRate() As Double
Dim xmlHttp As Object, response As String
Set xmlHttp = CreateObject("MSXML2.XMLHTTP")
xmlHttp.Open "GET", "https://www.cbr.ru/scripts/XML_daily.asp", False
xmlHttp.send
response = xmlHttp.responseText
' Парсинг XML (упрощённо)
Dim posStart As Integer, posEnd As Integer
posStart = InStr(response, "") + 7
posEnd = InStr(response, "")
GetUSDRate = Replace(Mid(response, posStart, posEnd - posStart), ",", ".")
End Function
⚠️ Важно: Для работы этого кода нужно разрешить доступ к интернету в настройках безопасности Excel и установить библиотеку MSXML2 (обычно есть по умолчанию).