К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как работает функция в 1С: устройство, параметры и примеры

Как устроена функция в 1С: объявление, параметры, возврат значения, отличие от процедуры, экспорт и типичные ошибки с практическими примерами кода.

Функция в 1С — это именованный блок кода на встроенном языке, который принимает параметры, выполняет вычисления и обязательно возвращает результат через оператор «Возврат». Функции используются повсюду: в модулях объектов, общих модулях, модулях форм и даже в выражениях на форме. Понимание того, как функция объявляется, как передаются параметры и куда возвращается значение, — базовый навык для любого, кто дорабатывает конфигурацию или пишет собственные обработки.

Главное отличие функции от процедуры — наличие возвращаемого значения. Если блок кода должен что-то вычислить и отдать результат (сумму с НДС, найденную ссылку, строку сообщения), это функция. Если код просто выполняет действия (проводит документ, заполняет таблицу), достаточно процедуры. Неправильный выбор между ними — частая причина запутанного кода, где результат «теряется» или передаётся через глобальные переменные.

Ниже разобраны объявление функции, работа с параметрами, возврат значения, область видимости, отличия от процедуры, диагностика ошибок и практические приёмы, которые помогут писать предсказуемый код.

Как объявить функцию: синтаксис и структура

Функция объявляется в модуле по шаблону: ключевое слово «Функция», имя, список параметров в круглых скобках, необязательное слово «Экспорт», тело с операторами и завершающее «КонецФункции». Минимальный пример:

Функция СуммаСНДС(Сумма, Ставка) Экспорт

Возврат Сумма + Сумма * Ставка / 100;

КонецФункции

Имя функции должно быть уникальным в пределах модуля и отражать то, что она возвращает: «ПолучитьКурсВалюты», «РассчитатьСкидку», «НайтиКонтрагентаПоИНН». Имена вида «Ф1» или «Обработка» затрудняют чтение и поиск по конфигурации. Слово «Экспорт» делает функцию доступной из других модулей — без него функция видна только внутри своего модуля.

Порядок функций внутри модуля не влияет на возможность вызова: платформа видит все объявления модуля независимо от их расположения. Однако для читаемости принято группировать экспортные функции в области «ПрограммныйИнтерфейс», а вспомогательные — в «СлужебныеПроцедурыИФункции».

Параметры: передача по значению и по ссылке

Параметры перечисляются в скобках через запятую. По умолчанию параметр передаётся по ссылке: изменения внутри функции отразятся на переменной вызывающего кода. Ключевое слово «Знач» перед именем параметра включает передачу по значению — функция работает с копией, и исходная переменная не меняется.

Функция ДобавитьПозицию(Знач Таблица, Товар)

// Таблица здесь — копия, оригинал не изменится

НоваяСтрока = Таблица.Добавить();

НоваяСтрока.Товар = Товар;

Возврат Таблица;

КонецФункции

Для параметра можно задать значение по умолчанию через знак равенства: Функция Рассчитать(Сумма, Ставка = 20). Такие параметры должны стоять в конце списка. При вызове их можно опустить — подставится значение по умолчанию. Если нужно проверить, передан ли параметр без значения по умолчанию, сравните его с Неопределено.

Практическое правило: используйте «Знач» для примитивных типов (числа, строки, даты), когда функция не должна влиять на вызывающий код. Для крупных объектов вроде таблиц значений осознанно выбирайте режим: передача по ссылке быстрее, но побочные изменения могут стать источником трудноуловимых ошибок.

Возврат значения и ранний выход

Оператор «Возврат» завершает выполнение функции и передаёт значение в точку вызова. Код после «Возврат» в той же ветке не выполняется. Если функция завершилась без «Возврат», она вернёт Неопределено — это частая причина ошибок вида «попытка сложения со значением Неопределено».

Ранний выход — удобный приём для обработки граничных случаев в начале функции. Вместо глубокой вложенности условий проверяйте некорректные входные данные сразу:

Функция ЦенаСоСкидкой(Цена, ПроцентСкидки) Экспорт

Если Цена <= 0 Тогда

Возврат 0;

КонецЕсли;

Если ПроцентСкидки > 100 Тогда

Возврат 0;

КонецЕсли;

Возврат Цена * (100 - ПроцентСкидки) / 100;

