Как имея ссылку на реквизит и GUID получить ссылку на объект 1С

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

В практике разработчика 1С часто возникают ситуации, когда необходимо восстановить или заполнить данные объекта, имея на руках лишь строковое представление уникального идентификатора (GUID) и понимание того, в какой реквизит эти данные должны попасть. Типичный пример — парсинг XML-файла, логов или работа с механизмами версионирования (как в БСП), где ссылки часто хранятся в упрощенном виде. Разберем подробно, как правильно преобразовать строку в полноценную ссылку, используя встроенные механизмы платформы.

Проблема: когда известен GUID, но не понятен тип

Представим ситуацию: мы программно обрабатываем справочник Номенклатура. У нас есть строка "f54af7af-3d13-11e1-8113-001a4d407980", которая является идентификатором базовой единицы измерения. Мы знаем, что это значение должно быть записано в реквизит БазоваяЕдиницаИзмерения. Однако, чтобы записать его, нам нужно получить объект типа СправочникСсылка.ЕдиницыИзмерения.

Если мы просто напишем Справочники.ЕдиницыИзмерения.ПолучитьСсылку(), нам придется жестко прописывать имя справочника в коде. Это неудобно, если мы пишем универсальную обработку. Рассмотрим более гибкие методы.

Решение 1: Универсальный метод через XMLЗначение

Проанализируем самый эффективный способ, который подходит для большинства задач. Платформа 1С предоставляет функцию XMLЗначение(). Она уникальна тем, что умеет преобразовывать строковые данные в типы 1С, основываясь на переданном описании типа. Это касается не только справочников, но и перечислений, чисел, дат и булевых значений.

Для того чтобы не «хардкодить» тип, мы можем получить его прямо из существующего объекта или его метаданных. Посмотрим на пример кода:


// Предположим, Выборка.Объект — это наша Номенклатура
// ИмяРеквизита — строка "БазоваяЕдиницаИзмерения"
// СтрокаGUID — тот самый идентификатор из файла

ИмяРеквизита = "БазоваяЕдиницаИзмерения";
СтрокаGUID = "f54af7af-3d13-11e1-8113-001a4d407980";

// Получаем тип реквизита напрямую из объекта
ТипНужногоЗначения = ТипЗнч(Объект[ИмяРеквизита]);

// Преобразуем строку в ссылку нужного типа
СсылкаНаОбъект = XMLЗначение(ТипНужногоЗначения, СтрокаGUID);

// Теперь можно смело заполнять
Объект[ИмяРеквизита] = СсылкаНаОбъект;

Важный нюанс: метод ТипЗнч(Объект[ИмяРеквизита]) отлично работает, если реквизит уже инициализирован или имеет простой (не составной) тип. Если же реквизит пустой, а тип у него составной, этот метод может вернуть Неопределено. В таком случае надежнее обращаться к метаданным.

Решение 2: Динамическое получение менеджера через метаданные

Если нам нужно именно «найти» менеджер справочника или документа, зная только имя реквизита, проанализируем ситуацию через дерево метаданных. Этот способ сложнее, но он дает полный контроль над процессом.

Рассмотрим алгоритм действий:

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

НовыйGUID = Новый УникальныйИдентификатор(СтрокаGUID);

// Получаем описание типов реквизита из метаданных
ОписаниеТипов = Объект.Метаданные().Реквизиты.БазоваяЕдиницаИзмерения.Тип;
// Берем первый доступный тип (актуально для простых типов)
НужныйТип = ОписаниеТипов.Типы()[0];

// Находим метаданные этого типа в системе
МетаданныеОбъекта = Метаданные.НайтиПоТипу(НужныйТип);

// Определяем имя (например, "ЕдиницыИзмерения")
ИмяОбъекта = МетаданныеОбъекта.Имя;

// В зависимости от того, справочник это или что-то другое, получаем ссылку
Если Метаданные.Справочники.Содержит(МетаданныеОбъекта) Тогда
    Ссылка = Справочники[ИмяОбъекта].ПолучитьСсылку(НовыйGUID);
ИначеЕсли Метаданные.Документы.Содержит(МетаданныеОбъекта) Тогда
    Ссылка = Документы[ИмяОбъекта].ПолучитьСсылку(НовыйGUID);
КонецЕсли;

Особенности работы с перечислениями

При разборе XML-данных часто встречается формат записи перечислений в виде их имен (например, <СтавкаНДС>НДС20</СтавкаНДС>). В этом случае GUID не используется. Функция XMLЗначение здесь также является «золотым стандартом».

Выясним, как это работает: если вы передадите в XMLЗначение тип перечисления и строку с его именем (как оно задано в конфигураторе), система вернет готовую ссылку на значение перечисления. Рассмотрим пример:


// СтрокаИзФайла = "НДС20"
ТипСтавки = Тип("ПеречислениеСсылка.СтавкиНДС");
ЗначениеНДС = XMLЗначение(ТипСтавки, "НДС20");

// Теперь ЗначениеНДС содержит реальную ссылку ПеречислениеСсылка.СтавкиНДС.НДС20

Важные замечания по методу ПолучитьСсылку()

Нужно помнить, что метод менеджера ПолучитьСсылку() работает «лениво». Это означает, что 1С создаст ссылку в памяти, даже если объекта с таким идентификатором на самом деле нет в базе данных. Проанализируем последствия:

Работа с составными типами данных

Ситуация усложняется, когда реквизит может принимать значения разных типов (например, реквизит Владелец может быть и Справочником, и Организацией). В XML-файлах для таких случаев обычно указывается атрибут xsi:type.

Если же у вас есть только GUID и вы не знаете, к какому из типов он относится, вам придется перебирать все типы из ОписаниеТипов.Типы() и проверять наличие объекта в каждом из них. Однако в корректно выгруженных данных тип всегда должен присутствовать явно или неявно через метаданные родительского объекта.

Таким образом, использование XMLЗначение в сочетании с анализом метаданных позволяет создавать надежные и универсальные механизмы импорта и обработки данных, минимизируя количество ошибок, связанных с несоответствием типов.

← На главную