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

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

Как создать функцию в 1С: полное руководство для разработчика

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

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

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

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

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

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

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

Функция или процедура

Функция

Нужен результат вычисления: сумма, признак, ссылка, структура данных. Результат используется в выражениях и присваиваниях.

Процедура

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

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

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

У общего модуля критически важны флаги в палитре свойств. Флаг «Сервер» означает выполнение на сервере, «Клиент (управляемое приложение)» — на клиенте. Код, работающий с базой данных (запросы, записи объектов), должен выполняться на сервере. Если функция с запросом окажется в клиентском модуле, при вызове получите ошибку компиляции или выполнения.

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

Создание общего модуля и написание функции

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

В теле модуля напишите функцию. Минимальный рабочий пример — расчёт суммы скидки по проценту:

Функция РассчитатьСкидку(СуммаДокумента, ПроцентСкидки) Экспорт

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

ВызватьИсключение "Процент скидки должен быть от 0 до 100";

КонецЕсли;

СуммаСкидки = СуммаДокумента * ПроцентСкидки / 100;

Возврат СуммаСкидки;

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

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

Порядок создания функции
  1. 1
    В конфигураторе создайте общий модуль и установите нужные флаги (Сервер, Вызов сервера)
  2. 2
    Напишите функцию: имя, параметры, слово Экспорт, тело с обязательным Возврат
  3. 3
    Проверьте синтаксис: Ctrl+F7 или пункт меню «Конфигурация — Проверка конфигурации»
  4. 4
    Обновите конфигурацию базы данных (F7), если изменения этого требуют
  5. 5
    Вызовите функцию из прикладного кода и проверьте результат в отладчике

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

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

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

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

Вызов функции и проверка результата

Функцию из общего модуля вызывают через имя модуля: СуммаСкидки = РаботаСоСкидками.РассчитатьСкидку(ИтогСумма, 10);. Если функция объявлена в том же модуле, где вызывается, имя модуля не нужно — достаточно имени функции.

Для проверки используйте отладчик: поставьте точку останова (F9) на строке вызова, запустите отладку (F5), шагните внутрь функции (F11) и посмотрите значения переменных в табло. Контрольный пример: при сумме 10 000 и проценте 15 результат должен быть 1 500. Если значение отличается — проблема в формуле или в входных данных.

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

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

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

На всех ветках логики выполняется оператор Возврат, значение имеет ожидаемый тип

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

Есть путь выполнения без Возврат — функция вернёт Неопределено

Доступность функции
Норма

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

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

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

Контекст выполнения
Норма

Серверный код (запросы, записи) находится в серверном модуле

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

Ошибка о недопустимости вызова на клиенте или отсутствии контекста

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

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

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

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

Расширенные сценарии: директивы компиляции и возврат сложных данных

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

Возврат нескольких значений

Функция возвращает одно значение, но это может быть структура или массив. Например, функция анализа документа может вернуть структуру с полями «ЕстьОшибки», «ТекстОшибки», «СуммаРасхождения». Это чище, чем передавать несколько параметров по ссылке для возврата результатов.

Функции в расширениях конфигурации

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

Давайте функциям говорящие имена по шаблону «глагол + объект»: РассчитатьСкидку, ПолучитьОстаток, ПроверитьЗаполнение. По такому имени сразу понятно, что функция делает и что возвращает, а код читается без комментариев.
ПЗ
Практическое замечание

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

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

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

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

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

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

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

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

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

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

Встроенный язык 1С — с динамической типизацией, явного объявления типов параметров нет. Типы фиксируют в комментарии перед функцией (так называемое описание для синтакс-помощника EDT/конфигуратора), а внутри функции при необходимости проверяют через ТипЗнч().

Где лучше хранить функции: в одном большом модуле или в нескольких?

Группируйте функции по прикладному смыслу: отдельные модули для работы со скидками, с номенклатурой, с печатью. Один «сводный» модуль на всё затрудняет поиск и увеличивает риск конфликтов при командной разработке.

Итог

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

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