КонецФункции

Такой стиль называют «защитным программированием»: функция явно определяет, что она делает с некорректными данными, а не падает с ошибкой в середине вычислений. Решите заранее, что возвращать в спорных случаях — 0, Неопределено или пустую структуру — и придерживайтесь этого соглашения во всём модуле.

Область видимости и экспортные функции

Функция без слова «Экспорт» доступна только внутри своего модуля. Это правильный выбор для вспомогательных вычислений: чем меньше видимость, тем проще сопровождать код. Экспортные функции общих модулей вызываются откуда угодно по схеме ИмяОбщегоМодуля.ИмяФункции(Параметры).

Общие модули бывают серверными, клиентскими и с признаком «Вызов сервера». Функция в серверном модуле недоступна на тонком клиенте напрямую — её вызывают через серверный вызов из клиентского кода. В модуле формы директивы компиляции &НаСервере, &НаКлиенте и &НаСервереБезКонтекста определяют, где исполняется функция. Несоответствие контекста — типичная причина ошибки «Процедура или функция с указанным именем не определена».

Функции с контекстом «БезКонтекста» не имеют доступа к реквизитам формы, зато выполняются быстрее, так как не требуют передачи данных формы между клиентом и сервером. Выносите в такие функции чистые вычисления, которым не нужны данные объекта.

Сравнение вариантов

Функция в общем модуле

Подходит для логики, используемой в разных объектах конфигурации. Ограничение: нужно правильно настроить флаги Сервер/Клиент/ВызовСервера.

Функция в модуле объекта

Подходит для операций, привязанных к конкретному документу или справочнику. Ограничение: недоступна без контекста объекта.

Функция в модуле формы

Подходит для обработки действий пользователя и работы с реквизитами формы. Ограничение: живёт только пока открыта форма.

Чем функция отличается от процедуры

Технических отличий два. Первое: функция возвращает значение и может стоять в правой части присваивания или внутри выражения — Итог = СуммаСНДС(База, 20);. Процедура вызывается отдельным оператором, её имя нельзя использовать в выражении. Второе: у процедуры оператор «Возврат» используется без значения и только для досрочного выхода.

Выбор между ними определяется смыслом блока кода. Нужен результат вычисления — функция. Нужно выполнить последовательность действий (записать объект, отправить сообщение, заполнить табличную часть) — процедура. Антипаттерн — процедура, которая «возвращает» результат через параметр по ссылке: такой код труднее тестировать, чем честную функцию.

Маршрут решения

Как выбрать действие

Блок кода должен вычислить и отдать одно значениеОбъявите функцию и верните результат через «Возврат»
Блок кода выполняет действия без вычисляемого результатаИспользуйте процедуру
Нужно вернуть несколько значенийВерните из функции Структуру с именованными полями вместо набора параметров по ссылке
Функция нужна в нескольких объектах конфигурацииВынесите её в общий модуль с признаком Экспорт

Типичные ошибки и их диагностика

Самая частая ошибка — «Процедура или функция с указанным именем не определена». Причины: опечатка в имени, отсутствие «Экспорт» у функции общего модуля, вызов серверной функции с клиента без серверного контекста. Проверьте имя, модификатор доступа и флаги компиляции модуля.

Вторая группа ошибок связана с возвращаемым значением: функция вернула Неопределено из-за пропущенного «Возврат» в одной из веток, а вызывающий код пытается использовать результат в арифметике. Защита — проверка результата через Если Результат = Неопределено Тогда в местах, где такой исход допустим.

Третья группа — побочные эффекты через параметры по ссылке. Функция молча изменила переданную таблицу значений, и дальше по коду данные оказались не теми, что ожидались. Диагностируется отладчиком: поставьте точку останова до и после вызова и сравните содержимое переменной.

Типичные ошибки
01
Пропущен «Возврат» в одной из веток — функция возвращает Неопределено, вызывающий код падает на арифметике или сравнении.
02
Вызов серверной функции из клиентского контекста — ошибка компиляции или выполнения; нужен общий модуль с «Вызов сервера».
03
Изменение параметра, переданного по ссылке, без предупреждения — неочевидные побочные эффекты в вызывающем коде.
04
Использование процедуры с параметром-результатом там, где нужна функция — код труднее читать и тестировать.
05
Экспорт всех функций подряд — раздутый программный интерфейс модуля, который страшно менять.

