При разработке программных решений на платформе 1С разработчики часто сталкиваются с ситуацией, когда экспортный метод модуля объекта отчета без проблем вызывается в одном контексте (например, при закуске в толстом клиенте), но выдает исключение при вызове из общего модуля на сервере или из регламентного задания. В этом материале разберем по шагам, почему возникает ошибка «Метод объекта не обнаружен», проанализируем роль условий препроцессора и рассмотреем способы правильной организации программного формирования отчетов.
Рассмотрим стандартный пример кода в серверном общем модуле или регламентном задании, вызывающем экспортный метод объекта отчета:
ОтчетОбъект = Отчеты.НужныйОтчет.Создать();
ОтчетОбъект.СформироватьОтчет();
При выполнении этого кода платформа выбрасывает ошибку, утверждающую, что метод СформироватьОтчет не обнаружен у созданного объекта. При этом в самом модуле объекта отчета функция объявлена корректно и имеет ключевое слово Экспорт.
Проанализируем ключевой фактор, который чаще всего приводит к подобной проблеме. Модуль объекта может содержать инструкцию препроцессора, ограничивающую области компиляции кода:
#Если ТолстыйКлиентОбычноеПриложение Тогда
Функция СформироватьОтчет() Экспорт
// Алгоритм формирования отчета
КонецФункции
#КонецЕсли
Выясним, что происходит при таком объявлении:
ТолстыйКлиентОбычноеПриложение. Код успешно компилируется, и метод становится доступен.Сервер и Вызов сервера) или из регламентного задания, исполнение кода выполняется строго на сервере приложений 1С.#Если ТолстыйКлиентОбычноеПриложение на сервере принимает значение Ложь. В результате платформа полностью исключает содержимое данного блока из компиляции на сервере.СформироватьОтчет, что и вызывает ошибку исполнения.Рассмотрим другие частые причины, из-за которых экспортный метод модуля объекта может быть недоступен на сервере:
Экспорт: Процедура или функция объявлена в модуле объекта как локальная (например, Процедура СформироватьОтчет() вместо Процедура СформироватьОтчет() Экспорт).#Если НаКлиенте Тогда, #Если Клиент Тогда или #Если НЕ Сервер Тогда вокруг процедуры.Предупреждение, Вопрос) или обращение к клиентским элементам интерфейса, модуль не скомпилируется в неинтерактивном серверном контексте (фоновые и регламентные задания).Разберем по шагам, как исправить проблему в зависимости от архитектуры вашего решения.
Если код формирования отчета не содержит клиентских вызовов и диалогов, удалим или скорректируем ограничивающие условия препроцессора вокруг метода. Откроем модуль объекта отчета и убедимся, что процедура доступна на сервере:
Функция СформироватьОтчет() Экспорт
// Алгоритм, работающий с данными на сервере
КонецФункции
Если часть кода отчета действительно предназначена только для клиента (например, работа с формами), вынесем интерфейсное взаимодействие в модуль формы, оставив в модуле объекта только чистую бизнес-логику работы с данными.
Если для выполнения алгоритма не требуется хранить состояние конкретного экземпляра отчета, вынесем метод в модуль менеджера. В таком случае вызвать процедуру или функцию можно напрямую без вызова метода Создать():
// В модуле менеджера отчета:
Функция СформироватьОтчетСервер() Экспорт
// Логика формирования
КонецФункции
// Вызов из общего модуля:
Отчеты.НужныйОтчет.СформироватьОтчетСервер();
Для фоновых и регламентных заданий рекомендуем использовать стандартные объекты платформы для работы со Схемой компоновки данных. Рассмотрим пример стандартного формирования отчета в ТабличныйДокумент на сервере:
ОтчетОбъект = Отчеты.НужныйОтчет.Создать();
СхемаКомпоновки = ОтчетОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = СхемаКомпоновки.НастройкиПоУмолчанию;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ТабличныйДокумент = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Таким образом, всегда проверяйте контекст исполнения кода и инструкции препроцессора. Это позволит избежать ошибок компиляции при вызове методов объектов 1С в серверных модулях и фоновых заданиях.