Почему возникает ошибка «Метод объекта не обнаружен» при вызове процедуры документа из регламентного задания?

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

При разработке и сопровождении конфигураций 1С разработчики нередко сталкиваются с ситуацией: в коде создается объект прикладного типа (например, документ или справочник), после чего происходит обращение к его экспортной процедуре, объявленной в модуле объекта. В интерактивном режиме под толстым клиентом или внешней обработкой код выполняется без замечаний, однако при запуске той же логики через регламентное задание платформа генерирует исключение «Метод объекта не обнаружен».

Разберем детально, почему возникает подобное поведение платформы, как локализовать причину и правильно адаптировать код модулей объектов для работы в фоновых заданиях.

Анализ проблемы и механизма исполнения

Рассмотрим типовой сценарий, в котором возникает ошибка. В общем модуле описана процедура, вызываемая регламентным заданием:


Процедура ВыполнитьРегламентнуюОтправку() Экспорт
    ЭлПисьмо = Документы.ЭлектронноеПисьмо.СоздатьДокумент();
    // Заполнение реквизитов документа
    ЭлПисьмо.ОтправитьПисьмо();
КонецПроцедуры

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

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


#Если Клиент Тогда
Процедура ОтправитьПисьмо(ФормаПисьма = Неопределено) Экспорт
    // Исполняемый код отправки
КонецПроцедуры
#КонецЕсли

В этом случае при компиляции на сервере весь блок кода внутри #Если Клиент Тогда просто отсекается. Для серверного контекста фонового задания такой процедуры в составе объекта не существует, что и приводит к ошибке времени выполнения «Метод объекта не обнаружен».

Пошаговая диагностика и поиск скрытых блоков препроцессора

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

  1. Проверка исходного кода модуля объекта: открываем модуль объекта документа и выполняем поиск инструкций #Если, #ИначеЕсли, #Иначе и #КонецЕсли. Особое внимание следует обратить на блоки #Если Клиент Тогда, #Если ТолстыйКлиентОбычноеПриложение Тогда и незакрытые директивы препроцессора в предшествующих процедурах модуля.
  2. Синтаксический контроль в контексте сервера: стандартная быстрая проверка модуля в Конфигураторе проверяет код в контексте текущего режима разработки. Чтобы увидеть ошибки сервера, перейдем в меню Конфигурация → Проверка конфигурации... и отметим флаги Сервер, Внешнее соединение и Фоновое задание.
  3. Анализ прав доступа: убедимся, что у пользователя, под которым назначено исполнение регламентного задания, присутствуют достаточные права на чтение, изменение и интерактивные операции с данным объектом метаданных.

Варианты правильного решения

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

Способ 1. Корректировка инструкций препроцессора

Если алгоритм процедуры не содержит интерактивных вызовов (таких как предупреждения, вопросы пользователю или открытие экранных форм), процедуру необходимо сделать доступной на сервере, удалив обрамляющую директиву #Если Клиент Тогда или заменив её условием:


#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
Процедура ОтправитьПисьмо() Экспорт
    // Бизнес-логика, не зависящая от интерфейса
    СтатусПисьма = Перечисления.СтатусыПисем.Отправленное;
    ЭтотОбъект.Записать();
КонецПроцедуры
#КонецЕсли

Важно: в модулях объектов и менеджеров директивы компиляции вида &НаСервере или &НаКлиенте не используются — они предназначены исключительно для модулей управляемых форм и команд.

Способ 2. Разделение серверной логики и интерфейсных вызовов

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


// Процедура доступна на клиенте и сервере
Процедура ВыполнитьОтправкуНаСервере() Экспорт
    // Формирование и отправка почтового сообщения через ИнтернетПочта
    ПочтовыйПрофиль = Новый ИнтернетПочтовыйПрофиль;
    // Заполнение параметров профиля...
    Почта = Новый ИнтернетПочта;
    Почта.Подключиться(ПочтовыйПрофиль);
    // Отправка...
    Почта.Отключиться();
КонецПроцедуры

#Если Клиент Тогда
Процедура ОтправитьПисьмоИнтерактивно(ФормаПисьма = Неопределено) Экспорт
    ВыполнитьОтправкуНаСервере();
    Если ФормаПисьма <> Неопределено Тогда
        ФормаПисьма.Обновить();
    КонецЕсли;
КонецПроцедуры
#КонецЕсли

Способ 3. Вынос логики в модуль менеджера или общий модуль

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


// В общем модуле или модуле менеджера
Процедура СформироватьИОтправить(СсылкаНаДокумент) Экспорт
    ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
    ДокументОбъект.Заполнить();
    ДокументОбъект.Записать();
КонецПроцедуры

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

← На главную