Как проверить работу функции

Самый быстрый способ проверить чистую функцию — вызвать её из внешней обработки или из команды формы с тестовыми данными и вывести результат через «Сообщить». Для функций общих модулей удобно временно вызвать их из обработчика кнопки на любой форме.

Отладчик конфигуратора позволяет пошагово пройти тело функции: клавиша F11 (шаг с заходом) проваливается внутрь вызова, F10 идёт поверх. В табло (Ctrl+Shift+F9) можно вычислить любое выражение, включая вызов функции с произвольными параметрами, прямо во время остановки.

Проверяйте функцию на трёх классах входных данных: нормальные значения, граничные (ноль, пустая строка, максимальные скидки) и некорректные (Неопределено, отрицательные числа там, где они не имеют смысла). Если функция корректно отрабатывает все три класса, её можно считать устойчивой.

Контрольные точки

Как проверить результат

Возвращаемое значение
Норма

Функция всегда возвращает значение ожидаемого типа на всех ветках

Тревожный признак

В отдельных сценариях приходит Неопределено без умысла

Побочные эффекты
Норма

Входные параметры после вызова не изменились (если не задумано иное)

Тревожный признак

Переданная таблица или структура изменилась без явной необходимости

Граничные данные
Норма

Ноль, пустая строка и Неопределено обрабатываются предсказуемо

Тревожный признак

Ошибка выполнения или нереалистичный результат на крайних значениях

Держите функции короткими: если тело превышает 30–40 строк, скорее всего, внутри несколько независимых шагов, которые стоит вынести в отдельные функции с говорящими именами. Короткие функции проще отлаживать и безопаснее менять.
ПЗ
Практическое замечание
Итог

Что важно запомнить

Функция объявляется парой «Функция...КонецФункции», принимает параметры (по ссылке или через «Знач» — по значению) и обязана вернуть результат оператором «Возврат». «Экспорт» открывает доступ из других модулей, контекст компиляции определяет, где код исполняется. Проверяйте возврат на всех ветках и избегайте скрытых побочных эффектов через параметры по ссылке.

Частые вопросы о функциях в 1С

Что вернёт функция, если в ней нет оператора «Возврат»?

Функция вернёт значение Неопределено. Это не вызовет ошибку в момент возврата, но почти наверняка приведёт к ошибке позже — когда вызывающий код попытается использовать результат в вычислении или сравнении. Поэтому перед завершением разработки проверяйте, что каждая ветка логики заканчивается осмысленным «Возврат».

Может ли функция вернуть несколько значений?

Напрямую — нет, оператор «Возврат» передаёт одно значение. Обходные пути: вернуть Структуру с несколькими именованными полями, Массив или изменить параметры, переданные по ссылке. Вариант со Структурой считается наиболее читаемым: вызывающий код обращается к результату по понятным именам полей.

Почему функция общего модуля «не видна» из моего кода?

Проверьте три вещи: стоит ли слово «Экспорт» после объявления функции, включён ли у общего модуля нужный контекст (например, «Вызов сервера», если вы обращаетесь с клиента к серверной функции), и нет ли одноимённой функции в текущем модуле, которая перекрывает вызов. Также убедитесь, что сам общий модуль не помечен «Привилегированный» там, где это не требуется, — это влияет на права, но не на видимость.

Чем «Знач» перед параметром отличается от обычного параметра?

Без «Знач» параметр передаётся по ссылке: функция работает с той же переменной, что и вызывающий код, и может её изменить. С «Знач» функция получает копию, и изменения внутри не затрагивают оригинал. Копирование больших структур данных стоит ресурсов, поэтому «Знач» ставят осознанно — когда важна защита от побочных эффектов.

Можно ли вызвать функцию в выражении на форме или в запросе?

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

Как передать в функцию необязательный параметр?

Задайте значение по умолчанию в объявлении: «Функция Рассчитать(Сумма, Ставка = 20)». При вызове параметр можно опустить, и подставится значение по умолчанию. Параметры со значениями по умолчанию должны идти в конце списка. Если умолчания нет, внутри функции проверяйте параметр на Неопределено и обрабатывайте этот случай явно.