При разработке различных инструментов автоматизации, систем контроля версий или вспомогательных утилит программисты часто сталкиваются с необходимостью узнать состав внешнего файла конфигурации (.cf). Основная сложность заключается в том, что файл конфигурации является закрытым проприетарным контейнером 1С, и прямого метода в языке 1С для получения объекта Метаданные из произвольного файла на диске не существует.
В этой статье мы подробно разберем, как обойти это ограничение, проанализируем штатные возможности платформы и рассмотрим альтернативные подходы, которые позволяют получить структуру объектов (справочников, документов, реквизитов) программным путем.
Прежде всего, разберем важное заблуждение, которое часто встречается на форумах. Существует мнение, что можно создать объект метаданных напрямую из двоичных данных с помощью кода вида Новый ОбъектМетаданныхКонфигурация(ДанныеФайла). Важно понимать: в актуальных релизах платформы «1С:Предприятие 8.3» такого конструктора не существует. Объект ОбъектМетаданныхКонфигурация доступен только для чтения метаданных текущей сессии через глобальную переменную Метаданные. Попытка вызвать такой конструктор приведет к ошибке выполнения.
Наиболее надежный и «штатный» способ получить полное описание структуры метаданных — это использование механизма выгрузки конфигурации в файлы. Платформа 1С умеет представлять всю структуру метаданных в виде набора XML-файлов, которые легко прочитать программно.
Рассмотрим по шагам, как автоматизировать этот процесс:
.cf нам понадобится пустая база-контейнер..cf в эту базу.Для реализации этого алгоритма без участия пользователя мы воспользуемся запуском конфигуратора в пакетном режиме. Проанализируем пример командной строки:
// 1. Загружаем файл .cf во временную базу
"C:\Program Files\1cv8\common\1cestart.exe" DESIGNER /F "C:\Temp\EmptyBase" /LoadCfg "C:\Temp\TargetConfig.cf" /UpdateDBCfg
// 2. Выгружаем метаданные в XML
"C:\Program Files\1cv8\common\1cestart.exe" DESIGNER /F "C:\Temp\EmptyBase" /DumpConfigToFiles "C:\Temp\XML_Metadata"
После выполнения этих команд в каталоге XML_Metadata появится структурированное дерево папок. Например, описание справочников будет находиться в файлах вида Catalogs\ИмяСправочника.xml. Далее мы можем использовать встроенный объект ЧтениеXML для парсинга этих данных.
Рассмотрим пример кода для чтения имени справочника из выгруженного XML:
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Temp\XML_Metadata\Catalogs\Склады.xml");
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента И Чтение.Имя = "MetaDataObject" Тогда
// Здесь мы находим описание объекта и его реквизитов
Пока Чтение.Прочитать() Цикл
Если Чтение.Имя = "Properties" Тогда
// Читаем свойства объекта
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
Если нам нужно не просто получить список имен, а полноценно обращаться к свойствам объектов метаданных (типы, длины строк, связи), удобнее использовать COM-соединение. Этот метод позволяет работать с объектом Метаданные внешней конфигурации так же, как мы работаем с текущей.
Разберем алгоритм совместной работы:
МенеджерИнформационныхБаз или просто создав папку с файлом 1Cv8.1CD)..cf через пакетный запуск (как в предыдущем методе).COM-соединение с этой базой.Посмотрим на пример кода подключения:
ПараметрыСоединения = "File=""C:\Temp\TempBase"";Usr=""Администратор"";";
COMСоединитель = Новый COMОбъект("V83.COMConnector");
Попытка
Соединение = COMСоединитель.Connect(ПараметрыСоединения);
// Теперь мы можем обращаться к метаданным внешней базы
Для Каждого Справочник Из Соединение.Метаданные.Справочники Цикл
Сообщить("Справочник: " + Справочник.Имя);
Для Каждого Реквизит Из Справочник.Реквизиты Цикл
Сообщить(" - Реквизит: " + Реквизит.Имя + ", Тип: " + Соединение.String(Реквизит.Тип));
КонецЦикла;
КонецЦикла;
Исключение
Сообщить("Ошибка подключения: " + ОписаниеОшибки());
КонецПопытки;
Преимущество этого метода заключается в том, что нам доступны все методы платформы для анализа типов данных. Мы можем легко узнать, является ли реквизит ссылкой на другой объект, даже если этот объект находится во внешнем файле.
В ситуациях, когда разворачивание полноценной базы 1С невозможно (например, в Linux-контейнерах или в рамках CI/CD процессов), можно воспользоваться инструментами, работающими с файлом .cf на уровне структуры контейнера.
Файл .cf — это структурированное хранилище (V8 Container File). Внутри него находятся файлы, сжатые алгоритмом zlib. Основные метаданные обычно хранятся в файлах с именами metadata или в виде GUID-файлов.
Для автоматизации этой задачи отлично подходит OneScript и библиотека v8files. Рассмотрим, как это работает концептуально:
.cf во временный каталог.root, чтобы найти ссылки на объекты.{} (вложенные фигурные скобки).Хотя парсинг формата "фигурных скобок" достаточно трудоемок, он позволяет получить структуру метаданных мгновенно, не дожидаясь запуска тяжелого конфигуратора 1С.
Существует еще один малоизвестный способ — программное использование объекта СравнениеКонфигураций. Мы можем запустить сравнение текущей пустой конфигурации с файлом на диске.
Проанализируем ситуацию: если вызвать метод сравнения, платформа сформирует дерево различий. Поскольку в текущей базе объектов нет, дерево различий будет содержать полную структуру внешнего файла .cf.
Сравнение = Новый СравнениеКонфигураций;
Результат = Сравнение.Сравнить("C:\Temp\CurrentBase.cf", "C:\Temp\External.cf");
// Результат содержит дерево объектов, которые есть во внешнем файле
Однако стоит учитывать, что этот метод чаще используется в интерактивном режиме и имеет ограничения при попытке детального программного анализа свойств каждого реквизита.
Выбор метода зависит от ваших условий:
Помните, что работа с внешними файлами .cf всегда требует наличия установленной платформы соответствующей версии, так как формат контейнера может незначительно меняться между релизами (например, при переходе с 8.3.10 на более высокие версии изменились механизмы работы с расширениями .cfe).