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

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

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

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

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

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

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

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

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

// Процедура: выполняет действие, ничего не возвращает

Процедура ВывестиСообщениеПользователю(Текст) Экспорт

Сообщить(Текст);

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

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

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

Результат = Сумма + Сумма * СтавкаНДС / 100;

Возврат Результат;

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

Обратите внимание на парность: «Процедура … КонецПроцедуры» и «Функция … КонецФункции». Если открыть метод словом «Функция», а закрыть «КонецПроцедуры», конфигуратор выдаст синтаксическую ошибку ещё на этапе проверки модуля.

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

Возврат значения: главное различие на практике

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

Процедура тоже может содержать оператор «Возврат», но только без значения — как способ досрочно выйти из метода. Написать «Возврат Истина;» внутри процедуры нельзя: это синтаксическая ошибка.

Функция ЭтоПроведенныйДокумент(ДокументСсылка) Экспорт

Если ДокументСсылка.Пустая() Тогда

Возврат Ложь; // ветка с возвратом

КонецЕсли;

Возврат ДокументСсылка.Проведен; // ветка с возвратом

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

Процедура ПроверитьЗаполнение(Объект)

Если Объект.Товары.Количество() = 0 Тогда

Возврат; // просто выходим, значения нет

КонецЕсли;

// дальнейшая обработка

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

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

Когда выбирать процедуру, а когда функцию

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

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

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

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

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

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

Экспорт и видимость: вызов из других модулей

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

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

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

// доступна как РаботаСЦенами.ПолучитьЦену(...)

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

Функция ВнутреннийРасчет(Параметр) // без Экспорт — только внутри модуля

// ...

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

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

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

Контекст выполнения: клиент, сервер и директивы компиляции

В модулях форм и команд процедуры и функции сопровождаются директивами компиляции: «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста», «&НаКлиентеНаСервереБезКонтекста». Директива определяет, где выполнится код, и она одинаково применима к обоим видам методов.

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

&НаКлиенте

Процедура РассчитатьНажатие(Команда)

Итог = РассчитатьИтогНаСервере(Объект.Ссылка);

ПоказатьПредупреждение(, "Итог: " + Итог);

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

&НаСервереБезКонтекста

Функция РассчитатьИтогНаСервере(Ссылка)

Возврат Ссылка.Товары.Итог("Сумма");

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

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

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

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

Процедура УвеличитьЧисло(Число) // по ссылке

Число = Число + 1; // изменится и у вызывающего

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

Процедура УвеличитьКопию(Знач Число) // по значению

Число = Число + 1; // у вызывающего не изменится

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

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

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

Функция с возвратом структуры

Подходит, когда результатов несколько: Возврат Новый Структура("Успех, Сумма, Описание", ...). Читаемо, но структуру нужно документировать

Процедура с параметрами по ссылке

Подходит для простых случаев с одним-двумя выходными параметрами. При большом числе изменяемых параметров код становится запутанным

Процедура без результата

Подходит для действий без обратной связи: запись, сообщение, заполнение. Ошибки придётся сигнализировать исключением

Как проверить, что метод оформлен правильно

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

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

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

Компиляция модуля
Норма

Проверка конфигурации проходит без ошибок по модулю

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

Ошибки вида «ожидается КонецФункции» или «переменная не определена»

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

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

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

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

Видимость из других модулей
Норма

Вызов ИмяМодуля.ИмяМетода() работает, автоподстановка показывает метод

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

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

Контекст вызова
Норма

Клиентский код вызывает только клиентские методы и серверные через вызов сервера

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

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

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

Итог

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

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

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

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

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

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

Напрямую — нет, оператор Возврат принимает одно значение. Обходные пути: вернуть структуру или массив с несколькими полями, либо использовать процедуру с параметрами, передаваемыми по ссылке. Структура предпочтительнее, так как явно видна в сигнатуре вызова.

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

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

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

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

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

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

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

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