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

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

Как в процедуре вызвать функцию в 1С

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

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

Типичный сценарий: процедура выполняет действие (записывает документ, выводит сообщение, формирует отчёт), а функция вычисляет и возвращает результат (сумму скидки, признак ошибки, ссылку на найденный элемент). Разделение логики на процедуры и функции делает код читаемым и позволяет переиспользовать вычисления в разных местах конфигурации.

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

Синтаксис вызова функции из процедуры

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

Функция РассчитатьСкидку(Сумма)

Возврат Сумма * 0.1;

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

Процедура ПриОформленииЗаказа()

СуммаЗаказа = 10000;

Скидка = РассчитатьСкидку(СуммаЗаказа);

Сообщить("Скидка: " + Скидка);

КонецПроцедуры

Здесь процедура ПриОформленииЗаказа вызывает функцию РассчитатьСкидку, передаёт ей сумму и сохраняет возвращённое значение в переменную Скидка. Порядок объявления в модуле значения не имеет: функция может быть описана ниже процедуры, компилятор найдёт её в пределах модуля.

Результат функции можно использовать прямо в выражении, без промежуточной переменной:

Если РассчитатьСкидку(СуммаЗаказа) > 5000 Тогда

Сообщить("Требуется согласование скидки");

КонецЕсли;

Передача параметров при вызове

Параметры перечисляются в скобках через запятую в том порядке, в котором они объявлены в заголовке функции. Количество фактических параметров не должно превышать количество формальных, иначе компилятор выдаст ошибку «Слишком много фактических параметров».

Если у функции объявлены параметры со значениями по умолчанию, их можно опускать при вызове:

Функция СформироватьНадпись(Имя, Разделитель = ", ")

Возврат Имя + Разделитель + "клиент";

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

Процедура Тест()

Текст1 = СформироватьНадпись("Иван"); // разделитель по умолчанию

Текст2 = СформироватьНадпись("Иван", "; "); // явный разделитель

КонецПроцедуры

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

Работа с возвращаемым значением

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

Проверяйте результат перед использованием, особенно если функция ищет данные в базе и может ничего не найти:

Процедура ЗаполнитьКонтрагента()

Контрагент = НайтиКонтрагентаПоИНН(ИНН);

Если Контрагент = Неопределено Тогда

Сообщить("Контрагент не найден");

Возврат;

КонецЕсли;

// дальше работаем с найденным контрагентом

КонецПроцедуры

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

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

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

Тип возвращаемого значения
Норма

Совпадает с ожидаемым (число, строка, ссылка)

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

Пришло Неопределено там, где ожидались данные

Все ветки кода функции
Норма

Каждая ветка завершается Возврат со значением

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

Есть ветка, где Возврат отсутствует — результат непредсказуем

Поведение при отсутствии данных
Норма

Функция явно возвращает Неопределено или пустое значение, вызывающий код это обрабатывает

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

Функция падает с ошибкой или молча возвращает мусор

Вызов функции из другого модуля

Функции, объявленные в модуле объекта, формы или обработки, по умолчанию доступны только внутри этого модуля. Чтобы вызвать функцию извне, её нужно объявить с ключевым словом Экспорт, а саму функцию разместить в общем модуле.

// Общий модуль РаботаСЦенами

Функция ПолучитьЦену(Номенклатура, Дата) Экспорт

// ... запрос к регистру цен

Возврат Цена;

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

// Процедура в модуле документа

Процедура ПриИзмененииНоменклатуры()

Цена = РаботаСЦенами.ПолучитьЦену(Номенклатура, ТекущаяДатаСеанса());

КонецПроцедуры

Вызов строится по шаблону ИмяОбщегоМодуля.ИмяФункции(Параметры). Если у общего модуля снят флаг «Клиент» или «Сервер», доступность функции зависит от контекста исполнения: серверная функция недоступна в клиентском коде без серверного вызова.

Директивы компиляции

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

Типичные ошибки при вызове функций

Большинство проблем при вызове функций из процедур сводится к нескольким повторяющимся ситуациям. Знание их признаков экономит время на отладке.

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

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

Практический порядок действий

Как добавить вызов функции из процедуры
  1. 1
    Определите, где будет размещена функция: в том же модуле или в общем модуле для переиспользования
  2. 2
    Объявите функцию с параметрами, при необходимости добавьте Экспорт и директиву компиляции
  3. 3
    Обеспечьте оператор Возврат со значением во всех ветках логики функции
  4. 4
    В процедуре вызовите функцию и примите результат в переменную или используйте в выражении
  5. 5
    Проверьте результат на Неопределено перед дальнейшей обработкой
  6. 6
    Выполните синтаксическую проверку модуля и протестируйте вызов на реальных данных

После внесения изменений используйте проверку конфигурации (Конфигурация → Проверка конфигурации) с включённой проверкой логической целостности модулей — она выявит несуществующие имена функций и несовпадение параметров до запуска.

Итог

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

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

Частые вопросы

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

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

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

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

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

Убедитесь, что функция объявлена с ключевым словом Экспорт, а у общего модуля установлены нужные флаги контекста (Клиент, Сервер). Вызов выполняется через точку: ИмяОбщегоМодуля.ИмяФункции(Параметры). При вызове с клиента серверной функции учитывайте, что это серверный вызов.

Что делать при ошибке «Процедура или функция с указанным именем не определена»?

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

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

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

Сколько параметров может быть у функции?

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