Как исправить ошибку «Метод объекта не обнаружен» при вызове функции модуля объекта во внешней обработке 1С?

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

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

Выясняем причину: почему платформа не видит экспортный метод?

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


&НаКлиенте
Процедура ЗагрузитьСписок(Команда)
    ТабДок = Новый ТабличныйДокумент;
    ТабДок = ВывестиДокумент(Объект.ДокументОтгулСписком, ТабДок);
    ТабДок.Показать();
КонецПроцедуры

&НаСервере
Функция ВывестиДокумент(ДокументОтгулСписком, ТабДок)
    Об = РеквизитФормыВЗначение("Объект");
    ТабДок = Об.СформироватьПечатнуюФормуЗдесь(ДокументОтгулСписком, ТабДок); 
    Возврат ТабДок;
КонецФункции

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


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

При вызове метода РеквизитФормыВЗначение("Объект") управляемая форма преобразует данные формы в полноценный прикладной объект внешней обработки на сервере. В этот момент происходит компиляция модуля объекта в контексте сервера. Если в процессе выполнения строки Об.СформироватьПечатнуюФормуЗдесь(...) система выбрасывает исключение «Метод объекта не обнаружен», это означает, что на сервере данный метод не скомпилировался.

Главным виновником этой ситуации выступают директивы препроцессора (инструкции условной компиляции). Если код функции в модуле объекта был ошибочно обернут в конструкцию:


#Если ТолстыйКлиентОбычноеПриложение Тогда
Функция СформироватьПечатнуюФормуЗдесь(СсылкаНаОбъект, ОбъектыПечати) Экспорт
    // ...
КонецФункции
#КонецЕсли

то в режиме тонкого клиента или при выполнении кода на сервере под управлением управляемого приложения этот кусок кода просто игнорируется компилятором. Для сервера этого метода физически не существует. Как только объект создается на сервере через РеквизитФормыВЗначение, платформа пытается найти метод в скомпилированном контексте и, не находя его, выдает ошибку.

Варианты решения проблемы

Проанализируем возможные варианты исправления этой ошибки в зависимости от архитектурных требований к вашей внешней обработке.

Вариант 1. Полное удаление ограничивающих директив

Если ваша внешняя обработка или печатная форма предназначена исключительно для работы в управляемом приложении (например, в современных конфигурациях БСП вроде ЗУП 3.1, ERP 2.5, БП 3.0), вам не требуются ограничения обычного приложения. Просто удалите инструкции условной компиляции:

  1. Откройте модуль объекта вашей внешней обработки.
  2. Найдите строки #Если ТолстыйКлиентОбычноеПриложение Тогда и соответствующую ей #КонецЕсли.
  3. Удалите их, оставив само тело функции и ключевое слово Экспорт доступными для компиляции в любых контекстах.

Вариант 2. Использование гибридной директивы компиляции

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


#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

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

#КонецЕсли

Такой подход гарантирует, что при вызове метода из серверного контекста управляемой формы (через РеквизитФормыВЗначение) компилятор сервера увидит и успешно выполнит экспортную функцию.

Очистка номеров и кодов: как правильно убрать префиксы и нули

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

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

Рассмотрим пример вывода табельного номера сотрудника на печать с использованием БСП:


ТабельныйНомерДляПечати = ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(Сотрудник.Код, Истина, Истина);

Использование стандартных функций БСП избавляет от необходимости тащить в модуль объекта тяжелые алгоритмы разбора строк и защищает код от непредвиденных ошибок при обновлении платформы или конфигурации.

Правильная методология отладки внешних печатных форм

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

Рекомендуется не просто вызывать произвольные процедуры вроде ВывестиДокумент, а эмулировать штатное поведение БСП. Посмотрим на пример реализации серверного метода тестовой формы отладки:


&НаСервере
Функция СформироватьПечатнуюФормуНаСервере(СсылкаНаДокумент)
    
    // Получаем объект внешней обработки для доступа к его модулю
    ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
    
    // Эмулируем параметры вызова БСП
    МассивОбъектов = Новый Массив;
    МассивОбъектов.Добавить(СсылкаНаДокумент);
    
    КоллекцияПечатныхФорм = УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм("ИмяМакетаПечатнойФормы");
    ОбъектыПечати = Новый СписокЗначений;
    ПараметрыВывода = УправлениеПечатью.ПодготовитьСтруктуруПараметровВывода();
    
    // Вызываем стандартную экспортную процедуру модуля объекта ВПФ
    ОбработкаОбъект.Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода);
    
    // Извлекаем сформированный табличный документ из коллекции
    Если КоллекцияПечатныхФорм.Количество() > 0 Тогда
        Возврат КоллекцияПечатныхФорм[0].ТабличныйДокумент;
    КонецЕсли;
    
    Возврат Неопределено;
    
КонецФункции

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

← На главную