Часто у начинающих разработчиков, а также у программистов, пришедших в 1С из других языков (таких как JavaScript, Python или C#), возникает логичный вопрос: а обязательно ли разделять подпрограммы на процедуры и функции? Допустимо ли использовать функции вместо процедур, даже если возвращаемое значение нам не нужно? Рассмотрим этот вопрос подробно, проанализируем разницу в производительности, требования стандартов 1С и специфичные механизмы платформы.
Начнем с фундаментального определения, заложенного в платформу «1С:Предприятие»:
Возврат.Разберем вопрос нагрузки на систему. Существует миф, что функции работают медленнее, так как компилятору необходимо выделять память под возвращаемый результат (обычно типа нетипизированного Variant), в то время как процедурам это не требуется. На практике, в современных реалиях платформы 1С, разница в скорости выполнения или потребления памяти между процедурой и функцией ничтожно мала. Если вы напишете тестовую обработку, прогоните идентичный код через процедуру и функцию миллион раз и сделаете замер производительности, вы убедитесь, что разница укладывается в погрешность случайного разброса. Таким образом, с технической точки зрения (исключительно в контексте базового вызова) они работают одинаково быстро.
Несмотря на отсутствие разницы в производительности, использовать функции вместо процедур «просто так» категорически не рекомендуется. Проанализируем почему.
Официальные стандарты 1С («Система стандартов и методик разработки конфигураций») требуют строгого смыслового разделения подпрограмм. Если алгоритм просто выполняет действие (например, записывает документ, очищает таблицу или отправляет письмо) и не должен ничего возвращать, он обязательно должен быть оформлен как Процедура.
Использование функции без обработки ее результата считается нарушением стандартов кодирования. Современные инструменты статического анализа кода (такие как SonarQube с плагином BSL, 1C:EDT или встроенный автоматический аудит) помечают вызов функции, результат которой не присвоен переменной, как ошибку стиля (Code Smell).
Рассмотрим, как это влияет на читаемость кода. Когда программист видит вызов процедуры, он сразу понимает, что метод просто выполняет работу. Если же он видит вызов функции, он ожидает, что метод что-то вычислил и это значение нужно использовать. Процедура также защищает вас от логических ошибок при написании сложных выражений. Например, платформа просто не позволит вам написать синтаксически неверный код вроде:
// Это вызовет синтаксическую ошибку, если методы являются процедурами
Результат = НашаПроцедура1() + НашаПроцедура2();
Посмотрим на ситуации, когда платформа 1С технически требует использования именно функций. Разделение на процедуры и функции в 1С — это не только синтаксический сахар, но и жесткая привязка к внутренним механизмам.
Shift+F9). В этом окне платформа может выполнить код и показать результат. Вызвать там функцию — можно, а вот вызвать процедуру платформа не позволит, выдав синтаксическую ошибку.Вычислить(), куда передаете строку с кодом, этот код должен вернуть значение. Следовательно, внутри строки могут вызываться только функции. Процедура Выполнить() дает больше свободы, но часто запрещена из соображений безопасности в облачных средах.Разберем интересный подход, когда процедуры осознанно заменяют функциями для улучшения архитектуры. В сложных системах, таких как БСП (Библиотека стандартных подсистем), разработчики часто уходят от использования процедур с множеством параметров Отказ или ТекстОшибки. Вместо этого они создают функции, которые выполняют действие и возвращают статус успешности.
Рассмотрим пример. Вместо классической процедуры:
Процедура ПровестиДокумент(ДокументСсылка, Отказ, ОписаниеОшибки)
// алгоритм проведения
КонецПроцедуры
Разработчики используют функцию, возвращающую структуру или булево значение:
Функция ПровестиДокумент(ДокументСсылка)
РезультатВыполнения = Новый Структура("Успех, ТекстОшибки", Истина, "");
Попытка
// алгоритм проведения
Исключение
РезультатВыполнения.Успех = Ложь;
РезультатВыполнения.ТекстОшибки = ОписаниеОшибки();
КонецПопытки;
Возврат РезультатВыполнения;
КонецФункции
Такой подход позволяет вызывающему коду легко и элегантно обрабатывать результаты выполнения без нагромождения лишних переменных.
Если вам нужно, чтобы метод изменил значение переданной переменной (например, модифицировал массив или структуру), вы можете использовать как процедуру, так и функцию. В 1С параметры по умолчанию передаются по ссылке (кроме примитивных типов в некоторых случаях, хотя объекты мутируют). Если вы хотите защитить переданную переменную от изменений внутри процедуры или функции, используйте ключевое слово Знач в объявлении параметров:
Процедура РасчетСуммы(Знач ИсходныеДанные)
// Копия ИсходныеДанные, изменения не отразятся на оригинале
КонецПроцедуры
Подведем итог. Использовать функции вместо процедур просто потому, что "так привычнее" — неверный путь в разработке на 1С. Это нарушает стандарты кода, усложняет его понимание другими программистами и вызывает срабатывание анализаторов качества кода.
Используйте Процедуры для методов, которые инкапсулируют действия (создание, удаление, изменение интерфейса), и применяйте Функции там, где необходимо вычислить и вернуть результат, закэшировать данные, использовать метод в СКД или реализовать паттерн безопасного возврата статуса операции.