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

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

В чем отличие процедуры от функции в 1С

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

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

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

Синтаксис объявления: как выглядят процедура и функция

Обе конструкции объявляются схожим образом. Процедура начинается ключевым словом Процедура и заканчивается словом КонецПроцедуры, функция — соответственно Функция и КонецФункции. Параметры в круглых скобках указываются одинаково, поддерживаются значения по умолчанию и передача по ссылке через Знач.

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

Возврат Сумма * Процент / 100;

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

Процедура ЗаписатьВЖурнал(ТекстСобытия)

ЗаписьЖурналаРегистрации("МоеПриложение", , , , ТекстСобытия);

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

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

Главное отличие: возвращаемое значение и использование в выражениях

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

// Корректно: функция внутри выражения

ИтоговаяСумма = СуммаДокумента - РассчитатьСкидку(СуммаДокумента);

Если РассчитатьСкидку(СуммаДокумента) > 1000 Тогда

Сообщить("Крупная скидка");

КонецЕсли;

// Корректно: процедура отдельным оператором

ЗаписатьВЖурнал("Документ проведен");

Обратная ситуация — ошибка. Строка Результат = ЗаписатьВЖурнал("текст"); не скомпилируется, потому что процедура не возвращает значение. Точно так же нельзя просто вызвать функцию как оператор и проигнорировать результат — строгой ошибки это не даст, но считается плохим стилем: если результат не нужен, вероятно, это должна быть процедура.

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

Процедура

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

Функция

Подходит, когда нужен результат: расчёт, поиск, проверка условия. Можно встраивать в любые выражения и условия.

Что вернуть, если результат не нужен: типичные сценарии

На практике разработчик часто сомневается, что выбрать. Простое правило: задайте вопрос «нужно ли мне после вызова получить какое-то значение?». Если да — функция. Если код только что-то делает (записывает, отправляет, устанавливает) — процедура.

Когда однозначно функция

Расчёты и преобразования: вычисление НДС, форматирование строки, поиск элемента справочника по коду. Проверки с булевым результатом: ДокументЗаполненКорректно(), ЕстьПраваНаИзменение(). Получение данных: ПолучитьКурсВалюты(), НайтиКонтрагентаПоИНН().

Когда однозначно процедура

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

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

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

Нужно получить число, строку, ссылку или булево для дальнейшей логикиОбъявите функцию и верните результат через Возврат
Нужно только выполнить действие без результатаОбъявите процедуру
Результат нужен в нескольких местах выражения одновременноФункция — единственный вариант, процедура в выражение не встанет
Код меняет данные и одновременно сообщает об успехеФункция с возвратом Булево (Истина — успех, Ложь — ошибка)

Общие свойства: параметры, директивы, экспортность

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

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

Типичные ошибки при выборе и использовании

Самая распространённая ошибка — забыть оператор Возврат в функции или покрыть не все ветки логики. Если в функции есть условие и возврат происходит только внутри Если, то при невыполнении условия функция вернёт Неопределено. Это не вызовет ошибки компиляции, но приведёт к трудноуловимым сбоям в местах вызова.

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

Типичные ошибки
01
Нет Возврат в одной из веток функции — функция молча возвращает Неопределено и ломает логику вызывающего кода
02
Присваивание результата процедуры переменной — ошибка компиляции, процедура ничего не возвращает
03
Функция с побочными эффектами (записывает данные в базу) — неожиданные изменения при, казалось бы, безобидном вызове в условии
04
Дублирование кода: одна и та же логика написана как процедура и как функция в разных модулях — расхождение при доработках

Как проверить корректность кода

После написания метода выполните проверку модуля в конфигураторе (меню «Конфигурация» → «Проверка конфигурации» или синтаксический контроль модуля). Ошибки типа «процедура используется как функция» выявляются на этом этапе. Для проверки возвращаемых значений полезно временно вывести результат через Сообщить() или посмотреть его в отладчике.

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

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

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

Каждый путь выполнения заканчивается Возврат со значением

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

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

Место вызова
Норма

Функция вызывается в выражении, процедура — отдельным оператором

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

Процедура стоит в правой части присваивания

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

Функция только вычисляет и возвращает

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

Функция меняет объекты или пишет в базу без явной необходимости

Итог

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

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

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

Может ли процедура вернуть значение через параметр?

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

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

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

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

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

Чем обработчики событий отличаются от обычных процедур?

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

Может ли асинхронный метод быть функцией?

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

Как передать несколько результатов из одного метода?

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