Как лучше хранить тип значения объекта в измерении регистра сведений?

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

В процессе разработки конфигураций на платформе 1С:Предприятие 8.3 мы часто сталкиваемся с задачами, которые требуют хранения информации о типах объектов метаданных. Например, как в рассматриваемом случае, возникает необходимость прикрепленные к различным документам и справочникам файлы раскладывать в определенные тома на диске, при этом группируя их по типу объекта-владельца. Для такой организации нам требуется хранить в регистре сведений не конкретную ссылку на объект (например, на определенный элемент справочника "ДоговорыКонтрагентов"), а именно тип этого объекта (сам "Справочник.ДоговорыКонтрагентов").

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

Вариант 1: Хранение строкового представления типа

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

Например, если у нас есть ссылка на конкретный объект, мы можем получить его тип и преобразовать его в строку:


ОбъектСсылка = Справочники.ДоговорыКонтрагентов.НайтиПоКоду("000000001");
Если ОбъектСсылка <> Неопределено Тогда
    ИмяТипаСтрокой = Строка(ТипЗнч(ОбъектСсылка)); // Результат будет "СправочникСсылка.ДоговорыКонтрагентов"
КонецЕсли;

Или же, если нам нужно получить имя типа самого объекта метаданных, мы можем использовать его метаданные:


ИмяТипаСтрокой = Метаданные.Справочники.ДоговорыКонтрагентов.ПолноеИмя(); // Результат будет "Справочник.ДоговорыКонтрагентов"

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

  1. Зависимость от наименования объекта метаданных: Если в будущем мы или другой разработчик переименуем справочник "ДоговорыКонтрагентов" в конфигураторе, например, на "ДоговорыСПартнерами", все существующие записи в регистре, использующие старое строковое представление, станут неактуальными. Наша логика раскладки файлов по томам будет нарушена, и потребуется ручное исправление данных в регистре, что трудоемко и чревато ошибками.

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

Вариант 2: Использование Плана видов характеристик (ПВХ)

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

Принцип реализации:

  1. Создаем новый План видов характеристик: Мы создаем новый объект конфигурации — ПланВидовХарактеристик, например, с именем "ТипыОбъектовДляХраненияФайлов".
  2. Заполняем ПВХ элементами: В режиме Предприятия или программно мы создаем элементы этого ПВХ, каждый из которых будет соответствовать требуемому типу объекта метаданных. Например, мы создадим элемент с наименованием "ДоговорыКонтрагентов" для типа Справочник.ДоговорыКонтрагентов, "Контрагенты" для Справочник.Контрагенты и так далее.
  3. Указываем тип измерения: В измерении нашего регистра сведений, где мы хотим хранить тип объекта, мы устанавливаем тип данных ПланВидовХарактеристикСсылка.ТипыОбъектовДляХраненияФайлов.

Преимущества данного подхода:

  1. Устойчивость к переименованию объектов метаданных: В отличие от строкового хранения, если мы переименуем справочник "ДоговорыКонтрагентов" в конфигураторе, ссылка на элемент в ПВХ останется той же. Это обеспечивает более надежное связывание.
  2. Гибкость: Мы можем добавить дополнительные реквизиты к элементам ПВХ, например, для хранения пути к тому или других настроек, специфичных для этого типа объектов.

Недостатки ПВХ:

  1. Ручное администрирование: Главный недостаток этого метода заключается в том, что он требует ручного создания элементов в ПВХ для каждого нового типа объекта, который мы хотим учитывать. Если в нашей системе появятся новые справочники или документы, для которых потребуется организовать хранение файлов по типу, нам придется не забыть добавить соответствующие элементы в ПВХ. Это увеличивает объем работ по сопровождению и повышает вероятность человеческой ошибки.
  2. Потенциальное дублирование: При неаккуратном подходе можно создать несколько элементов, относящихся к одному и тому же типу объекта, что приведет к путанице.

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

Вариант 3: Рекомендуемый подход – Справочник "ИдентификаторыОбъектовМетаданных" (БСП)

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

Что такое ИдентификаторыОбъектовМетаданных?

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

Принцип работы:

  1. Тип измерения: В измерении нашего регистра сведений мы устанавливаем тип данных СправочникСсылка.ИдентификаторыОбъектовМетаданных.
  2. Получение идентификатора: Для получения ссылки на нужный элемент этого справочника мы используем специальные функции БСП.
  3. Запись в регистр: Полученную ссылку мы записываем в измерение регистра сведений.

Преимущества этого подхода:

  1. Исключительная устойчивость к переименованию объектов метаданных: Это главное и самое значимое преимущество. Если мы переименуем любой объект конфигурации (например, справочник "ДоговорыКонтрагентов" в "ДоговорыСПартнерами"), уникальный элемент в справочнике ИдентификаторыОбъектовМетаданных, соответствующий этому объекту, останется прежним. Таким образом, все записи в нашем регистре сведений, использующие эту ссылку, продолжат работать корректно без необходимости ручного исправления.
  2. Автоматическое обновление: При использовании БСП в конфигурации, справочник ИдентификаторыОбъектовМетаданных автоматически актуализируется при обновлении. Система сама следит за появлением новых объектов метаданных и изменением существующих.
  3. Высокая производительность: Сравнение и поиск по ссылкам (типа СправочникСсылка) в 1С всегда выполняется значительно быстрее, чем по строковым значениям, особенно при больших объемах данных.
  4. Стандартизация: Это стандартное решение, предлагаемое фирмой 1С в составе БСП, что означает его надежность, поддержку и соответствие лучшим практикам разработки.

