Как вызвать экспортную процедуру внешнего отчета из регламентного задания в 1С?

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

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

Разбор основной причины проблемы

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

В контексте нашей проблемы важно то, что в безопасном режиме доступ к экспортным методам модуля объекта может быть ограничен или заблокирован, если система считает вызов небезопасным. Именно поэтому попытка вызвать лОтчет.СформироватьОтчет() приводит к тому, что платформа "не видит" этот метод. Выясним, как это исправить.

Решение: Отключение безопасного режима

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


// Получаем ссылку на внешний отчет из справочника
СсылкаНаОтчет = Справочники.ВнешниеОбработки.НайтиПоКоду("00001");

// Извлекаем двоичные данные файла из хранилища
ДвоичныеДанные = СсылкаНаОтчет.ХранилищеВнешнейОбработки.Получить();

// Создаем временный файл на сервере
ИмяФайла = ПолучитьИмяВременногоФайла("epf");
ДвоичныеДанные.Записать(ИмяФайла);

Попытка
    // Ключевой момент: второй параметр "Ложь" отключает безопасный режим
    ОбъектОтчета = ВнешниеОтчеты.Создать(ИмяФайла, Ложь);
    
    // Теперь экспортная процедура будет доступна
    ОбъектОтчета.СформироватьОтчет();
Исключение
    // Обязательно фиксируем ошибку в журнале регистрации
    ЗаписьЖурналаРегистрации("ВыполнениеОтчета", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;

// Очистка временного файла
УдалитьФайлы(ИмяФайла);

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

Использование метода Подключить для оптимизации

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

Разберем, почему это удобно:

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

Пример использования метода Подключить:


// Подключаем отчет и получаем его внутреннее имя
ИмяВПамяти = ВнешниеОтчеты.Подключить(ИмяФайла, , Ложь);

// Создаем объект, используя полученное имя
ОбъектОтчета = ВнешниеОтчеты.Создать(ИмяВПамяти);
ОбъектОтчета.СформироватьОтчет();

Нюансы выполнения на сервере и "Обычные формы"

Если ваш отчет был изначально разработан для "Обычных форм", при запуске в фоновом задании могут возникнуть дополнительные сложности. Выясним причины:

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

2. Директивы компиляции. Проверьте, чтобы ваша процедура СформироватьОтчет не была обернута в условия типа #Если Клиент Тогда. Для фонового задания код должен быть доступен серверу.

3. Работа с СКД. Если отчет построен на Системе компоновки данных, помните, что вызов простого метода модуля объекта не инициирует автоматический вывод в табличный документ, как это происходит при нажатии кнопки "Сформировать" в форме. Проанализируем, что должно быть внутри процедуры:


Процедура СформироватьОтчет() Экспорт
    // Инициализация схемы и настроек
    Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Подготовка макета компоновки
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки);
    
    // Выполнение компоновки
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
    
    // Вывод результата в таблицу или файл
    Результат = Новый ТабличныйДокумент;
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(Результат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
    // Сохранение результата, например, в PDF
    Результат.Записать("C:\Reports\Report.pdf", ТипФайлаТабличногоДокумента.PDF);
КонецПроцедуры

Важность очистки временных файлов

При использовании ПолучитьИмяВременногоФайла() 1С создает реальный файл в системной директории сервера. Посмотрим на типичную ошибку: если регламентное задание запускается каждые 5 минут и не удаляет за собой файлы, дисковое пространство на сервере может закончиться очень быстро.

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

Защита от опасных действий

Начиная с версии платформы 8.3.9, даже при отключении безопасного режима может сработать Защита от опасных действий. Это системное окно, которое спрашивает разрешение на запуск внешнего кода. В фоновом задании нажать "Да" некому, поэтому задание просто зависнет или упадет.

Чтобы этого избежать, выполните одно из действий:

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

← На главную