Как программно открыть внешний отчет из файла (.erf) в 1С 8.3 на управляемых формах?

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

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

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

Для реализации этой задачи нам потребуются следующие объекты и функции платформы 1С:

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

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

Вариант 1: Простое открытие формы внешнего отчета по файлу

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

Рассмотрим алгоритм действий по шагам:

  1. Выбор файла отчета на клиенте: Сначала нам нужно предоставить пользователю возможность выбрать файл внешнего отчета (.erf) с локального диска. Для этого мы используем объект ДиалогВыбораФайла.
  2. Загрузка файла во временное хранилище на сервере: После выбора файла, его путь передается на сервер. На сервере мы читаем файл как двоичные данные и помещаем их во временное хранилище. Это позволяет платформе 1С получить доступ к содержимому отчета.
  3. Получение описания внешнего отчета: Используя адрес временного хранилища, мы вызываем метод ВнешниеОтчеты.ПолучитьМакетОбъектаВнешнегоОтчета(). Этот метод анализирует содержимое файла и возвращает объект, содержащий метаданные внешнего отчета, такие как его имя.
  4. Открытие формы отчета: Зная имя отчета из метаданных, мы формируем полный идентификатор формы (например, "Отчет.ИмяОтчета.ФормаОтчета") и вызываем ОткрытьФорму(). В параметры открытия передаем адрес во временном хранилище, чтобы платформа знала, откуда загружать отчет.

Давайте посмотрим на пример кода для реализации этого варианта. Мы определим две процедуры: одну клиентскую для выбора файла и одну серверную для загрузки и открытия отчета.


