Разработка и Конфигурация · 12 мин
Ошибка 1С «Обращение к процедуре как к функции»: причины и способы исправления
Разбираем ошибку 1С «Обращение к процедуре как к функции»: почему возникает, как найти проблемный код, исправить объявление и вызов, типичные ошибки и FAQ.
Ошибка «Обращение к процедуре как к функции» — одно из самых частых сообщений синтаксической проверки в конфигураторе 1С. Она означает, что в коде вызывается процедура, но результат её выполнения присваивается переменной, участвует в выражении или передаётся как параметр — то есть код ожидает возвращаемое значение, которого процедура по определению не имеет.
Ошибка относится к разряду статических: платформа обнаруживает её ещё на этапе проверки модуля, до запуска кода. Это плюс — проблема не доходит до пользователей, если вы внимательно смотрите окно сообщений после сохранения модуля. Минус в том, что сообщение не всегда очевидно указывает, где именно нарушение: иногда виновата строка вызова, иногда — само объявление метода, а иногда — конфликт имён с методом общего модуля.
Ниже разобраны механика возникновения ошибки, способы быстро найти проблемное место, варианты исправления и типичные сценарии, в которых ошибка появляется даже у опытных разработчиков — например, при рефакторинге, копировании кода между модулями и работе с экспортными методами.
Что именно проверяет платформа и почему возникает ошибка
В языке 1С существует строгое разделение: процедура выполняет действия и не возвращает значение, функция обязана вернуть результат через оператор «Возврат». Синтаксический анализатор при проверке модуля сопоставляет каждый вызов с объявлением метода. Если вызов стоит справа от знака присваивания, внутри выражения, в условии «Если» или в списке фактических параметров другого вызова — анализатор требует, чтобы вызываемый метод был функцией.
Классический пример ошибочного кода:
Результат = ЗаполнитьДокумент(Ссылка); // ЗаполнитьДокумент объявлена как Процедура
Здесь компилятор видит: метод «ЗаполнитьДокумент» объявлен как процедура, значит, возвращаемого значения нет, и присваивать нечего. В окне сообщений появляется текст «Обращение к процедуре как к функции» с указанием модуля и строки.
Важно понимать: ошибка привязана к месту вызова, а не к месту объявления. Поэтому первый шаг диагностики — посмотреть на строку из сообщения об ошибке, а уже потом переходить к объявлению метода, чтобы понять, что было задумано изначально.
Как быстро найти проблемное место в модуле
Двойной щелчок по сообщению об ошибке в окне сообщений конфигуратора переносит курсор на строку с некорректным вызовом. Это работает и при проверке модуля вручную (команда «Конфигурация — Проверка конфигурации» или проверка модуля через контекстное меню), и при автоматической проверке при сохранении.
Если вызовов одноимённого метода много, а сообщение появилось одно — проблема в конкретной строке. Найдите объявление метода через «Правка — Найти» по тексту «Процедура ИмяМетода» или через список процедур и функций модуля (выпадающий список в верхней части редактора модуля либо панель «Процедуры и функции»).
Отдельный случай — метод находится в общем модуле или модуле менеджера объекта. Тогда поиск объявления нужно вести по всей конфигурации: Ctrl+Shift+F, режим поиска по всем модулям, шаблон «Процедура ИмяМетода(». Это особенно актуально в типовых конфигурациях, где одноимённые методы могут существовать в нескольких общих модулях.
- 1Дважды щёлкните по сообщению об ошибке, чтобы перейти к строке вызова
- 2Определите, какой метод вызывается и откуда ожидается результат
- 3Найдите объявление метода: Процедура или Функция
- 4Решите, что неверно: вызов или объявление
- 5Исправьте код и повторите проверку модуля
Способ 1: исправить место вызова
Если метод по смыслу ничего возвращать не должен — например, он записывает объект, выводит сообщение или заполняет табличную часть — правильное исправление находится в точке вызова. Уберите присваивание и вызовите процедуру отдельным оператором:
// Было (ошибка):
Результат = ЗаписатьДокумент(ДокументОбъект);
// Стало:
ЗаписатьДокумент(ДокументОбъект);
Тот же принцип применяется, когда вызов процедуры оказался внутри условия или выражения. Например, конструкция «Если ЗаписатьОбъект(Объект) Тогда» некорректна для процедуры — её нужно переписать: вызвать процедуру отдельно, а условие строить на проверяемых данных, а не на результате вызова.
Частая разновидность — процедура передана как параметр другого метода: «Сообщить(ФорматироватьСумму(Сумма))». Если «ФорматироватьСумму» — процедура, выражение не имеет значения, и ошибка неизбежна. Либо метод должен стать функцией, либо результат нужно получать иным способом.
Способ 2: превратить процедуру в функцию
Если по логике задачи метод должен возвращать результат — успешность операции, вычисленное значение, ссылку на созданный объект — тогда исправляется объявление. Замените ключевое слово «Процедура» на «Функция», «КонецПроцедуры» на «КонецФункции» и добавьте оператор «Возврат» с результатом:
Функция ЗаписатьДокумент(ДокументОбъект) Экспорт
Попытка
ДокументОбъект.Записать();
Возврат Истина;
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункции
Обратите внимание: функция должна возвращать значение на всех путях выполнения. Если в какой-то ветке кода «Возврат» отсутствует, функция вернёт «Неопределено» — это не вызовет синтаксической ошибки, но может привести к трудноуловимым логическим сбоям в местах вызова.
Типичные сценарии, в которых появляется ошибка
Копирование кода между модулями
Самый частый источник — фрагмент кода скопирован из модуля, где метод был функцией, в модуль, где одноимённый метод объявлен процедурой, или где метода нет вовсе и разработчик создал его «по памяти» как процедуру. Вызов остался в форме присваивания — и проверка модуля сразу это показывает.
Рефакторинг с изменением типа метода
При рефакторинге функцию превратили в процедуру (например, результат перестали использовать), но забыли поправить один из вызовов. Глобальный поиск по имени метода после любого изменения сигнатуры — обязательное действие, иначе ошибка всплывёт при следующей проверке конфигурации.
Конфликт с методом общего модуля
Если в общем модуле есть экспортная процедура с тем же именем, что и локальная функция (или наоборот), разрешение имени может пойти не туда, куда вы ожидали. Проверьте, не перекрывает ли имя метод из подключённого общего модуля, и при необходимости вызывайте метод явно: «ИмяОбщегоМодуля.ИмяМетода(…)».
Обработчики событий и команды
Обработчики событий формы и команды по умолчанию создаются как процедуры. Если разработчик пытается использовать обработчик как функцию — например, в выражении ожидается результат обработчика ожидания или произвольного обработчика — возникает та же ошибка. Обработчики должны оставаться процедурами; результат передаётся через параметры, реквизиты формы или дополнительные описания оповещений.
Как проверить, что исправление корректно
После правки выполните синтаксическую проверку модуля: сообщение «Обращение к процедуре как к функции» должно исчезнуть, а новых ошибок появиться не должно. Затем запустите проверку конфигурации целиком — если метод экспортный и вызывается из других модулей, ошибки могут проявиться именно там.
Далее — функциональная проверка: выполните сценарий, в котором задействован исправленный код, и убедитесь, что результат соответствует ожиданию. Если процедура превращена в функцию, проверьте значение, которое она возвращает, в отладчике: поставьте точку останова на операторе «Возврат» и посмотрите фактическое значение.
Как проверить результат
Ошибок нет, сообщение исчезло
Ошибка осталась или появилась в другой строке — не все вызовы исправлены
Переменная получает ожидаемое значение
Переменная равна Неопределено — в функции есть ветка без «Возврат»
Проверка конфигурации проходит без ошибок
Ошибки в модулях, вызывающих изменённый метод
Альтернативы: когда менять тип метода не нужно
Иногда ни один из двух способов не подходит: вызов менять нельзя (код чужой или типовой), а процедуру в функцию превращать опасно. В таких случаях результат можно передать через параметр по значению «по ссылке» (параметр с ключевым словом «Знач» отсутствует — изменения параметра внутри процедуры видны снаружи для изменяемых типов), через реквизит объекта или формы, либо через структуру, которую процедура заполняет.
Другой вариант — обернуть вызов: создать новую функцию, которая вызывает существующую процедуру и возвращает нужный результат, вычисленный по состоянию после вызова. Это безопасно для типового кода: исходный метод не трогается, а новая функция размещается в вашем общем модуле или расширении.
Как выбрать способ исправления
Профилактика: как не допускать ошибку в будущем
Главная привычка — запускать синтаксическую проверку модуля после каждой правки, а не перед обновлением базы. Ошибка ловится мгновенно, и контекст правки ещё свеж в памяти. Вторая привычка — после любого изменения сигнатуры метода (тип, имя, состав параметров) выполнять глобальный поиск по имени метода и просматривать все места вызова.
Полезно также придерживаться соглашения об именовании: имена функций должны намекать на возвращаемое значение («ПолучитьОстаток», «ЭтоПроведённыйДокумент», «НайтиКонтрагента»), а имена процедур — на действие («ЗаписатьДокумент», «ЗаполнитьТабличнуюЧасть»). Тогда несоответствие вызова и объявления заметно уже при чтении кода, до проверки модулей.
Что важно запомнить
Ошибка «Обращение к процедуре как к функции» означает, что вызов процедуры стоит там, где требуется значение. Решение — либо исправить вызов, либо превратить метод в функцию с гарантированным «Возврат». После правки проверьте модуль, всю конфигурацию и фактическое поведение кода.
FAQ
Появляется ли эта ошибка в режиме Предприятия, а не только в конфигураторе?
Как правило, нет: это статическая ошибка, которую платформа отсекает при проверке модуля. Если конфигурация с такой ошибкой каким-то образом попала в рабочую базу (например, проверка была отключена), выполнение кода завершится исключением в момент компиляции модуля при первом обращении к нему.
Можно ли вызвать функцию как процедуру, не используя результат?
Да, это разрешено: вызов функции отдельным оператором без присваивания корректен, возвращаемое значение просто игнорируется. Обратная ситуация — вызов процедуры как функции — запрещена, в этом и суть разбираемой ошибки.
Почему ошибка указывает на строку, где всё выглядит правильно?
Чаще всего вызываемый метод оказывается не тем, что вы ожидаете: одноимённая процедура в общем модуле перекрывает функцию, или метод был изменён при обновлении конфигурации. Найдите фактическое объявление метода через глобальный поиск и сверьте его тип.
Что делать, если метод сотни раз вызывается в конфигурации?
Не меняйте тип метода — это потребует проверки всех вызовов. Безопаснее исправить один проблемный вызов или создать функцию-обёртку с другим именем, которая вызывает процедуру и возвращает нужный результат.
Влияет ли директива компиляции (&НаСервере, &НаКлиенте) на эту ошибку?
Нет, ошибка не зависит от контекста исполнения. Но похожая ситуация возникает, когда клиентский код вызывает серверную процедуру, объявленную без директивы или с несовместимой директивой, — это уже другая ошибка, о недоступности метода в данном контексте.
Можно ли отключить эту проверку, чтобы код сохранялся?
Отключить конкретно эту диагностику штатно нельзя, и делать это не стоило бы в любом случае: код с такой ошибкой неработоспособен. Правильный путь — исправить несоответствие между вызовом и объявлением метода.