Как правильно сохранить объект метаданных в реквизите 1С?

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

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

Выясним причину: почему нельзя хранить ОбъектМетаданных напрямую

Проанализируем архитектуру платформы. Тип данных ОбъектМетаданных (например, описание справочника "Контрагенты") существует исключительно в оперативной памяти в момент работы сеанса. Это часть структуры самой конфигурации, её «чертеж». База данных 1С спроектирована так, чтобы хранить только прикладные данные (числа, строки, даты, булево) или ссылки на записи в таблицах (ссылочные типы).

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

Способ 1: Использование полного имени (строковый метод)

Самый простой и часто используемый метод — преобразование объекта метаданных в уникальную строку, которую легко сохранить в обычный реквизит типа Строка. Рассмотрим этот процесс по шагам.

Во-первых, нам необходимо получить строковое представление объекта. Для этого у любого объекта метаданных есть метод ПолноеИмя(). Проанализируем пример кода:


// Получаем объект метаданных справочника
ОбъектМета = Метаданные.Справочники.Номенклатура;

// Записываем его полное имя в строковый реквизит
ИмяДляСохранения = ОбъектМета.ПолноеИмя(); 
// В переменной будет строка "Справочник.Номенклатура"

Во-вторых, когда нам потребуется выполнить обратное действие — получить объект метаданных из сохраненной строки — мы воспользуемся глобальным контекстом Метаданные. Посмотрим на пример восстановления:


// Восстанавливаем объект из строки, сохраненной в реквизите
ИмяИзБазы = Объект.ИмяРеквизитаСтрока; // Например, "Справочник.Номенклатура"
НайденныйОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ИмяИзБазы);

Если НайденныйОбъектМетаданных <> Неопределено Тогда
    // Теперь мы можем программно обращаться к свойствам, например:
    Сообщить("Выбран объект: " + НайденныйОбъектМетаданных.Синоним);
КонецЕсли;

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

Способ 2: Использование идентификаторов объектов метаданных (БСП)

Если вы работаете в современной конфигурации, построенной на базе Библиотеки стандартных подсистем (БСП), существует более «профессиональный» путь. В составе БСП есть специальный справочник ИдентификаторыОбъектовМетаданных.

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

  1. Ссылочная целостность: Вы храните не просто текст, а ссылку на элемент справочника. Это позволяет использовать стандартные механизмы поиска ссылок и отчетов.
  2. Производительность: Поиск и фильтрация по ссылке в базе данных происходят быстрее, чем по текстовой строке.
  3. Стабильность: Даже если объект будет переименован в конфигураторе (что бывает редко, но случается), механизмы БСП обновят идентификатор, сохранив связи в данных.

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


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

// Теперь эту ссылку можно записать в реквизит табличной части или документа
Объект.ИдентификаторМетаданных = СсылкаНаИдентификатор;

Различия между Типом и Объектом метаданных

Часто в процессе разработки возникает путаница между понятиями Тип и ОбъектМетаданных. Выясним разницу, чтобы не совершать ошибок при проектировании:

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

Рекомендации по работе на сервере и клиенте

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

Проанализируем оптимальный алгоритм работы:

  1. Выполняйте сбор информации об объектах метаданных на сервере.
  2. Формируйте из них список значений или таблицу, где в качестве значения будет выступать ПолноеИмя() (строка).
  3. Передавайте этот список на клиент для выбора пользователем.
  4. После выбора сохраняйте строковое значение в базу.

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

← На главную