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

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

Как обращаться к функции в 1С

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

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

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

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

Синтаксис вызова функции

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

Пример простого вызова:

// Объявление функции в том же модуле

Функция РассчитатьСуммуСНДС(Сумма, Ставка)

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

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

// Обращение к функции

ИтоговаяСумма = РассчитатьСуммуСНДС(10000, 20);

Сообщить("Итого: " + ИтоговаяСумма);

Вызов функции может быть частью любого выражения: условия «Если», арифметической операции, параметра другой функции. Например: Если РассчитатьСуммуСНДС(Сумма, 20) > Лимит Тогда .... Это допустимо, но при сложных выражениях читаемость кода снижается — результат лучше предварительно сохранить в переменную с понятным именем.

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

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

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

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

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

Обращение к функциям общих модулей

Чаще всего функции размещают в общих модулях, чтобы использовать их из разных объектов конфигурации. Обращение выполняется через имя общего модуля: Результат = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "Наименование"). Здесь «ОбщегоНазначения» — имя общего модуля, а после точки — имя экспортной функции.

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

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

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

Как выбрать место для функции

Функция нужна только внутри одной формыОбъявите её в модуле формы без Экспорт, с директивой &НаКлиенте или &НаСервере
Функция нужна нескольким объектам и работает с базой данныхПоместите её в общий модуль с флагом Сервер и объявите с Экспорт
Функцию нужно вызывать из клиентского кода формыИспользуйте общий модуль с флагами Сервер и Вызов сервера
Функция работает только с интерфейсом и не обращается к даннымПодойдёт общий модуль с флагом Клиент (управляемое приложение)

Вызов функций из модуля формы и модуля объекта

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

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

Из внешних обработок и отчётов обращение к функциям конфигурации выполняется так же, как из встроенного кода, — через общие модули. Это удобно для тестирования: можно быстро проверить работу функции, не меняя конфигурацию.

bsl
&НаСервереБезКонтекста
Функция ПолучитьКурсВалюты(Валюта, Дата)
    Возврат РаботаСКурсамиВалют.ПолучитьКурс(Валюта, Дата);
КонецФункции

Проверка результата и обработка возвращаемых значений

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

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

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

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

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

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

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

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

В некоторых условиях возвращается Неопределено без явной обработки

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

Вызов из другого модуля проходит без ошибок, функция объявлена с Экспорт

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

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

Параметры
Норма

Количество и порядок фактических параметров совпадают с объявлением

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

Ошибка «Слишком много фактических параметров» или неверные значения внутри функции

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

Переданные переменные не меняются, если это не предусмотрено

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

После вызова изменились значения переменных вызывающего кода (передача по ссылке)

Типичные ошибки при обращении к функциям

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

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

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

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

Ограничения и безопасная работа

При доработке типовых конфигураций избегайте прямого изменения функций в общих модулях поставщика: при обновлении конфигурации изменения будут потеряны или вызовут конфликт. Если конфигурация на поддержке, используйте расширения конфигурации — в них можно переопределить или дополнить функциональность через аннотации «&ИзменениеИКонтроль», «&Вместо», «&После».

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

Итог

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

Функция вызывается по имени со скобками и параметрами; для доступа из других модулей нужно ключевое слово Экспорт и обращение через имя общего модуля. Проверяйте контекст исполнения (клиент/сервер), порядок параметров и наличие Возврат во всех ветках — это покрывает большинство ошибок при обращении к функциям.

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

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

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

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

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

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

Нет, скобки обязательны всегда. Вызов функции без параметров записывается как ИмяФункции(). Без скобок имя будет воспринято как обращение к переменной, что приведёт к ошибке или неверному результату.

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

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

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

Достаточно написать имя общего модуля, точку и имя функции: Результат = МойМодуль.МояФункция(Параметр). Функция должна быть экспортной, а флаги модуля должны разрешать вызов из нужного контекста — например, для вызова с клиента нужны флаги «Сервер» и «Вызов сервера».

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

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