Как программно прочитать структуру метаданных из внешнего файла .cf?

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

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

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

Развенчание мифа о встроенном конструкторе

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

Метод 1: Выгрузка конфигурации в XML-файлы (Batch-режим)

Наиболее надежный и «штатный» способ получить полное описание структуры метаданных — это использование механизма выгрузки конфигурации в файлы. Платформа 1С умеет представлять всю структуру метаданных в виде набора XML-файлов, которые легко прочитать программно.

Рассмотрим по шагам, как автоматизировать этот процесс:

  1. Создание временной информационной базы: Для работы с файлом .cf нам понадобится пустая база-контейнер.
  2. Загрузка конфигурации: Выполняем загрузку файла .cf в эту базу.
  3. Выгрузка в файлы: Используем команду выгрузки метаданных в иерархию папок.

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


// 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" Тогда
                // Читаем свойства объекта
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецЦикла;
Чтение.Закрыть();

Метод 2: Использование временной базы и COM-соединения

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

Разберем алгоритм совместной работы:

  1. Программно создаем пустую файловую базу (используя МенеджерИнформационныхБаз или просто создав папку с файлом 1Cv8.1CD).
  2. Загружаем в нее .cf через пакетный запуск (как в предыдущем методе).
  3. Устанавливаем COM-соединение с этой базой.

Посмотрим на пример кода подключения:


ПараметрыСоединения = "File=""C:\Temp\TempBase"";Usr=""Администратор"";";
COMСоединитель = Новый COMОбъект("V83.COMConnector");

Попытка
    Соединение = COMСоединитель.Connect(ПараметрыСоединения);
    // Теперь мы можем обращаться к метаданным внешней базы
    Для Каждого Справочник Из Соединение.Метаданные.Справочники Цикл
        Сообщить("Справочник: " + Справочник.Имя);
        Для Каждого Реквизит Из Справочник.Реквизиты Цикл
            Сообщить(" - Реквизит: " + Реквизит.Имя + ", Тип: " + Соединение.String(Реквизит.Тип));
        КонецЦикла;
    КонецЦикла;
Исключение
    Сообщить("Ошибка подключения: " + ОписаниеОшибки());
КонецПопытки;

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

Метод 3: Использование внешних утилит и OneScript

В ситуациях, когда разворачивание полноценной базы 1С невозможно (например, в Linux-контейнерах или в рамках CI/CD процессов), можно воспользоваться инструментами, работающими с файлом .cf на уровне структуры контейнера.

Файл .cf — это структурированное хранилище (V8 Container File). Внутри него находятся файлы, сжатые алгоритмом zlib. Основные метаданные обычно хранятся в файлах с именами metadata или в виде GUID-файлов.

Для автоматизации этой задачи отлично подходит OneScript и библиотека v8files. Рассмотрим, как это работает концептуально:

  1. Утилита распаковывает контейнер .cf во временный каталог.
  2. Парсится корневой файл root, чтобы найти ссылки на объекты.
  3. Читаются файлы описания объектов, которые представляют собой текстовые данные в формате {} (вложенные фигурные скобки).

Хотя парсинг формата "фигурных скобок" достаточно трудоемок, он позволяет получить структуру метаданных мгновенно, не дожидаясь запуска тяжелого конфигуратора 1С.

Метод 4: Сравнение конфигураций

Существует еще один малоизвестный способ — программное использование объекта СравнениеКонфигураций. Мы можем запустить сравнение текущей пустой конфигурации с файлом на диске.

Проанализируем ситуацию: если вызвать метод сравнения, платформа сформирует дерево различий. Поскольку в текущей базе объектов нет, дерево различий будет содержать полную структуру внешнего файла .cf.


Сравнение = Новый СравнениеКонфигураций;
Результат = Сравнение.Сравнить("C:\Temp\CurrentBase.cf", "C:\Temp\External.cf");
// Результат содержит дерево объектов, которые есть во внешнем файле

Однако стоит учитывать, что этот метод чаще используется в интерактивном режиме и имеет ограничения при попытке детального программного анализа свойств каждого реквизита.

Итоги и рекомендации

Выбор метода зависит от ваших условий:

Помните, что работа с внешними файлами .cf всегда требует наличия установленной платформы соответствующей версии, так как формат контейнера может незначительно меняться между релизами (например, при переходе с 8.3.10 на более высокие версии изменились механизмы работы с расширениями .cfe).

← На главную