Метаданные и их идентификаторы
Идентификаторы (GUID’ы) метаданных конфигурации. Немного о том, как их получить.
- Описание
- Подробнее
Описание
Есть ли проблема
Каждый объект метаданных конфигурации имеет собственный уникальный идентификатор, который невозможно получить простым способом. Платформа 1С не предоставляет методов работы с этими внутренними свойствами, которые иногда все же нужны. Из штатных механизмов платформы для работы с метаданными мы имеем только метод "ПолноеИмя()", который вернет нам почти удобочитаемый идентификатор объекта.
ПолноеИмя = Метаданные.Документы.ЗаказКлиента.ПолноеИмя()
Сообщить(ПолноеИмя); // Выведет "Документ.ЗаказКлиента"
Нужно ли еще что-то? Иногда могут встать такие задачи, хоть и нестандартные:
- Нужно отследить фактическую замену объекта метаданных. Например, если удалили справочник из конфигурации, но при этом добавили новый с таким же именем.
- При возникновении ошибок, связанных с кэшем, в них может фигурировать идентификатор метаданных. Для расследования нужно распознать что это за объект.
- Для собственного решения по хранению информации о метаданных в конфигурации. Аналог справочника "ИдентификаторыОбъектовМетаданных" из БСП, в котором каждому объекту конфигурации (ну, почти каждому — только верхнеуровневым) соответствует элемент этого справочника по полному имени. По тому самому значению, полученному с помощью "ПолноеИмя()".
- Или Вам просто интересно узнать, как подобную информацию получить.
- Другие причины.
Сегодня мы рассмотрим некоторые особенности работы с метаданными в БСП, способы получения расширенной информации в ручном режиме, а также программный путь получения дополнительной информации о метаданных.
Путь БСП
Как уже упоминалось выше, в БСП есть справочник "Идентификаторы объектов метаданных", который содержит информацию об объектах метаданных конфигурации.
Обновляется автоматически в процедурах обновления БСП. Также обновление может быть запущено вручную.
Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника();
Сопоставление элемента этого справочника с объектом метаданных конфигурации выполняется с помощью поля "ПолноеИмя", в которое записывается результат вызова функции "ПолноеИмя()" для объекта метаданных (см. начало статьи). Вот пример заполнения элемента из демобазы БСП для документа "Заказ клиента".
Кроме этого поля также есть "ЗначениеПустойСсылки", "НоваяСсылка", "ИмяПредопределенныхДанных" и "КлючОбъектаХранилища", но в их назначение погружаться сейчас не будем. Отмечу лишь, что они помогают провести "умное" обновление справочника с учетом переименований и других особенностей:
// Порядок обновления:
// 1. Переименование объектов метаданных (с учетом нижестоящих подсистем).
// 2. Обновление предопределенных идентификаторов (коллекций объектов метаданных).
// 3. Обновление идентификаторов объектов метаданных, которые имеют ключ объекта метаданных.
// 4. Обновление идентификаторов объектов метаданных, которые не имеют ключа объекта метаданных.
// 5. В процессе 3 и 4 пометка удаления дублей идентификаторов (по полным именам).
// 6. Добавление новых идентификаторов объектов метаданных.
// 7. Обновление родителей идентификаторов объектов метаданных и запись обновленных.
Подробнее Вы можете посмотреть самостоятельно в процедуре "ОбновитьДанныеСправочника", о которой мы уже говорили ранее.
Главное, что стоит сказать — это отсутствие необходимости сохранять уникальный идентификатор объекта метаданных для этого справочника и механизмов его обновления. Разработчики БСП нашли альтернативный путь и используют его.
Ручная работа
Но представим, что для нашей задачи все-таки нужен уникальный идентификатор объекта метаданных. Как его получить?
Самый простой способ — сделать вручную выгрузку конфигурации в файлы и посмотреть идентификатор самостоятельно. Для платформы 8.3 есть возможность выгружать конфигурацию в XML.
Файлы выгружаются в каталог, там мы и сможем найти нужную для нас информацию. Например, в демобазе БСП есть документ "_ДемоЗаказПокупателя". Идем в каталог с файлами конфигурации, переходим во вложенный каталог "Documents" и находим файл "_ДемоЗаказПокупателя.xml". Вот его содержимое (не все, только самая важная для нас часть):
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject> <!-- Убрал пространства имен и некоторые другие атрибуты -->
<Document uuid="4eee25b1-2da6-459b-953b-4c8d519c9bce">
<InternalInfo>
<xr:GeneratedType name="DocumentObject._ДемоЗаказПокупателя" category="Object">
<xr:TypeId>eb4c3baa-9f3f-4988-b1cc-ebb9a21105ca</xr:TypeId>
<xr:ValueId>bf5eaf96-437c-417c-96bd-5b4e968ab66b</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="DocumentRef._ДемоЗаказПокупателя" category="Ref">
<xr:TypeId>6e094677-52bb-4e65-8322-5fbd75bbdd8e</xr:TypeId>
<xr:ValueId>ac0e6277-d79a-4c3d-aa88-9edcdaaeff3a</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="DocumentSelection._ДемоЗаказПокупателя" category="Selection">
<xr:TypeId>26d4fa62-e00f-4fb9-acaf-44033d6cf1d8</xr:TypeId>
<xr:ValueId>7a336f96-3af1-4177-923a-579783b96811</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="DocumentList._ДемоЗаказПокупателя" category="List">
<xr:TypeId>11c10634-2427-4654-8c12-f68386be6e27</xr:TypeId>
<xr:ValueId>b18e5dd3-3e87-4698-90b5-b79eae1ad923</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="DocumentManager._ДемоЗаказПокупателя" category="Manager">
<xr:TypeId>dca0d409-e137-46a7-8ca8-6408b204142e</xr:TypeId>
<xr:ValueId>08f7715a-0036-463e-b649-22a98fb140e0</xr:ValueId>
</xr:GeneratedType>
</InternalInfo>
<!-- Тут еще много много информации об объекте метаданных -->
</Document>
</MetaDataObject>
В первом узле, подчиненном "MetaDataObject", мы видим имя вида объекта (в нашем случае "Document", т.е. документ), а также его уникальный идентификатор. Да, в нашей конфигурации у документа "_ДемоЗаказПокупателя" идентификатор объекта метаданных — "4eee25b1-2da6-459b-953b-4c8d519c9bce". На самом деле тут можно узнать не только GUID объекта метаданных, но и другую служебную информацию:
- Идентификатор различных связанных типов данных (объекта, ссылки, менеджера и др.).
- Состав объекта (поля, типы и т.д.)
- И кое-что другое.
Фактически это полная информация об объекте.
Таким же образом можно узнать GUID любого объекта метаданных конфигурации. Но это очень неудобно выполнять вручную каждый раз, когда это значение понадобится, поэтому идем дальше.
Извлекаем из журнала регистрации
Есть еще один необычный способ получения идентификаторов метаданных — это использование файлов журнала регистрации. Да, именно файлов, т.к. штатными средствами прочитать GUID объекта метаданных из них платформа 1С не позволяет.
Есть два формата журнала регистрации:
- Текстовый формат, который хорошо описан в публикации "Формат файлов журнала регистрации 1С 8.1/8.2 — ELF/LOG/LGF/LGP".
- SQLite формат, структуру которого можно посмотреть в публикации "Все, что вы хотели знать о журнале регистрации".
Например, для SQLite-формата идентификатор объекта метаданных хранится в таблице "MetadataCodes".
В текстовом формате идентификатор метаданных хранится в файле "1Cv8.lgf", который содержит информацию о ссылочных данных журнала. Записи с идентификатором "5" как раз и содержат информацию о метаданных. Вот пример такой записи.
Как именно читать данные из этих источников подробно останавливаться не будем. Но кратко перечислю основные варианты:
- Для SQLite формата делать запросы через ODBC-драйвер к файлу журнала.
- Для текстового формата — парсить файл "1Cv8.lgf".
В публикации "Экспорт журнала регистрации. Набор инструментов (приложения + исходный код)" как раз есть информация о парсинге обоих форматов журнала регистрации и открытый исходный код. Также там есть пример конфигурации с внешним источником данных для получения данных журнала регистрации, но уже из внешнего хранилища.
Программные маневры
Предыдущие способы рабочие, но очень неудобные, да и не всегда подходят.
Минусы ручного анализа очевидны:
- Большие трудозатраты для анализа, не говоря уже о случаях, когда нужно получить идентификаторы всех объектов метаданных.
- Задача сама по себе требует автоматизации
- Нет возможности программной работы
Для получения данных из журнала регистрации также есть недостатки:
- Не все метаданные могли участвовать в событиях журнала, а значит их и не будет в исходных файлах
- Необходимость парсинга / подключения к файлам журнала, что не всегда возможно для файлов с рабочего окружения
Но есть и третий способ — это программное получение GUID’ов метаданных с помощью программного кода. Для этого нужно выполнить следующую последовательность действий:
- Выгружаем конфигурацию в файлы
- Парсим основные файлы описания метаданных
- Обрабатываем результат
- Получаем таблицу метаданных с полями "Полное имя" и "GUID".
Рассмотрим кратко реализацию каждого шага.
Выгружаем и парсим
Для выгрузки конфигурации в файлы из кода встроенного языка платформы 1С запустим конфигуратор в пакетном режиме с указанием параметра "DumpConfigToFiles", который как раз и сделает то, что нам нужно. Вот простейший пример процедуры для этого.
Процедура ВыгрузитьКонфигурациюВКаталог(ИмяСервера, ИмяБазы, ИмяПользователь, ПарольПользователя, КаталогВыгрузи)
КаталогСерверногоПриложения = КаталогПрограммы();
ПриложениеТолстыйКлиент = КаталогСерверногоПриложения + "1cv8.exe";
КомандаКонфигуратора = """" + ПриложениеТолстыйКлиент + """"
+ " DESIGNER"
+ " /S""" + ИмяСервера + "\" + ИмяБазы + """"
+ " /N""" + ИмяПользователь + """"
+ " /P""" + ПарольПользователя + """"
+ " /DumpConfigToFiles """ + КаталогВыгрузи + """"
+ " ";
РезультатВыполнения = ВыполнитьПриложение(КомандаКонфигуратора);
Если ЗначениеЗаполнено(РезультатВыполнения.Ошибки) Тогда
ВызватьИсключение "Не удалось выгрузить конфигурацию в файлы.
|Подробно:
|" + РезультатВыполнения.Ошибки;
КонецЕсли;
КонецПроцедуры
Мы формируем команду для запуска конфигуратора в пакетном режиме с указанием адреса информационной базы, а также данных для входа пользователя. Для параметра "DumpConfigToFiles" указывается каталог выгрузки. Вызвать процедуру очень просто, главное не забыть подставить в нее свои корректные параметры.
ИмяСервера = "localhost";
ИмяБазы = "bal_demo";
ИмяПользователь = "Администратор";
ПарольПользователя = "";
КаталогВыгрузкиКонфигурации = "C:\cfg";
ВыгрузитьКонфигурациюВКаталог(
ИмяСервера,
ИмяБазы,
ИмяПользователь,
ПарольПользователя,
КаталогВыгрузкиКонфигурации);
Функция "ВыполнитьПриложение" — это еще одна добавленная процедура, которая запускает указанную команду с таймаутом выполнения. Это особенно важно, т.к. при выполнении подобного кода на сервере может произойти зависание сеанса, если с приложением что-то пошло не так.
Подробнее о безопасном запуске приложений из 1С для Windows и Linux шел разговор в публикации "Вы запускаете приложения, но делаете это без уважения". Ниже под спойлером приведу исходный код этой процедуры и всех вспомогательных ее частей.