Получаем UUID, ссылку и полное имя объекта в 1С
Содержание
Чаще всего под «идентификатором объекта» понимают UUID конкретной записи — строку вида a1b2c3d4-.... Получить её из любой ссылки можно одной строкой кода: Ссылка.УникальныйИдентификатор(). Но в 1С под словом «идентификатор» скрываются три разные сущности, и путаница между ними — главная причина, почему скопированный GUID «не находит» объект.
Ниже — чем отличается UUID записи от полного имени объекта метаданных и от внутреннего UUID самого объекта конфигурации, как получить каждый из них программно, запросом и без единой строки кода, а также что делать со ссылочными полями составного типа и значениями перечислений.
Три разных идентификатора: не перепутайте
Прежде чем писать код, определитесь, что именно нужно — иначе будете искать одно, а получать другое.
- 🔹 Полное имя объекта метаданных — строка
Справочник.Номенклатура,Документ.РеализацияТоваровУслуг. Это имя вида объекта в конфигурации, одинаковое во всех базах одной конфигурации. - 🔹 UUID записи (элемента) —
a1b2c3d4-e5f6-7890-abcd-ef1234567890. Уникален для одной конкретной строки справочника или документа внутри базы. Именно его обычно и имеют в виду. - 🔹 Внутренний UUID объекта метаданных — GUID, который платформа присваивает самому объекту конфигурации (справочнику как таковому). Он хранится в конфигурации и используется, например, при обмене и сериализации.
Один и тот же GUID записи не говорит, из какого он справочника. Тип хранится отдельно от UUID. Поэтому «найти по UUID» без указания ссылочного типа нельзя — об этом ниже в разделе про составные типы.
Короткая сводка, что брать под задачу:
| Что нужно | Что получать | Чем |
|---|---|---|
| Привязать запись к внешней системе | UUID записи | Ссылка.УникальныйИдентификатор() |
| Записать «какой это вид объекта» | Полное имя | Ссылка.Метаданные().ПолноеИмя() |
| Восстановить ссылку из строки | UUID + тип | Менеджер.ПолучитьСсылку(...) |
| Сопоставить объекты при обмене | Внутренний UUID метаданных | выгрузка конфигурации |
Как получить UUID записи из ссылки
У любой ссылки на справочник, документ, план видов характеристик и подобный объект есть метод УникальныйИдентификатор(). Он возвращает значение типа УникальныйИдентификатор, а не строку:
УИД = Ссылка.УникальныйИдентификатор(); // тип УникальныйИдентификатор
СтрокаУИД = Строка(УИД); // "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
Для записи в текстовый файл, в поле другой системы или в лог приводите результат к строке через Строка() или конкатенацию.
UUID записи постоянен весь срок её жизни. Перепроведение документа, изменение реквизитов, пометка на удаление его не меняют. Новый UUID появляется только при создании новой записи.
Второй способ получить строковое представление — функция XMLСтрока(). Для ссылки она тоже возвращает UUID записи:
СтрокаУИД = XMLСтрока(Ссылка); // тот же GUID записи
Разница практическая: XMLСтрока() работает с любым значением XDTO-сериализуемого типа и парна функции XMLЗначение(), которой ссылку восстанавливают обратно (см. следующий раздел).
Старые функции ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр() для этой задачи использовать не стоит: их внутренний формат не документирован и может меняться между версиями платформы. Для сохранения и восстановления ссылок берите пару XMLСтрока() / XMLЗначение().
Как получить ссылку запросом по реквизиту
Если UUID неизвестен, а запись надо найти по артикулу, коду или наименованию, ссылку достают запросом, а уже из неё берут идентификатор. В языке запросов нет функции, превращающей ссылку в строковый GUID, — запрос возвращает саму ссылку, а UUID получают в коде:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул = &Артикул";
Запрос.УстановитьПараметр("Артикул", "АРТ-00123");
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
УИД = Выборка.Ссылка.УникальныйИдентификатор();
КонецЕсли;
В запросе доступно поле Ссылка и виртуальное Представление/функция ПРЕДСТАВЛЕНИЕ(...) для читаемого имени, но не строковый UUID. Поэтому схема всегда такая: запрос отдаёт ссылку → код отдаёт идентификатор.
Когда нужно выгрузить идентификаторы сразу по многим записям (например, для сверки с внешней базой), запрос отдаёт выборку, а цикл собирает пары «представление → UUID»:
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Строка = Выборка.Ссылка;
Сообщить(Строка(Строка) + " = " + XMLСтрока(Строка));
КонецЦикла;
Если по условию находится больше одной записи, Выборка.Следующий() вернёт только первую. Для контроля добавляйте РАЗЛИЧНЫЕ, проверяйте количество строк в результате или уточняйте отбор, иначе получите идентификатор «случайного» дубля.
Как восстановить ссылку по строке UUID
Обратная задача — есть строковый GUID из внешней системы, нужна ссылка. Понадобятся две вещи: сам UUID и ссылочный тип (из какого справочника запись). Без типа платформа не знает, куда смотреть.
Первый способ — через менеджер объекта и метод ПолучитьСсылку():
УИД = Новый УникальныйИдентификатор("a1b2c3d4-e5f6-7890-abcd-ef1234567890");
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(УИД);
Второй — через XMLЗначение(), если UUID пришёл строкой:
Ссылка = XMLЗначение(Тип("СправочникСсылка.Номенклатура"),
"a1b2c3d4-e5f6-7890-abcd-ef1234567890");
У ПолучитьСсылку() есть особенность, на которой спотыкаются чаще всего:
ПолучитьСсылку() не проверяет существование записи. Он всегда возвращает ссылку — даже если записи с таким UUID в базе нет. Проверять Ссылка.Пустая() бесполезно: такая ссылка не пустая.
Чтобы убедиться, что запись реально есть, прочитайте объект:
Объект = Ссылка.ПолучитьОбъект();
Если Объект = Неопределено Тогда
// записи с таким UUID в базе нет
КонецЕсли;
Как посмотреть идентификатор без программирования
Писать код не обязательно. Для разовой задачи подойдут готовые инструменты.
- Консоль запросов. Внешняя обработка «Консоль запросов» (входит в комплект ИТС и типовые поставки) умеет выводить колонку со ссылкой. Правый клик по значению ссылки в результате — и в контекстном меню обычно есть команда показать внутренний идентификатор или открыть объект.
- Консоль кода (исполнения кода). В неё вставляете три строки из разделов выше и сразу видите результат в сообщении — удобно, когда UUID нужен прямо сейчас.
- Выгрузка конфигурации в файлы. Для внутреннего UUID объекта метаданных (не записи): в Конфигураторе
Конфигурация → Выгрузить конфигурацию в файлы. У каждого объекта появится свой XML-файл, в корневом элементе которого есть атрибутuuid— это и есть внутренний идентификатор справочника или документа как объекта конфигурации.
UUID объекта метаданных одинаков во всех базах, развёрнутых из одной конфигурации, потому что он — часть конфигурации. UUID записи, наоборот, живёт внутри конкретной информационной базы.
Полное имя и имя объекта метаданных из кода берутся так:
Метаданные.Справочники.Номенклатура.ПолноеИмя(); // "Справочник.Номенклатура"
Метаданные.Справочники.Номенклатура.Имя(); // "Номенклатура"
Ссылка.Метаданные().ПолноеИмя(); // то же, но от конкретной ссылки
Готовое решение: внешняя обработка
Чтобы не вспоминать синтаксис каждый раз, оформите разовую универсальную внешнюю обработку
. На форму кладёте поле ссылки составного типа (или ЛюбаяСсылка) и поле для результата, а в обработчик команды — несколько строк:
&НаСервере
Процедура ПоказатьИдентификаторНаСервере(Ссылка)
Если Ссылка = Неопределено ИЛИ НЕ ЗначениеЗаполнено(Ссылка) Тогда
Возврат;
КонецЕсли;
ПолноеИмя = Ссылка.Метаданные().ПолноеИмя();
УИД = Строка(Ссылка.УникальныйИдентификатор());
Результат = ПолноеИмя + " : " + УИД;
КонецПроцедуры
Для типовых конфигураций на Библиотеке стандартных подсистем задача ещё проще. В БСП есть справочник «Идентификаторы объектов метаданных», где каждому объекту конфигурации сопоставлен его внутренний UUID и готовые методы для перевода «объект метаданных ↔ идентификатор». Если работаете в типовой на БСП, используйте этот механизм вместо собственного — он уже учитывает переименования и обновления.
Расширения конфигурации (появились в платформе 8.3.6) позволяют добавить такую обработку или дополнительную команду к объекту, не снимая конфигурацию с поддержки. Загрузка .cfe и «Обновить конфигурацию базы данных» — два отдельных шага.
Ссылка.УникальныйИдентификатор(). Храните рядом ссылочный тип (полное имя), иначе потом не восстановите ссылку.Ссылка.Метаданные().ПолноеИмя() — строка Справочник.Номенклатура.uuid) или справочник «Идентификаторы объектов метаданных» в БСП.Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(...)) либо XMLЗначение(Тип(...), "...").Составные типы, перечисления и предопределённые значения
Со ссылочным полем составного типа (например, «Контрагент» может быть и юрлицом, и физлицом) UUID получается так же — метод УникальныйИдентификатор() есть у любой ссылки. Но перед восстановлением ссылки из строки нужно знать конкретный тип. Определить его помогает ТипЗнч():
Если ТипЗнч(Ссылка) = Тип("СправочникСсылка.Номенклатура") Тогда
// ссылка ведёт на номенклатуру
КонецЕсли;
Для сохранения и восстановления значения составного типа вместе с типом удобнее пара XMLСтрока() / XMLЗначение(): первая запишет и UUID, и тип в понятном виде, вторая восстановит значение по типу и строке.
Перечисления устроены иначе. Их значения предопределены в конфигурации, отдельных записей в базе нет. Надёжный «идентификатор» значения перечисления — его имя, а ссылку по имени возвращает ПредопределенноеЗначение():
Ставка = ПредопределенноеЗначение("Перечисление.СтавкиНДС.НДС20");
Та же функция работает и для предопределённых элементов справочников, планов счетов, планов видов характеристик:
Рубль = ПредопределенноеЗначение("Справочник.Валюты.Рубль");
Для перечислений и предопределённых значений ориентируйтесь на имя, а не на UUID: имя стабильно и читаемо, а строковый GUID предопределённого значения привязывать к внешним системам смысла мало.
Частые вопросы
Сохранится ли UUID записи при переносе базы через выгрузку/загрузку (.dt)?
Совпадёт ли UUID одной и той же номенклатуры в двух разных базах?
Можно ли по одному UUID понять, из какого он справочника?
Почему `ПолучитьСсылку()` вернул ссылку, а объекта в базе нет?
Ссылка.ПолучитьОбъект() — для несуществующей записи он вернёт Неопределено.Чем `УникальныйИдентификатор()` отличается от `XMLСтрока()` для ссылки?
УникальныйИдентификатор() возвращает значение типа УникальныйИдентификатор, XMLСтрока() — сразу строку и парна XMLЗначение() для обратного преобразования вместе с типом.