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

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

Ошибка 1С «Обращение к процедуре как к функции»: причины и способы исправления

Разбираем ошибку 1С «Обращение к процедуре как к функции»: почему возникает, как найти проблемный код, исправить объявление и вызов, типичные ошибки и FAQ.

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

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

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

Что именно проверяет платформа и почему возникает ошибка

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

Классический пример ошибочного кода:

Результат = ЗаполнитьДокумент(Ссылка); // ЗаполнитьДокумент объявлена как Процедура

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

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

Как быстро найти проблемное место в модуле

Двойной щелчок по сообщению об ошибке в окне сообщений конфигуратора переносит курсор на строку с некорректным вызовом. Это работает и при проверке модуля вручную (команда «Конфигурация — Проверка конфигурации» или проверка модуля через контекстное меню), и при автоматической проверке при сохранении.

Если вызовов одноимённого метода много, а сообщение появилось одно — проблема в конкретной строке. Найдите объявление метода через «Правка — Найти» по тексту «Процедура ИмяМетода» или через список процедур и функций модуля (выпадающий список в верхней части редактора модуля либо панель «Процедуры и функции»).

Отдельный случай — метод находится в общем модуле или модуле менеджера объекта. Тогда поиск объявления нужно вести по всей конфигурации: Ctrl+Shift+F, режим поиска по всем модулям, шаблон «Процедура ИмяМетода(». Это особенно актуально в типовых конфигурациях, где одноимённые методы могут существовать в нескольких общих модулях.

Порядок диагностики
  1. 1
    Дважды щёлкните по сообщению об ошибке, чтобы перейти к строке вызова
  2. 2
    Определите, какой метод вызывается и откуда ожидается результат
  3. 3
    Найдите объявление метода: Процедура или Функция
  4. 4
    Решите, что неверно: вызов или объявление
  5. 5
    Исправьте код и повторите проверку модуля

Способ 1: исправить место вызова

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

// Было (ошибка):

Результат = ЗаписатьДокумент(ДокументОбъект);

// Стало:

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

Тот же принцип применяется, когда вызов процедуры оказался внутри условия или выражения. Например, конструкция «Если ЗаписатьОбъект(Объект) Тогда» некорректна для процедуры — её нужно переписать: вызвать процедуру отдельно, а условие строить на проверяемых данных, а не на результате вызова.

Частая разновидность — процедура передана как параметр другого метода: «Сообщить(ФорматироватьСумму(Сумма))». Если «ФорматироватьСумму» — процедура, выражение не имеет значения, и ошибка неизбежна. Либо метод должен стать функцией, либо результат нужно получать иным способом.

Способ 2: превратить процедуру в функцию

Если по логике задачи метод должен возвращать результат — успешность операции, вычисленное значение, ссылку на созданный объект — тогда исправляется объявление. Замените ключевое слово «Процедура» на «Функция», «КонецПроцедуры» на «КонецФункции» и добавьте оператор «Возврат» с результатом:

Функция ЗаписатьДокумент(ДокументОбъект) Экспорт

Попытка

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

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

Исключение

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

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

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

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

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

Копирование кода между модулями

Самый частый источник — фрагмент кода скопирован из модуля, где метод был функцией, в модуль, где одноимённый метод объявлен процедурой, или где метода нет вовсе и разработчик создал его «по памяти» как процедуру. Вызов остался в форме присваивания — и проверка модуля сразу это показывает.

Рефакторинг с изменением типа метода

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

Конфликт с методом общего модуля

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

Обработчики событий и команды

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

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

Как проверить, что исправление корректно

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

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

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

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

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

Ошибок нет, сообщение исчезло

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

Ошибка осталась или появилась в другой строке — не все вызовы исправлены

Значение в точке вызова
Норма

Переменная получает ожидаемое значение

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

Переменная равна Неопределено — в функции есть ветка без «Возврат»

Другие модули
Норма

Проверка конфигурации проходит без ошибок

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

Ошибки в модулях, вызывающих изменённый метод

Альтернативы: когда менять тип метода не нужно

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

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

Маршрут решения

Как выбрать способ исправления

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

Профилактика: как не допускать ошибку в будущем

Главная привычка — запускать синтаксическую проверку модуля после каждой правки, а не перед обновлением базы. Ошибка ловится мгновенно, и контекст правки ещё свеж в памяти. Вторая привычка — после любого изменения сигнатуры метода (тип, имя, состав параметров) выполнять глобальный поиск по имени метода и просматривать все места вызова.

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

Итог

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

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

FAQ

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

Как правило, нет: это статическая ошибка, которую платформа отсекает при проверке модуля. Если конфигурация с такой ошибкой каким-то образом попала в рабочую базу (например, проверка была отключена), выполнение кода завершится исключением в момент компиляции модуля при первом обращении к нему.

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

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

Почему ошибка указывает на строку, где всё выглядит правильно?

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

Что делать, если метод сотни раз вызывается в конфигурации?

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

Влияет ли директива компиляции (&НаСервере, &НаКлиенте) на эту ошибку?

Нет, ошибка не зависит от контекста исполнения. Но похожая ситуация возникает, когда клиентский код вызывает серверную процедуру, объявленную без директивы или с несовместимой директивой, — это уже другая ошибка, о недоступности метода в данном контексте.

Можно ли отключить эту проверку, чтобы код сохранялся?

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