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