В практике разработчика 1С иногда возникают задачи, выходящие за рамки стандартного написания кода в Конфигураторе. Одной из таких задач является программное создание внешней обработки (файла .epf) с динамическим наполнением её модуля объекта. Это может потребоваться для создания сложных конструкторов кода, систем автоматизированного тестирования или инструментов миграции данных. В данной статье мы подробно разберем, как реализовать этот функционал, используя различные подходы: от штатных средств платформы до специализированных внешних инструментов.
Прежде чем мы перейдем к коду, давайте проанализируем ситуацию. Файл внешней обработки .epf представляет собой сложный бинарный контейнер (формат Compound File Storage). Внутри него данные (формы, макеты, модули) хранятся в сжатом виде. Просто открыть этот файл как текстовый и дописать туда процедуру невозможно. Нам необходимо либо использовать механизмы самой платформы для «сборки» файла, либо применять сторонние библиотеки, умеющие работать с этим форматом.
Рассмотрим несколько эффективных способов решения этой задачи.
Это самый надежный и «чистый» метод, поддерживаемый фирмой 1С. Суть его заключается в том, что мы подготавливаем структуру обработки в виде набора XML и bsl (текстовых) файлов, а затем просим Конфигуратор собрать их в один бинарный .epf. Этот метод мы и разберем по шагам.
Шаг 1. Подготовка шаблона. Сначала нам нужно вручную создать пустую обработку в Конфигураторе и выгрузить её в файлы. Это создаст необходимую структуру каталогов.
Для выгрузки используем команду:
1cv8.exe DESIGNER /F "ПутьКБазе" /N "Логин" /P "Пароль" /DumpExternalDataProcessorOrReportToFiles "C:\Temp\Template.epf" "C:\Temp\SourceFiles"
Шаг 2. Программное изменение модуля. После выгрузки в папке C:\Temp\SourceFiles появится файл ObjectModule.bsl (или аналогичный в зависимости от версии выгрузки). Теперь мы можем программно изменить его содержимое, используя стандартные средства работы с текстовыми файлами в 1С.
Проанализируем пример кода для записи нового текста в модуль:
ТекстМодуля = Новый ТекстовыйДокумент;
ТекстМодуля.ДобавитьСтроку("Процедура ВыполнитьКоманду()");
ТекстМодуля.ДобавитьСтроку(" Сообщить(""Код сформирован программно!"");");
ТекстМодуля.ДобавитьСтроку("КонецПроцедуры");
ТекстМодуля.Записать("C:\Temp\SourceFiles\ObjectModule.bsl", КодировкаТекста.UTF8);
Шаг 3. Сборка файла. Теперь выполним обратную операцию — соберем измененные файлы в готовую обработку:
1cv8.exe DESIGNER /F "ПутьКБазе" /N "Логин" /P "Пароль" /LoadExternalDataProcessorOrReportFromFiles "C:\Temp\SourceFiles" "C:\Temp\Result.epf"
Этот метод гарантирует, что полученный файл будет полностью валидным и откроется в любой версии платформы.
Если нам нужно решение, не зависящее от установленного Конфигуратора (например, для работы на сервере или в CI/CD процессах), рассмотрим использование OneScript. Это независимый интерпретатор языка 1С, для которого существует библиотека v8files.
Рассмотрим, как это работает. Библиотека позволяет работать с файлом .epf как с объектом. Проанализируем пример скрипта на OneScript:
#использовать v8files
ФайлОбработки = v8files.ОткрытьВнешнююОбработку("C:\Temp\MyTemplate.epf");
МодульОбъекта = ФайлОбработки.ПолучитьМодульОбъекта();
МодульОбъекта.Текст = "Сообщить(""Привет из OneScript!"");";
ФайлОбработки.Записать("C:\Temp\ReadyProcessing.epf");
Преимущество этого метода в его высокой скорости. Нам не нужно запускать тяжелый процесс 1cv8.exe, ждать авторизации в базе и выполнения команд. Библиотека напрямую работает с бинарной структурой контейнера, распаковывая и упаковывая потоки zlib «на лету».
Иногда задача «создать обработку» является избыточной. Если нам нужно просто выполнить произвольный программный код, который генерируется динамически, мы можем использовать операторы Выполнить() и Вычислить().
Выясним, как это реализовать в контексте имитации внешней обработки. Мы можем создать одну «универсальную» внешнюю обработку-контейнер, в которой будет всего одна команда, считывающая текст из внешнего файла или параметра и исполняющая его.
Посмотрим на пример кода внутри такой обработки:
Процедура Сформировать(ТекстАлгоритма)
// ТекстАлгоритма может быть передан как параметр или прочитан из файла
Выполнить(ТекстАлгоритма);
КонецПроцедуры
Этот способ гораздо проще в реализации, но имеет ограничение: мы ограничены контекстом выполнения текущего модуля. Если же нам критически важно иметь именно отдельный файл .epf (например, для передачи заказчику), следует вернуться к Способу 1.
Рассмотрим ситуацию, когда нам нужно вносить минимальные изменения в уже готовую обработку. Проанализируем возможность использования бинарной замены. Мы можем создать обработку-шаблон, в модуле которой разместим уникальную строку-маркер, например: //---PLACEHOLDER---.
Важные моменты:
V8Unpack).Если ваш конструктор должен создавать не только код модуля, но и визуальный интерфейс (кнопки, поля ввода), задача усложняется. В структуре XML выгрузки формы описываются в отдельном файле (обычно Form.xml). Там используется формат XDTO, описывающий положение элементов, их привязки к данным и обработчики событий.
Для создания формы программно мы рекомендуем:
XML-структуру.ЗаписьXML для генерации аналогичной структуры с нужными вам параметрами.Мы выяснили, что программное создание внешней обработки — задача вполне решаемая. Наиболее стабильным методом является использование командной строки Конфигуратора совместно с выгрузкой/загрузкой файлов. Это гарантирует корректность формата и поддержку всех возможностей платформы 1С.
Для задач автоматизации (DevOps) лучше подойдет OneScript, который позволяет манипулировать модулями без запуска основной платформы. А для простых сценариев динамического кода всегда стоит помнить про оператор Выполнить(), который зачастую избавляет от необходимости генерировать физические файлы на диске.
Выбор конкретного метода зависит от ваших требований к производительности и окружению, в котором будет работать ваш «конструктор».