В процессе разработки конфигураций на платформе 1С:Предприятие 8.3 мы часто сталкиваемся с задачами, которые требуют хранения информации о типах объектов метаданных. Например, как в рассматриваемом случае, возникает необходимость прикрепленные к различным документам и справочникам файлы раскладывать в определенные тома на диске, при этом группируя их по типу объекта-владельца. Для такой организации нам требуется хранить в регистре сведений не конкретную ссылку на объект (например, на определенный элемент справочника "ДоговорыКонтрагентов"), а именно тип этого объекта (сам "Справочник.ДоговорыКонтрагентов").
На первый взгляд, задача может показаться простой, и мы можем подумать о хранении строкового представления типа. Однако, как показывает практика, такой подход имеет свои подводные камни. Давайте вместе проанализируем различные варианты решения этой задачи, оценим их преимущества и недостатки, и выберем наиболее надежный и гибкий.
Первая идея, которая приходит в голову, — это хранение в измерении регистра сведений обыкновенной Строки, которая будет содержать полное имя типа объекта. Для получения такой строки мы можем использовать функции платформы.
Например, если у нас есть ссылка на конкретный объект, мы можем получить его тип и преобразовать его в строку:
ОбъектСсылка = Справочники.ДоговорыКонтрагентов.НайтиПоКоду("000000001");
Если ОбъектСсылка <> Неопределено Тогда
ИмяТипаСтрокой = Строка(ТипЗнч(ОбъектСсылка)); // Результат будет "СправочникСсылка.ДоговорыКонтрагентов"
КонецЕсли;
Или же, если нам нужно получить имя типа самого объекта метаданных, мы можем использовать его метаданные:
ИмяТипаСтрокой = Метаданные.Справочники.ДоговорыКонтрагентов.ПолноеИмя(); // Результат будет "Справочник.ДоговорыКонтрагентов"
Этот подход кажется простым в реализации и не требует дополнительных объектов конфигурации. Мы просто создаем измерение типа Строка в нашем регистре сведений и записываем туда полученное значение. Однако, у этого метода есть один критический недостаток, который делает его ненадежным для долгосрочного использования:
Таким образом, хотя этот вариант и является самым быстрым в реализации, его зависимость от текстового имени объекта метаданных делает его непригодным для систем, требующих высокой степени устойчивости к изменениям конфигурации.
На форуме прозвучала идея использования Плана видов характеристик. Рассмотрим, как этот подход может быть применен для нашей задачи.
Принцип реализации:
ПланВидовХарактеристик, например, с именем "ТипыОбъектовДляХраненияФайлов".Справочник.ДоговорыКонтрагентов, "Контрагенты" для Справочник.Контрагенты и так далее.ПланВидовХарактеристикСсылка.ТипыОбъектовДляХраненияФайлов.Преимущества данного подхода:
Недостатки ПВХ:
Хотя ПВХ и является улучшением по сравнению со строковым хранением, необходимость ручного управления элементами ограничивает его применимость в больших и динамично развивающихся системах.
Наиболее надежным, гибким и архитектурно правильным решением для хранения типа значения объекта в измерении регистра сведений является использование справочника ИдентификаторыОбъектовМетаданных, который входит в состав Библиотеки стандартных подсистем (БСП) 1С.
Что такое ИдентификаторыОбъектовМетаданных?
Этот справочник предназначен специально для хранения ссылок на объекты метаданных конфигурации (справочники, документы, регистры, перечисления и т.д.). Для каждого объекта метаданных в нем создается уникальный элемент, который является его стабильным идентификатором, не зависящим от имени объекта в конфигураторе.
Принцип работы:
СправочникСсылка.ИдентификаторыОбъектовМетаданных.Преимущества этого подхода:
ИдентификаторыОбъектовМетаданных, соответствующий этому объекту, останется прежним. Таким образом, все записи в нашем регистре сведений, использующие эту ссылку, продолжат работать корректно без необходимости ручного исправления.ИдентификаторыОбъектовМетаданных автоматически актуализируется при обновлении. Система сама следит за появлением новых объектов метаданных и изменением существующих.СправочникСсылка) в 1С всегда выполняется значительно быстрее, чем по строковым значениям, особенно при больших объемах данных.Пример использования:
Рассмотрим, как мы можем получить и использовать идентификатор объекта метаданных.
// Предположим, у нас есть ссылка на конкретный объект, например, элемент справочника "ДоговорыКонтрагентов"
ОбъектСсылка = Справочники.ДоговорыКонтрагентов.НайтиПоКоду("000000001");
// Получим объект метаданных для типа этого объекта
Если ОбъектСсылка <> Неопределено Тогда
ОбъектМетаданных = ОбъектСсылка.Метаданные();
// Далее, через специальную функцию общего модуля БСП
// "ИдентификаторыОбъектовМетаданныхКлиентСервер" или "ИдентификаторыОбъектовМетаданныхПереопределяемый"
// (или напрямую Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоИдентификатору(ОбъектМетаданных.ПолноеИмя()))
// мы можем получить ссылку на элемент справочника ИдентификаторыОбъектовМетаданных.
// Примечание: Для работы с этим справочником часто используются служебные функции БСП,
// но для простоты примера мы можем использовать поиск по полному имени.
ИдентификаторТипа = Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоИдентификатору(ОбъектМетаданных.ПолноеИмя());
Если ИдентификаторТипа = Неопределено Тогда
// Если элемент не найден (например, при первом запуске или если БСП не обновила справочник),
// его можно создать или использовать специализированные функции БСП для получения/создания
// ИдентификаторТипа = ИдентификаторыОбъектовМетаданных.ПолучитьИдентификаторПоОбъектуМетаданных(ОбъектМетаданных);
// Для упрощения, если БСП есть, то этот элемент уже должен быть создан.
// В реальной жизни лучше использовать функции из общих модулей БСП,
// например, ИдентификаторыОбъектовМетаданныхСлужебный.ПолучитьИдентификаторОбъектаМетаданных(ОбъектМетаданных)
// или ИдентификаторыОбъектовМетаданных.ПолучитьИдентификаторПоПолномуИмени(ОбъектМетаданных.ПолноеИмя())
Сообщить("Идентификатор типа для " + ОбъектМетаданных.ПолноеИмя() + " не найден. Убедитесь, что справочник ИдентификаторыОбъектовМетаданных актуален.");
Иначе
// Теперь мы можем записать ИдентификаторТипа в измерение нашего регистра сведений
// ЗаписьРегистра.ТипОбъекта = ИдентификаторТипа;
// ...
Сообщить("Для типа " + ОбъектМетаданных.ПолноеИмя() + " найден идентификатор: " + ИдентификаторТипа);
КонецЕсли;
КонецЕсли;
Если нам нужно получить полное имя типа объекта метаданных обратно из ссылки на элемент справочника ИдентификаторыОбъектовМетаданных, мы также можем использовать соответствующие функции или свойства элемента:
// Пусть ЗаписьРегистра.ТипОбъекта - это ссылка на элемент справочника ИдентификаторыОбъектовМетаданных
ИдентификаторТипа = ЗаписьРегистра.ТипОбъекта;
Если ИдентификаторТипа <> Неопределено Тогда
ПолноеИмяТипа = ИдентификаторТипа.Идентификатор; // Реквизит "Идентификатор" хранит полное имя
// Или использовать функцию БСП:
// ПолноеИмяТипа = ИдентификаторыОбъектовМетаданных.ПолучитьПолноеИмяПоИдентификатору(ИдентификаторТипа);
Сообщить("Полное имя типа из идентификатора: " + ПолноеИяТипа);
// Теперь мы можем использовать это полное имя для динамического получения ссылки на объект метаданных
// или для других целей, например, для определения тома хранения файлов.
КонецЕсли;
Использование этого справочника является наиболее гибким и устойчивым решением, которое минимизирует риски, связанные с изменением структуры конфигурации, и обеспечивает высокую производительность.
В теории существует еще один, более экзотический способ хранения типа объекта — это XML-сериализация объекта ОписаниеТипов. Объект ОписаниеТипов позволяет описать один или несколько типов данных. Его можно сериализовать в строку, а затем десериализовать обратно.
Принцип реализации:
ОписаниеТипов: Мы создаем объект ОписаниеТипов, передавая ему нужный тип объекта метаданных.ЗаписьXML, мы сериализуем ОписаниеТипов в строковое представление XML. Эту строку затем сохраняем в измерении регистра с типом Строка.ЧтениеXML и десериализуем ОписаниеТипов обратно.Недостатки:
ОписаниеТипов в новых версиях платформы могут привести к несовместимости.Мы не рекомендуем использовать этот подход для данной задачи из-за его неоправданной сложности и многочисленных недостатков.
Мы рассмотрели несколько подходов к хранению типа значения объекта в измерении регистра сведений. Очевидно, что каждый из них имеет свои особенности.
ИдентификаторыОбъектовМетаданных из БСП — это рекомендованное и архитектурно правильное решение. Оно обеспечивает максимальную устойчивость к изменениям конфигурации, автоматическую актуализацию и высокую производительность. Мы настоятельно рекомендуем использовать именно этот подход для обеспечения долгосрочной стабильности и надежности вашей системы.При выборе решения для вашей задачи всегда стремитесь к максимальной гибкости и устойчивости, чтобы минимизировать будущие затраты на поддержку и развитие системы.