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

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

Ошибка «обращение к процедуре как к функции» в 1С: как найти и исправить

Почему 1С выдаёт ошибку «обращение к процедуре как к функции», как найти проблемный вызов, исправить код и проверить результат. Примеры и разбор типичных ошибок.

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

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

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

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

Процедура — это метод, который выполняет действия, но не возвращает значение. Она объявляется ключевыми словами Процедура ... КонецПроцедуры и вызывается отдельным оператором. Внутри процедуры оператор Возврат; используется только для досрочного выхода, без передачи значения наружу.

Функция объявляется словами Функция ... КонецФункции и обязана вернуть значение через Возврат Значение;. Именно поэтому вызов функции можно встраивать в выражения: присваивания, условия, арифметические операции, параметры других методов. Платформа ожидает, что на месте вызова появится конкретное значение.

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

Типичные ситуации, в которых возникает ошибка

Чаще всего проблема появляется при прямом присваивании результата вызова: Статус = ЗаписатьДокумент(Ссылка);, где ЗаписатьДокумент — процедура. Автор кода ожидал логический признак успеха, но метод изначально ничего не возвращает.

Вторая частая ситуация — вызов внутри условия: Если ПроверитьЗаполнение(Объект) Тогда, когда ПроверитьЗаполнение объявлена процедурой. Третья — использование процедуры как аргумента: Сообщить(ПолучитьПредставление(Элемент)); при процедурном объявлении метода.

Ошибка после рефакторинга и переноса кода

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

Неявные случаи

Ошибка возникает и при обращении к методам объектов, которые по своей природе являются процедурами. Например, попытка написать Результат = ЗаписьJSON.Записать(); или присвоить результат ЗаполнитьЗначенияСвойств(). Перед использованием метода в выражении нужно свериться с синтакс-помощником: возвращает ли метод значение и какого типа.

ПрисваиваниеРезультат = Вызов(...)

Если метод — процедура, это ошибка

УсловиеЕсли Вызов(...) Тогда

Процедура не может быть условием

АргументМетод(Вызов(...))

Вложенный вызов процедуры запрещён

ФормулаА + Вызов(...)

Процедура не участвует в вычислениях

Как найти место ошибки

Первый инструмент — синтаксическая проверка модуля. В конфигураторе откройте модуль и выполните проверку через меню «Текст» или сочетание клавиш: платформа укажет строку с ошибочным обращением. Для поиска по всей конфигурации используйте «Конфигурация → Проверка конфигурации» с включённой проверкой логической целостности модулей.

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

При массовом рефакторинге полезен глобальный поиск по имени метода (Ctrl+Shift+F) с областью поиска «Вся конфигурация». Так вы найдёте все места вызова и проверите каждое: стоит ли вызов отдельным оператором или встроен в выражение.

Порядок действий при исправлении
  1. 1
    По тексту ошибки определите модуль и имя метода
  2. 2
    Откройте объявление метода и убедитесь, что это процедура
  3. 3
    Найдите все вызовы метода глобальным поиском
  4. 4
    В каждом вызове уберите присваивание либо измените объявление на функцию
  5. 5
    Выполните синтаксическую проверку модуля
  6. 6
    Прогоните сценарий в пользовательском режиме

Способы исправления

Есть два корректных пути, и выбор зависит от смысла метода. Если метод действительно только выполняет действие (записывает, отправляет, заполняет), оставьте его процедурой и исправьте вызов: вынесите его в отдельный оператор без присваивания.

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

Функция ЗаписатьДокумент(Ссылка) Экспорт

Попытка

ДокОбъект = Ссылка.ПолучитьОбъект();

ДокОбъект.Записать();

Возврат Истина;

Исключение

Возврат Ложь;

КонецПопытки;

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

Когда нельзя менять объявление метода

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

Два подхода к исправлению

Оставить процедуру, исправить вызов

Подходит, когда метод только выполняет действие. Минимальные изменения, не затрагивает других вызовов.

Превратить в функцию

Подходит, когда результат реально нужен вызывающему коду. Требует проверить все существующие вызовы метода — они продолжат работать, но логика возврата должна быть полной.

Проверка результата после исправления

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

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

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

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

Синтаксическая проверка модуля
Норма

Ошибок нет

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

Сообщение об обращении к процедуре

Проверка конфигурации целиком
Норма

Нет ошибок во всех модулях

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

Ошибки в других объектах

Запуск сценария в базе
Норма

Код выполняется, результат корректен

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

Исключение или неверное значение

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

Каждая ветка содержит Возврат

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

В части сценариев результат Неопределено

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

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

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

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

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

Простейшая профилактика — дисциплина именования и проверки. Давайте методам говорящие имена: глаголы действия для процедур (ЗаписатьДанные, ОтправитьПисьмо) и имена результата для функций (ПолучитьОстаток, ЭтоКорректныйКод). По имени вызова сразу видно, уместен ли он в выражении.

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

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

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

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

Почему ошибка появилась после обновления конфигурации, хотя мой код не менялся?

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

Ошибка возникает только у части пользователей, в чём причина?

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

Чем грозит функция без оператора Возврат?

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

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

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

Как быстро найти все такие ошибки в большой конфигурации?

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

Итог

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

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