Пример использования:

Рассмотрим, как мы можем получить и использовать идентификатор объекта метаданных.


// Предположим, у нас есть ссылка на конкретный объект, например, элемент справочника "ДоговорыКонтрагентов"
ОбъектСсылка = Справочники.ДоговорыКонтрагентов.НайтиПоКоду("000000001");

// Получим объект метаданных для типа этого объекта
Если ОбъектСсылка <> Неопределено Тогда
    ОбъектМетаданных = ОбъектСсылка.Метаданные();

    // Далее, через специальную функцию общего модуля БСП
    // "ИдентификаторыОбъектовМетаданныхКлиентСервер" или "ИдентификаторыОбъектовМетаданныхПереопределяемый"
    // (или напрямую Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоИдентификатору(ОбъектМетаданных.ПолноеИмя()))
    // мы можем получить ссылку на элемент справочника ИдентификаторыОбъектовМетаданных.
    // Примечание: Для работы с этим справочником часто используются служебные функции БСП,
    // но для простоты примера мы можем использовать поиск по полному имени.

    ИдентификаторТипа = Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоИдентификатору(ОбъектМетаданных.ПолноеИмя());

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

Если нам нужно получить полное имя типа объекта метаданных обратно из ссылки на элемент справочника ИдентификаторыОбъектовМетаданных, мы также можем использовать соответствующие функции или свойства элемента:


// Пусть ЗаписьРегистра.ТипОбъекта - это ссылка на элемент справочника ИдентификаторыОбъектовМетаданных
ИдентификаторТипа = ЗаписьРегистра.ТипОбъекта;

Если ИдентификаторТипа <> Неопределено Тогда
    ПолноеИмяТипа = ИдентификаторТипа.Идентификатор; // Реквизит "Идентификатор" хранит полное имя
    // Или использовать функцию БСП:
    // ПолноеИмяТипа = ИдентификаторыОбъектовМетаданных.ПолучитьПолноеИмяПоИдентификатору(ИдентификаторТипа);

    Сообщить("Полное имя типа из идентификатора: " + ПолноеИяТипа);
    // Теперь мы можем использовать это полное имя для динамического получения ссылки на объект метаданных
    // или для других целей, например, для определения тома хранения файлов.
КонецЕсли;

Использование этого справочника является наиболее гибким и устойчивым решением, которое минимизирует риски, связанные с изменением структуры конфигурации, и обеспечивает высокую производительность.

Вариант 4: Использование XML-сериализации (сложный, нерекомендуемый)

В теории существует еще один, более экзотический способ хранения типа объекта — это XML-сериализация объекта ОписаниеТипов. Объект ОписаниеТипов позволяет описать один или несколько типов данных. Его можно сериализовать в строку, а затем десериализовать обратно.

Принцип реализации:

  1. Получение ОписаниеТипов: Мы создаем объект ОписаниеТипов, передавая ему нужный тип объекта метаданных.
  2. Сериализация в XML: Используя объект ЗаписьXML, мы сериализуем ОписаниеТипов в строковое представление XML. Эту строку затем сохраняем в измерении регистра с типом Строка.
  3. Десериализация: При необходимости извлечь тип, мы читаем строку XML из регистра, создаем ЧтениеXML и десериализуем ОписаниеТипов обратно.

Недостатки:

  1. Избыточная сложность: Для решения такой задачи этот метод чрезмерно сложен как в реализации, так и в отладке.
  2. Нечитаемость данных: Записи в регистре становятся абсолютно нечитаемыми для человека, что затрудняет анализ и отладку.
  3. Низкая производительность запросов: Построение запросов по такому строковому полю, содержащему XML, крайне затруднительно и неэффективно.
  4. Зависимость от формата XML: Любые изменения в формате сериализации ОписаниеТипов в новых версиях платформы могут привести к несовместимости.

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

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

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

  1. Хранение строкового представления типа — это самое простое, но и самое ненадежное решение из-за жесткой привязки к имени объекта метаданных.
  2. Использование Плана видов характеристик предоставляет некоторую устойчивость, но требует ручного администрирования и поддержки.
  3. Использование справочника ИдентификаторыОбъектовМетаданных из БСП — это рекомендованное и архитектурно правильное решение. Оно обеспечивает максимальную устойчивость к изменениям конфигурации, автоматическую актуализацию и высокую производительность. Мы настоятельно рекомендуем использовать именно этот подход для обеспечения долгосрочной стабильности и надежности вашей системы.
  4. XML-сериализация — это слишком сложный и неэффективный способ для данной задачи.

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

← На главную