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

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

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

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

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

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

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

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

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

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

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

Типичные сценарии возникновения ошибки

Самый распространённый случай — присваивание результата процедуры переменной. Например, разработчик пишет Результат = ЗаписатьДокумент(Ссылка), а ЗаписатьДокумент объявлена как процедура. Платформа останавливает выполнение с сообщением об обращении к процедуре как к функции.

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

Ошибка при работе с объектами и экспортными методами

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

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

Присваивание результатаКод вида Переменная = Вызов()

Проверить, объявлен ли вызываемый метод как Функция, а не Процедура

Вызов в условииЕсли Вызов() Тогда

Убедиться, что метод возвращает булево значение через Возврат

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

Сравнить сигнатуру метода в новой версии конфигурации — тип мог измениться

Ошибка при вызове метода объектаОбъект.Метод() в выражении

Открыть модуль объекта и проверить объявление экспортного метода

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

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

Для поиска всех вызовов конкретного метода используйте глобальный поиск по конфигурации (Ctrl+Shift+F) с именем метода. Это особенно важно перед изменением сигнатуры: нужно заранее знать все места, где метод вызывается, чтобы оценить масштаб правок. Обращайте внимание на вызовы через Выполнить и Вычислить — их глобальный поиск не покажет, потому что имя метода там собирается строкой.

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

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

Способы исправления: что выбрать

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

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

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

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

Убрать присваивание результата

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

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

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

Создать отдельную функцию-обёртку

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

Особые случаи: типовые конфигурации, расширения и внешние компоненты

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

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

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

Проверка результата и профилактика ошибки

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

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

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

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

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

Синтаксическая проверка конфигурации
Норма

Проверка завершается без ошибок компиляции модулей

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

Сообщения о несоответствии типа вызова в других модулях

Выполнение сценария в режиме предприятия
Норма

Код отрабатывает, результат соответствует ожиданиям

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

Ошибка воспроизводится или функция возвращает Неопределено

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

Каждая ветка логики завершается оператором Возврат со значением

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

Есть ветки без Возврат — вызывающий код получит Неопределено

Места вызова изменённого метода
Норма

Глобальный поиск не находит вызовов с несовместимым использованием

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

Остались вызовы через Выполнить/Вычислить со старой логикой

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

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

Вторая распространённая ошибка — забыть про закрывающее слово. При смене Процедура на Функция нужно заменить и КонецПроцедуры на КонецФункции, иначе модуль не скомпилируется. Мелочь, но при спешке встречается регулярно.

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

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

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

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

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

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

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

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

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

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

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

Ошибка возникает только у одного пользователя. В чём причина?

Скорее всего, у этого пользователя выполняется ветка кода, недоступная остальным — из-за ролей, функциональных опций или данных. Воспроизведите сценарий под его сеансом с отладкой и проверьте стек вызовов: проблемный вызов находится в условной ветке.

Можно ли через расширение изменить процедуру типовой конфигурации на функцию?

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

Чем отличается эта ошибка от «Процедура или функция с указанным именем не определена»?

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