В мире 1С:Предприятие процедуры и функции — это основные строительные блоки любой программы. Без них невозможно создать ни один отчёт, обработку или автоматизировать бизнес-процесс. Но многие начинающие разработчики путают их назначение, синтаксис или не понимают, когда лучше использовать тот или иной подход.
Эта статья поможет разобраться, что такое процедура и функция в 1С, чем они отличаются друг от друга, как правильно их писать и где применять. Мы рассмотрим не только теорию, но и практические примеры с кодом, типичные ошибки и советы по оптимизации. А в конце ответим на часто задаваемые вопросы, которые возникают у программистов при работе с этими конструкциями.
Если вы только начинаете осваивать 1С 8.3 или переходите с других языков программирования, эта информация станет для вас надёжным фундаментом. Опытные разработчики тоже найдут здесь полезные нюансы — например, как избежать распространённых ошибок при работе с рекурсией или передачей параметров.
1. Процедуры в 1С: определение и синтаксис
Процедура в 1С — это именованный блок кода, который выполняет определённое действие, но не возвращает результат. Она используется для группировки команд, которые нужно выполнить последовательно. Например, обработка события нажатия кнопки, загрузка данных или изменение состояния объекта.
Синтаксис объявления процедуры выглядит так:
Процедура ИмяПроцедуры(Параметр1, Параметр2, ...)
// Тело процедуры
// Код, который выполняет нужные действия
КонецПроцедуры
Где:
- 🔹
ИмяПроцедуры— уникальный идентификатор (регистрозависимый!ПечатьДокументаипечатьдокумента— разные процедуры). - 🔹
Параметр1, Параметр2— необязательные входные данные (могут отсутствовать). - 🔹
КонецПроцедуры— обязательное завершение блока.
Процедуры часто используются для:
- 📌 Обработки событий (например,
ПриОткрытии(),ПередЗаписью()). - 📌 Выполнения повторяющихся действий (например, очистка временных файлов).
- 📌 Изменения данных без возврата результата (например, обновление статуса документа).
Если процедура не принимает параметров, скобки после её имени можно опустить: Процедура Печать() равносильно Процедура Печать.
2. Функции в 1С: возвращаем результат
В отличие от процедуры, функция в 1С обязательно возвращает значение с помощью оператора Возврат. Это делает её универсальным инструментом для вычислений, проверок или получения данных. Например, функция может рассчитать сумму скидки, проверить корректность ИНН или вернуть список клиентов по фильтру.
Синтаксис функции:
Функция ИмяФункции(Параметр1, Параметр2, ...)
// Тело функции
Возврат Результат; // Обязательно!
КонецФункции
Ключевые особенности функций:
- 🔢 Обязательное наличие оператора
Возврат(иначе будет ошибка компиляции). - 🔢 Можно возвращать значения любого типа: числа, строки, массивы, объекты 1С.
- 🔢 Результат функции можно сразу использовать в выражениях (например,
Если РассчитатьСкидку(Сумма) > 100 Тогда...).
Примеры типичных функций:
- 📊
РассчитатьНДС(Сумма, Ставка)— возвращает сумму налога. - 🔍
НайтиКлиентаПоИНН(ИНН)— возвращает ссылку на контрагента илиНеопределено. - 📅
ПолучитьДатуОплаты(Документ)— возвращает дату из графика платежей.
3. Ключевые отличия процедур и функций
Чтобы окончательно разобраться, чем отличаются эти конструкции, сведем их характеристики в таблицу:
| Характеристика | Процедура | Функция |
|---|---|---|
| Возврат значения | ❌ Нет | ✅ Да (обязательно) |
| Использование в выражениях | ❌ Только как отдельный оператор | ✅ Можно вставить в условие или формулу |
| Типичные задачи | Обработка событий, изменение данных | Расчёты, проверки, получение данных |
Оператор Возврат |
❌ Запрещён (ошибка) | ✅ Обязателен |
| Пример вызова | ОчиститьКэш() |
Сумма = РассчитатьИтог(Данные) |
Важный нюанс: в 1С процедура может имитировать поведение функции, если использовать параметры по ссылке (с ключевым словом Перем). Однако это считается плохой практикой — лучше явно разделять логику на процедуры и функции.
Если ваш код что-то рассчитывает или проверяет — это функция. Если просто выполняет действия (сохраняет, печатает, обновляет) — это процедура.
4. Когда использовать процедуру, а когда — функцию?
Выбор между процедурой и функцией зависит от контекста задачи. Вот практические рекомендации:
Используйте процедуру, если:
- 📋 Нужно выполнить последовательность действий без возврата результата (например, отправить email, обновить статус).
- 📋 Работаете с событиями (
ПриЗаписи,ПередУдалением). - 📋 Логика не требует передачи данных "наружу" (например, очистка временных файлов).
Используйте функцию, если:
- 🧮 Нужно вернуть результат расчёта (сумма, процент, дата).
- 🔍 Требуется проверить условие (например,
Если КлиентАктивен(Ссылка) Тогда...). - 📊 Данные будут использоваться в других частях кода (например, получить список товаров по фильтру).
Можно ли обойтись только процедурами?
Технически да — можно передавать результаты через параметры по ссылке (Перем). Но это усложняет код, делает его менее читаемым и увеличивает риск ошибок. Функции были введены в 1С именно для упрощения логики.
Пример правильного разделения:
// ✅ Хорошо: процедура для действия, функция для расчёта
Процедура ОбновитьСтатусЗаказа(Заказ, НовыйСтатус)
Заказ.Статус = НовыйСтатус;
Заказ.Записать();
КонецПроцедуры
Функция РассчитатьСуммуСоСкидкой(Сумма, ПроцентСкидки)
Возврат Сумма * (1 - ПроцентСкидки / 100);
КонецФункции
5. Параметры процедур и функций: нюансы передачи
Параметры позволяют передавать данные в процедуры и функции. В 1С 8.3 есть несколько способов их объявления, которые влияют на поведение кода:
1. Передача по значению (по умолчанию)
Создаётся копия переменной. Изменения внутри процедуры/функции не затрагивают оригинал:
Процедура УвеличитьЧисло(Число)
Число = Число + 1; // Изменится только локальная копия
КонецПроцедуры
Переменная = 5;
УвеличитьЧисло(Переменная);
// Переменная остаётся равной 5
2. Передача по ссылке (ключевое слово Перем)
Работает с оригинальной переменной. Изменения сохранятся после выполнения:
Процедура УвеличитьЧисло(Перем Число)
Число = Число + 1; // Изменится оригинальная переменная
КонецПроцедуры
Переменная = 5;
УвеличитьЧисло(Переменная);
// Теперь Переменная равна 6
3. Необязательные параметры
Можно задать значение по умолчанию, если параметр не передан:
Функция Сложить(Число1, Число2 = 0)
Возврат Число1 + Число2;
КонецФункции
Результат = Сложить(10); // Вернёт 10 (Число2 = 0)
Убедиться, что передаёте корректные типы данных|Проверить обязательные параметры на Неопределено|Для изменяемых данных использовать Перем|Избегать слишком длинных списков параметров (более 5)
-->
⚠️ Внимание: Чрезмерное использование параметров по ссылке (Перем) может привести к трудноотслеживаемым ошибкам, особенно в больших системах. Старайтесь возвращать результаты через функции, а не модифицировать внешние переменные.
6. Типичные ошибки и как их избежать
Даже опытные разработчики иногда допускают ошибки при работе с процедурами и функциями. Вот наиболее распространённые проблемы и способы их решения:
1. Забытый оператор Возврат в функции
Если функция должна вернуть значение, но Возврат отсутствует, 1С выдаст ошибку компиляции. Всегда проверяйте:
Функция ПолучитьИмяКлиента(Клиент)
// ... код ...
// Забыли Возврат! Ошибка: "Ожидается оператор Возврат"
КонецФункции
2. Изменение параметров по значению
Многие ожидают, что передача параметра изменит оригинальную переменную, но по умолчанию это не так:
Процедура Удвоить(Значение)
Значение = Значение * 2; // Локальная копия!
КонецПроцедуры
Число = 5;
Удвоить(Число);
// Число остаётся 5!
3. Рекурсия без условия выхода
Функции и процедуры могут вызывать сами себя (рекурсия), но без ограничителя это приведёт к зависанию:
Функция Факториал(Н)
Если Н = 1 Тогда
Возврат 1;
Иначе
Возврат Н * Факториал(Н - 1); // Рекурсия
КонецЕсли;
КонецФункции
// Без условия "Если Н = 1" будет бесконечный вызов
4. Длинные списки параметров
Если у процедуры или функции более 5 параметров, это признак плохого проектирования. Лучше:
- 🔧 Объединить связанные параметры в структуру.
- 🔧 Разбить логику на несколько меньших функций.
Чтобы отладить функцию, которая возвращает неожиданный результат, добавьте временный вывод в консоль: Сообщить("Значение параметра: " + Параметр);.
7. Примеры из реальных задач
Рассмотрим практические сценарии, где процедуры и функции применяются в типичных бизнес-задачах.
Пример 1: Обработка документа "Реализация товаров"
Процедура ПриПроводке(Документ)
// Проверяем корректность данных перед проводкой
Если НЕ ПроверитьРеквизиты(Документ) Тогда
ПрерватьОбработку("Некорректные реквизиты!");
КонецЕсли;
// Рассчитываем суммы
Документ.СуммаДокумента = РассчитатьИтоговуюСумму(Документ.Строки);
Документ.Записать();
КонецПроцедуры
Функция ПроверитьРеквизиты(Док)
Возврат Док.Контрагент <> Неопределено И Док.Склад <> Неопределено;
КонецФункции
Функция РассчитатьИтоговуюСумму(Строки)
Сумма = 0;
Для Каждого Строка Из Строки Цикл
Сумма = Сумма + Строка.Сумма;
КонецЦикла;
Возврат Сумма;
КонецФункции
Пример 2: Работа со справочником "Номенклатура"
Функция ПолучитьОстаткиТовара(Товар, Склад)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОстаткиТоваров.КоличествоОстаток КАК Остаток
|ИЗ
| РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваров
|ГДЕ
| ОстаткиТоваров.Номенклатура = &Товар
| И ОстаткиТоваров.Склад = &Склад";
Запрос.УстановитьПараметр("Товар", Товар);
Запрос.УстановитьПараметр("Склад", Склад);
Результат = Запрос.Выполнить().Выбрать().Остаток;
Возврат Результат <> Неопределено ? Результат : 0;
КонецФункции
Процедура ВывестиОстаткиНаЭкран(Товар)
Сообщить("Остаток на основном складе: " +
ПолучитьОстаткиТовара(Товар, Справочники.Склады.Основной));
КонецПроцедуры
⚠️ Внимание: При работе с запросами в функциях следите за производительностью. Если функция вызывается в цикле, лучше оптимизировать запрос или использовать временные таблицы.
FAQ: Ответы на частые вопросы
Можно ли в 1С создать функцию без параметров?
Да, функции могут не иметь параметров. Например:
Функция ПолучитьТекущуюДату()
Возврат ТекущаяДата();
КонецФункции
Но даже в этом случае обязательно должен присутствовать оператор Возврат.
Чем отличается процедура от метода объекта в 1С?
Процедура — это общий термин для блока кода. Метод — это процедура или функция, принадлежащая конкретному объекту (например, методу справочника НайтиПоНаименованию()). По сути, методы — это процедуры/функции, привязанные к классам 1С.
Как вернуть из функции несколько значений?
В 1С функция может возвращать только одно значение. Чтобы обойти это ограничение, используйте:
- 📦 Структуру:
Возврат Новый Структура("Поле1, Поле2", Значение1, Значение2); - 📦 Массив:
Возврат Новый Массив; Массив.Добавить(Значение1); Массив.Добавить(Значение2);
Можно ли вызвать функцию из процедуры и наоборот?
Да, это стандартная практика. Например:
Процедура ОбработатьЗаказ(Заказ)
Сумма = РассчитатьСуммуЗаказа(Заказ); // Вызов функции
Если Сумма > 1000 Тогда
ПрименитьСкидку(Заказ); // Вызов процедуры
КонецЕсли;
КонецПроцедуры
Как отладить функцию, которая возвращает неверный результат?
Используйте следующие приёмы:
- Добавьте вывод промежуточных значений через
Сообщить(). - Проверьте типы передаваемых параметров (например, число vs строка).
- Вызнесите логику функции в отдельный модуль и протестируйте на тестовых данных.
- Используйте отладчик 1С (точки останова, пошаговое выполнение).