Задача сборки и разборки внешних отчетов и обработок в режиме «Предприятие» (без интерактивного использования Конфигуратора) часто возникает при автоматизации процессов разработки, реализации систем автообновления или при создании динамических инструментов генерации отчетности. В этой статье мы подробно разберем, как устроены файлы .erf и .epf, и какими инструментами можно реализовать их разборку на составляющие (схему компоновки, модули, формы) и обратную сборку.
Прежде чем переходить к инструментам, проанализируем структуру файлов. Внешние отчеты 1С представляют собой так называемые Compound Files (составные файлы). Это структурированные хранилища, внутри которых находятся потоки данных, сжатые по алгоритму, близкому к Deflate, но имеющему свои особенности реализации в платформе 1С.
Внутри типичного файла .erf (внешний отчет) можно выделить следующие ключевые элементы:
Сложность «чистой» реализации на встроенном языке 1С заключается в необходимости вручную формировать заголовки контейнера и корректно упаковывать данные. Поэтому рассмотрим наиболее эффективные практические способы решения этой задачи.
Одним из самых надежных способов является использование внешней консольной утилиты v8pack. Она написана на языке Go, работает чрезвычайно быстро и не требует наличия установленного Конфигуратора или лицензий 1С на сервере, где происходит сборка.
Разберем алгоритм взаимодействия с этой утилитой из кода 1С. Допустим, нам нужно разобрать отчет для изменения текста модуля.
Сначала выполним разборку:
ПутьКУтилите = "C:\Tools\v8pack.exe";
ПутьКФайлуОтчета = "C:\Work\MyReport.erf";
КаталогВыгрузки = "C:\Work\UnpackedReport\";
// Команда для разборки
Команда = СтрШаблон("%1 unpack --input ""%2"" --output ""%3""", ПутьКУтилите, ПутьКФайлуОтчета, КаталогВыгрузки);
ЗапуститьПриложение(Команда, , Истина);
После выполнения этой команды в каталоге появятся файлы, соответствующие внутренним потокам отчета. Мы можем программно изменить файл с модулем объекта или XML-файл схемы компоновки данных. Рассмотрим, как собрать отчет обратно:
// Команда для сборки
КомандаСборки = СтрШаблон("%1 pack --input ""%2"" --output ""%3""", ПутьКУтилите, КаталогВыгрузки, "C:\Work\NewReport.erf");
ЗапуститьПриложение(КомандаСборки, , Истина);
Этот метод идеален для серверных задач, так как v8pack корректно обрабатывает структуру контейнера и гарантирует, что полученный файл будет открываться платформой без ошибок.
Если ваша инфраструктура поддерживает OneScript, мы рекомендуем обратить внимание на проект precommit1c. Этот инструмент изначально создавался для декомпозиции файлов 1С перед помещением в системы контроля версий (Git), но он отлично справляется и с обратной задачей.
Преимущество этого метода в том, что он написан на языке, максимально близком к 1С, и позволяет тонко настраивать процесс разборки. Скрипт анализирует внутренние GUID-ы потоков и дает им человекочитаемые имена (например, ObjectModule.bsl вместо непонятных буквенно-цифровых имен).
Процесс вызова из 1С будет выглядеть аналогично запуску внешнего приложения, но с использованием интерпретатора oscript:
Команда = "oscript.exe precommit1c.os --decompile C:\Report.erf C:\OutDir";
ЗапуститьПриложение(Команда, , Истина);
Для тех, кто предпочитает интеграцию через скриптовые языки, отличным выбором станет библиотека onec-dtools. Она позволяет работать с файлами .epf/.erf как с объектами, предоставляя доступ к их содержимому без полной распаковки на диск.
С помощью этой библиотеки можно реализовать «точечную» замену данных. Например, если нам нужно только обновить схему компоновки данных, не трогая формы и модули, мы можем открыть контейнер, найти нужный поток и перезаписать его. Это значительно быстрее полной пересборки.
Рассмотрим ситуацию, когда использование внешних исполняемых файлов (exe) запрещено политикой безопасности. В этом случае придется использовать наработки на чистом языке 1С, такие как проект V8Reader.
Методика основана на чтении файла как ДвоичныеДанные и использовании объекта ЧтениеДанных. Проанализируем примерный алгоритм поиска данных в контейнере:
Нужно учитывать, что сборка файла (упаковка) в этом случае крайне трудозатратна, так как требует реализации обратного алгоритма сжатия и строгого соблюдения структуры блоков v8. Чаще всего этот метод используют только для чтения данных (например, для программного анализа кода модуля во внешних обработках без их открытия).
Если ваша основная задача — программно менять СКД или настройки отчета, можно обойтись без полной разборки контейнера. Платформа 1С предоставляет объект СхемаКомпоновкиДанных, который можно сериализовать в XML и обратно, используя СКДБилдер для упрощения работы с объектной моделью.
Выясним, как это можно использовать для «сборки» нового отчета:
СхемаКомпоновкиДанных.СериализаторXDTO для получения XML-представления схемы.Хотя напрямую «впрыснуть» этот XML обратно в .erf файл штатными методами 1С сложно (здесь может помочь специализированный конвертер XML в EPF), мы можем использовать программное создание объекта ВнешнийОтчет, подменяя его схему в памяти перед выполнением. Рассмотрим пример изменения настроек:
// Загружаем схему из файла или ресурса
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКФайлуСхемы);
НоваяСхема = СериализаторXDTO.ПрочитатьXML(Чтение, Тип("СхемаКомпоновкиДанных"));
Чтение.Закрыть();
// Подключаем внешний отчет
ОтчетОбъект = ВнешниеОтчеты.Создать(ПутьКШаблону);
// Программная подмена схемы (доступно для отчетов на СКД)
ОтчетОбъект.СхемаКомпоновкиДанных = НоваяСхема;
Важное ограничение: этот метод позволяет менять структуру данных и логику запросов, но он не позволяет изменить исходный код в МодульОбъекта внешнего отчета на лету. Для модификации кода модуля все равно придется прибегать к Способу 1 или Способу 2.
Проанализировав все доступные варианты, можно сделать следующие выводы:
v8pack.exe через ЗапуститьПриложение.OneScript с пакетом precommit1c.Выбор конкретного метода зависит от ваших требований к производительности и возможности запуска стороннего ПО в окружении вашего сервера 1С.