Допустимо ли использовать функции вместо процедур в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто у начинающих разработчиков, а также у программистов, пришедших в 1С из других языков (таких как JavaScript, Python или C#), возникает логичный вопрос: а обязательно ли разделять подпрограммы на процедуры и функции? Допустимо ли использовать функции вместо процедур, даже если возвращаемое значение нам не нужно? Рассмотрим этот вопрос подробно, проанализируем разницу в производительности, требования стандартов 1С и специфичные механизмы платформы.

Базовые отличия и вопрос производительности

Начнем с фундаментального определения, заложенного в платформу «1С:Предприятие»:

  1. Процедура — выполняет заданную последовательность действий и не возвращает результат в точку вызова.
  2. Функция — выполняет действия и обязательно возвращает результат с помощью оператора Возврат.

Разберем вопрос нагрузки на систему. Существует миф, что функции работают медленнее, так как компилятору необходимо выделять память под возвращаемый результат (обычно типа нетипизированного Variant), в то время как процедурам это не требуется. На практике, в современных реалиях платформы 1С, разница в скорости выполнения или потребления памяти между процедурой и функцией ничтожно мала. Если вы напишете тестовую обработку, прогоните идентичный код через процедуру и функцию миллион раз и сделаете замер производительности, вы убедитесь, что разница укладывается в погрешность случайного разброса. Таким образом, с технической точки зрения (исключительно в контексте базового вызова) они работают одинаково быстро.

Стандарты разработки 1С и чистота кода

Несмотря на отсутствие разницы в производительности, использовать функции вместо процедур «просто так» категорически не рекомендуется. Проанализируем почему.

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

Использование функции без обработки ее результата считается нарушением стандартов кодирования. Современные инструменты статического анализа кода (такие как SonarQube с плагином BSL, 1C:EDT или встроенный автоматический аудит) помечают вызов функции, результат которой не присвоен переменной, как ошибку стиля (Code Smell).

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


// Это вызовет синтаксическую ошибку, если методы являются процедурами
Результат = НашаПроцедура1() + НашаПроцедура2();

Когда функции незаменимы: архитектура платформы 1С

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

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

Паттерн возврата статуса (Альтернативная обработка ошибок)

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

Рассмотрим пример. Вместо классической процедуры:


Процедура ПровестиДокумент(ДокументСсылка, Отказ, ОписаниеОшибки)
    // алгоритм проведения
КонецПроцедуры

Разработчики используют функцию, возвращающую структуру или булево значение:


Функция ПровестиДокумент(ДокументСсылка)
    РезультатВыполнения = Новый Структура("Успех, ТекстОшибки", Истина, "");
    
    Попытка
        // алгоритм проведения
    Исключение
        РезультатВыполнения.Успех = Ложь;
        РезультатВыполнения.ТекстОшибки = ОписаниеОшибки();
    КонецПопытки;
    
    Возврат РезультатВыполнения;
КонецФункции

Такой подход позволяет вызывающему коду легко и элегантно обрабатывать результаты выполнения без нагромождения лишних переменных.

Изменение переменных внутри методов

Если вам нужно, чтобы метод изменил значение переданной переменной (например, модифицировал массив или структуру), вы можете использовать как процедуру, так и функцию. В 1С параметры по умолчанию передаются по ссылке (кроме примитивных типов в некоторых случаях, хотя объекты мутируют). Если вы хотите защитить переданную переменную от изменений внутри процедуры или функции, используйте ключевое слово Знач в объявлении параметров:


Процедура РасчетСуммы(Знач ИсходныеДанные)
    // Копия ИсходныеДанные, изменения не отразятся на оригинале
КонецПроцедуры

Итоги

Подведем итог. Использовать функции вместо процедур просто потому, что "так привычнее" — неверный путь в разработке на 1С. Это нарушает стандарты кода, усложняет его понимание другими программистами и вызывает срабатывание анализаторов качества кода.

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

← На главную