&НаСервере
// Функция ЗагрузитьИОткрытьВнешнийОтчет(ПутьКФайлуОтчета)
//   Загружает внешний отчет из указанного файла во временное хранилище и открывает его форму.
//   Параметры:
//     ПутьКФайлуОтчета (Строка) - Полный путь к файлу внешнего отчета (.erf).
//   Возвращаемое значение:
//     Истина, если отчет успешно загружен и открыт; Ложь в противном случае.
Функция ЗагрузитьИОткрытьВнешнийОтчет(ПутьКФайлуОтчета)

    // Проверяем существование файла. Это важно для корректной работы.
    Если Не ФайлСуществует(ПутьКФайлуОтчета) Тогда
        Сообщить("Файл отчета по указанному пути не найден: " + ПутьКФайлуОтчета);
        Возврат Ложь;
    КонецЕсли;

    // Загружаем отчет как двоичные данные и помещаем их во временное хранилище.
    // УникальныйИдентификатор используется, чтобы платформа могла отличить данный отчет от других.
    Попытка
        ДвоичныеДанныеОтчета = Новый ДвоичныеДанные(ПутьКФайлуОтчета);
        АдресВоВременномХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанныеОтчета, УникальныйИдентификатор);
    Исключение
        Сообщить("Не удалось загрузить файл отчета во временное хранилище: " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;

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

    // Формируем параметры для открытия формы.
    // 'АдресВнешнегоОтчета' - ключевой параметр, который сообщает платформе, где искать отчет.
    ПараметрыОткрытия = Новый Структура("АдресВнешнегоОтчета", АдресВоВременномХранилище);

    // Открываем форму отчета, используя его имя, полученное из метаданных.
    // 'ФормаОтчета' - это стандартное имя основной формы внешних отчетов.
    Попытка
        ОткрытьФорму("Отчет." + ОписаниеВнешнегоОтчета.Имя + ".ФормаОтчета", ПараметрыОткрытия);
        Возврат Истина;
    Исключение
        Сообщить("Не удалось открыть форму внешнего отчета: " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;

КонецФункции

&НаКлиенте
// Процедура ОткрытьОтчетНаКлиенте()
//   Клиентская процедура для выбора файла отчета и вызова серверной функции открытия.
Процедура ОткрытьОтчетНаКлиенте()
    // Создаем диалог выбора файла.
    ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    // Устанавливаем фильтр, чтобы пользователь видел только файлы .erf.
    ДиалогВыбораФайла.Фильтр = "Внешние отчеты (*.erf)|*.erf";
    // Устанавливаем заголовок диалога.
    ДиалогВыбораФайла.Заголовок = "Выберите файл внешнего отчета (.erf)";

    // Если пользователь выбрал файл, вызываем серверную функцию.
    Если ДиалогВыбораФайла.Выбрать() Тогда
        ЗагрузитьИОткрытьВнешнийОтчет(ДиалогВыбораФайла.ПолноеИмяФайла);
    КонецЕсли;
КонецПроцедуры

Мы видим, что этот код сначала запрашивает у пользователя путь к файлу внешнего отчета, затем передает этот путь на сервер, где происходит вся основная логика. Функция ЗагрузитьИОткрытьВнешнийОтчет обрабатывает загрузку файла, получение его метаданных и последующее открытие формы. Мы добавили проверки на существование файла и обработку возможных ошибок при загрузке и открытии, что делает код более надежным.

Вариант 2: Программное создание объекта внешнего отчета и установка параметров перед открытием

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

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

Рассмотрим алгоритм действий для этого варианта:

  1. Выбор файла отчета на клиенте: Как и в первом случае, мы начинаем с выбора файла отчета через ДиалогВыбораФайла на клиенте.
  2. Загрузка файла во временное хранилище на сервере: Аналогично первому варианту, файл отчета загружается во временное хранилище на сервере.
  3. Создание объекта внешнего отчета: На этом этапе мы используем метод ВнешниеОтчеты.Создать(АдресВоВременномХранилище, Истина). Важно передать второй параметр Истина, чтобы метод вернул именно объект отчета, а не просто менеджер.
  4. Установка параметров отчета: После получения объекта отчета мы можем обращаться к его свойствам и методам. Например, устанавливать значения для периода отчета, отборов или других настроек.
  5. Получение и открытие формы отчета: После того как все необходимые параметры установлены, мы получаем форму отчета с помощью метода объекта ПолучитьФорму() и открываем ее.

Давайте посмотрим на пример кода, демонстрирующий этот более гибкий подход.


&НаСервере
// Функция ЗагрузитьИОткрытьВнешнийОтчетСПараметрами(ПутьКФайлуОтчета)
//   Загружает внешний отчет, создает его объект, устанавливает параметры и открывает форму.
//   Параметры:
//     ПутьКФайлуОтчета (Строка) - Полный путь к файлу внешнего отчета (.erf).
//   Возвращаемое значение:
//     Истина, если отчет успешно загружен, параметры установлены и форма открыта; Ложь в противном случае.
Функция ЗагрузитьИОткрытьВнешнийОтчетСПараметрами(ПутьКФайлуОтчета)

    Если Не ФайлСуществует(ПутьКФайлуОтчета) Тогда
        Сообщить("Файл отчета по указанному пути не найден: " + ПутьКФайлуОтчета);
        Возврат Ложь;
    КонецЕсли;

    // Загружаем отчет как двоичные данные и помещаем их во временное хранилище.
    Попытка
        ДвоичныеДанныеОтчета = Новый ДвоичныеДанные(ПутьКФайлуОтчета);
        АдресВоВременномХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанныеОтчета, УникальныйИдентификатор);
    Исключение
        Сообщить("Не удалось загрузить файл отчета во временное хранилище: " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;

    // Создаем объект внешнего отчета. Второй параметр "Истина" обязателен,
    // чтобы получить именно объект отчета, а не менеджер.
    Попытка
        ОбъектВнешнегоОтчета = ВнешниеОтчеты.Создать(АдресВоВременномХранилище, Истина);
    Исключение
        Сообщить("Не удалось создать объект внешнего отчета. Возможно, файл поврежден или не является отчетом 1С: " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;

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

    // Получаем форму отчета из созданного объекта.
    Попытка
        ФормаОтчета = ОбъектВнешнегоОтчета.ПолучитьФорму();
        // Открываем полученную форму.
        ФормаОтчета.Открыть();
        Возврат Истина;
    Исключение
        Сообщить("Не удалось получить или открыть форму внешнего отчета: " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;

КонецФункции

&НаКлиенте
// Процедура ОткрытьОтчетНаКлиентеСПараметрами()
//   Клиентская процедура для выбора файла отчета и вызова серверной функции открытия с параметрами.
Процедура ОткрытьОтчетНаКлиентеСПараметрами()
    ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДиалогВыбораФайла.Фильтр = "Внешние отчеты (*.erf)|*.erf";
    ДиалогВыбораФайла.Заголовок = "Выберите файл внешнего отчета (.erf) для открытия с параметрами";

    Если ДиалогВыбораФайла.Выбрать() Тогда
        ЗагрузитьИОткрытьВнешнийОтчетСПараметрами(ДиалогВыбораФайла.ПолноеИмяФайла);
    КонецЕсли;
КонецПроцедуры

Этот вариант предоставляет гораздо большую гибкость. Мы не только открываем отчет, но и полностью контролируем его состояние до того, как он будет показан пользователю. Это особенно полезно в сценариях, когда отчет является частью более сложного бизнес-процесса, и его параметры должны быть заданы программно на основе контекста вызова.

Дополнительные соображения и рекомендации

При работе с внешними отчетами программным способом, мы должны учитывать несколько важных моментов:

  1. Безопасность: Загрузка и выполнение внешних отчетов всегда несет определенные риски безопасности. Убедитесь, что файлы .erf поступают из доверенных источников, чтобы избежать выполнения вредоносного кода.
  2. Очистка временного хранилища: Хотя платформа 1С обычно сама управляет очисткой временного хранилища, в некоторых случаях (например, при частой загрузке большого количества отчетов) может быть полезно явно удалять данные из хранилища после их использования с помощью функции УдалитьИзВременногоХранилища(), если мы уверены, что отчет больше не понадобится. Однако, в большинстве интерактивных сценариев это не является критичным, так как отчеты часто продолжают работать в текущем сеансе.
  3. Различные версии отчетов: Внешние отчеты могут быть разработаны для разных версий платформы 1С или разных конфигураций. Убедитесь, что загружаемый отчет совместим с вашей текущей версией платформы.
  4. Обработка ошибок: Мы уже включили блоки Попытка...Исключение...КонецПопытки в наши примеры. Это крайне важно для стабильной работы, так как загрузка внешнего файла может столкнуться с различными проблемами: файл не существует, файл поврежден, файл не является отчетом 1С, нет прав доступа и т.д. Информирование пользователя о причинах ошибки поможет ему быстрее разобраться с проблемой.
  5. Путь к файлу: При работе на клиенте путь к файлу берется с локального компьютера пользователя. При передаче на сервер, платформа сама обрабатывает передачу файла. Однако, если отчет находится на сервере, можно напрямую указывать серверный путь в Новый ДвоичныеДанные(ПутьКФайлуОтчета).

Таким образом, мы видим, что платформа 1С предоставляет достаточно гибкие механизмы для работы с внешними отчетами программным способом. Выбор конкретного подхода зависит от ваших задач: нужен ли вам просто просмотр отчета или полноценное взаимодействие с его программным объектом. Мы настоятельно рекомендуем использовать второй вариант, если вы планируете хоть какое-то программное воздействие на отчет, так как он обеспечивает максимальный контроль и гибкость.

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

← На главную