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