GUID объекта в 1С: получение, генерация и поиск по идентификатору
Содержание
GUID объекта в 1С получают методом УникальныйИдентификатор() у ссылки: Ид = Ссылка.УникальныйИдентификатор(). Результат — значение типа УникальныйИдентификатор, которое легко превратить в строку через Строка(Ид) и получить привычный вид a1b2c3d4-5d6e-7f80-9a0b-1c2d3e4f5a6b.
Дальше три близких задачи, которые часто путают: получить GUID уже существующего элемента, сгенерировать новый идентификатор с нуля и найти объект обратно по его GUID. У каждой свой приём, и ошибка обычно в том, что вместо одного берут другой. Разберём все на коде, который можно вставить в модуль и запустить.
Ссылка и УникальныйИдентификатор — это разные типы
Новичка сбивает то, что «ссылка на объект» и «GUID объекта» — не одно и то же, хотя оба однозначно указывают на запись.
- Ссылка (
СправочникСсылка.Номенклатура,ДокументСсылка.РеализацияТоваровУслуг) — платформенный тип. Хранит внутри идентификатор плюс информацию о таблице, умеет открывать объект, читать реквизиты, участвовать в запросах. - УникальныйИдентификатор (UUID / GUID) — только 16 байт самого идентификатора, без привязки к типу. Это чистое значение, которое удобно хранить в тексте, передавать во внешнюю систему, сравнивать.
Отсюда главное следствие: по одному GUID платформа не знает, из какого он справочника или документа. Поэтому при обратном поиске (раздел ниже) тип объекта нужно указывать явно — Справочники.Номенклатура.ПолучитьСсылку(...).
Ещё одно поле, которое путают с GUID, — внутренний Код справочника или Номер документа. Код можно менять руками, он уникален только в пределах одного справочника и привязан к учётной логике. GUID не меняется никогда за всё время жизни записи и уникален по всей базе. Для технической идентификации опираются именно на GUID.
Чтобы не держать в голове пять методов, вот сводка — к какой задаче какой приём:
| Задача | Вызов | Результат |
|---|---|---|
| GUID существующего объекта | Ссылка.УникальныйИдентификатор() | значение УникальныйИдентификатор |
| Привести GUID к строке | Строка(Ид) или XMLСтрока(Ид) | текст из 36 символов |
| Новый случайный GUID | Новый УникальныйИдентификатор() | новое значение |
| GUID из строки | Новый УникальныйИдентификатор(Текст) | значение из текста |
| Ссылка по GUID | Менеджер.ПолучитьСсылку(Ид) | ссылка (без проверки существования) |
Разберём каждую строку подробно.
Как получить GUID существующего элемента или документа
Базовый случай — есть ссылка, нужен её идентификатор. Метод один:
СсылкаНоменклатуры = Справочники.Номенклатура.НайтиПоКоду("00-0001");
Если ЗначениеЗаполнено(СсылкаНоменклатуры) Тогда
Ид = СсылкаНоменклатуры.УникальныйИдентификатор();
СтрокаGUID = Строка(Ид);
Сообщить(СтрокаGUID); // a1b2c3d4-5d6e-7f80-9a0b-1c2d3e4f5a6b
КонецЕсли;
Метод УникальныйИдентификатор() есть у любой ссылки: элемента справочника, документа, плана видов характеристик, счёта, задачи. Возвращает он значение типа УникальныйИдентификатор, а строковое представление вы получаете функцией Строка().
Проверяйте ссылку на заполненность перед вызовом метода. У пустой ссылки (Справочники.Номенклатура.ПустаяСсылка()) идентификатор тоже есть, но он нулевой — 00000000-0000-0000-0000-000000000000, и в выгрузку такой GUID попадать не должен.
Если нужна не строка с дефисами, а значение для XML-обмена, используйте XMLСтрока(Ид) — формат тот же, но вызов семантически правильный для сериализации.
Частая обёртка — функция, которая по ссылке любого типа отдаёт GUID строкой:
Функция GUIDПоСсылке(Ссылка) Экспорт
Если Не ЗначениеЗаполнено(Ссылка) Тогда
Возврат "";
КонецЕсли;
Возврат Строка(Ссылка.УникальныйИдентификатор());
КонецФункции
Такую функцию удобно держать в общем модуле и вызывать из любого места конфигурации.
Как сгенерировать новый GUID программно
Когда идентификатор нужен заранее — до записи объекта, для внешнего ключа, для имени временного файла — его создают конструктором:
НовыйИд = Новый УникальныйИдентификатор();
Сообщить(Строка(НовыйИд)); // каждый вызов даёт новое случайное значение
Без параметра конструктор выдаёт новый случайный UUID. Вероятность совпадения с уже существующим идентификатором на практике равна нулю — поэтому GUID и годится как ключ без центрального счётчика.
Важная оговорка: GUID не несёт в себе времени создания и не идёт по порядку. По нему нельзя отсортировать объекты «от старых к новым» и нельзя понять, какой элемент создан раньше. Для хронологии берут отдельный реквизит с датой, а GUID оставляют только для идентификации. Если при записи объекта вы не вызываете УстановитьСсылкуНового(), платформа сама сгенерирует идентификатор — руками это делать нужно лишь тогда, когда значение требуется заранее или должно совпасть с внешним.
Иногда наоборот: GUID пришёл строкой (из файла, из ответа веб-сервиса), и его надо превратить в значение. Передайте строку в конструктор:
Ид = Новый УникальныйИдентификатор("a1b2c3d4-5d6e-7f80-9a0b-1c2d3e4f5a6b");
Строка должна быть в каноническом формате — 32 шестнадцатеричные цифры и четыре дефиса. Если формат нарушен (лишние пробелы, фигурные скобки {}, обрезанная длина), конструктор вызовет ошибку. Приводите строку в порядок заранее: СокрЛП(), убрать скобки через СтрЗаменить().
Отдельный приём — создать ссылку с заранее заданным GUID. Это нужно при переносе данных, когда объект в приёмнике должен иметь тот же идентификатор, что и в источнике:
ЗаданныйИд = Новый УникальныйИдентификатор("a1b2c3d4-5d6e-7f80-9a0b-1c2d3e4f5a6b");
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.УстановитьСсылкуНового(Справочники.Номенклатура.ПолучитьСсылку(ЗаданныйИд));
НовыйЭлемент.Наименование = "Перенесённая позиция";
НовыйЭлемент.Записать();
Метод УстановитьСсылкуНового() работает только до первой записи объекта. У уже записанного элемента GUID сменить нельзя — это и есть гарантия его неизменности.
Поиск объекта по GUID
Обратная задача: есть идентификатор, нужна ссылка. Поскольку по GUID тип не определяется, менеджер объекта указываете вы сами методом ПолучитьСсылку():
Ид = Новый УникальныйИдентификатор("a1b2c3d4-5d6e-7f80-9a0b-1c2d3e4f5a6b");
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(Ид);
Здесь важная тонкость. Метод ПолучитьСсылку() НЕ проверяет, существует ли объект в базе. Он всегда возвращает корректную ссылку нужного типа, даже если записи с таким GUID нет. Это сделано нарочно — ссылку можно построить, пока объект ещё не записан.
Проверять существование нужно отдельно. Два надёжных способа:
Способ 1 — попытаться получить объект. Если записи нет, вернётся Неопределено:
Если Ссылка.ПолучитьОбъект() = Неопределено Тогда
Сообщить("Объекта с таким GUID в базе нет");
КонецЕсли;
Способ 2 — запрос. Предпочтителен в серверном коде: не загружает объект целиком и работает быстрее:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура
|ГДЕ Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
НайденоВБазе = Не Запрос.Выполнить().Пустой();
Обратите внимание: в запрос передаётся уже готовая ссылка, а не строка GUID. Сравнивать поле Ссылка напрямую с текстом идентификатора в языке запросов нельзя — сначала соберите ссылку методом ПолучитьСсылку(), потом передайте её параметром.
Если тип объекта заранее неизвестен (GUID может быть и из справочника, и из документа), универсального однопроходного поиска нет — придётся перебирать кандидатов-типы и для каждого проверять существование. Поэтому в обменах GUID почти всегда передают вместе с именем типа объекта.
Про производительность: сам ПолучитьСсылку() в базу не ходит и работает мгновенно — он лишь собирает значение ссылки из типа и идентификатора. «Дорогой» здесь не он, а проверка существования и чтение реквизитов. Поэтому если по итогу всё равно нужны данные объекта, сразу стройте запрос по ссылке, а не вызывайте ПолучитьОбъект() ради одной проверки.
Как посмотреть GUID объекта без программирования
Иногда код писать не нужно — GUID требуется разово, чтобы прописать его в настройке обмена или найти «потерявшийся» элемент. Посмотреть идентификатор можно прямо в режиме «1С:Предприятие».
В конфигурациях на базе Библиотеки стандартных подсистем (это Бухгалтерия, ЗУП, УТ, ERP и большинство типовых) у списков и форм объектов есть команда «Получить ссылку» в меню Ещё. Она формирует навигационную ссылку — длинную строку вида e1cib/data/Справочник.Номенклатура?ref=.... Хвост после ref= и есть GUID объекта, только записанный без дефисов, 32 шестнадцатеричные цифры подряд.
Чтобы превратить этот хвост в привычный вид с дефисами, разбейте его по схеме 8-4-4-4-12:
a1b2c3d4·5d6e·7f80·9a0b·1c2d3e4f5a6b→a1b2c3d4-5d6e-7f80-9a0b-1c2d3e4f5a6b.
Навигационную ссылку удобно использовать и как есть: вставьте её в адресную строку открытого приложения (или перешлите коллеге внутри той же базы) — 1С откроет нужный объект. Это быстрый способ дать ссылку на карточку, не описывая путь к ней словами.
Если команды «Получить ссылку» в меню нет (нетиповая конфигурация без БСП), остаётся программный путь из разделов выше — вывести Строка(Ссылка.УникальныйИдентификатор()) в сообщение через обработку или консоль кода.
Передача GUID во внешние системы и обмены
При интеграции GUID — самый надёжный ключ связи: он не меняется и уникален по всей базе. Правила простые.
- Наружу отдавайте строкой.
Строка(Ссылка.УникальныйИдентификатор())илиXMLСтрока(...)для XML-пакетов. Во внешней БД, JSON или файле GUID хранится как текст из 36 символов. - Внутрь принимайте через конструктор. Пришедшую строку оборачивайте в
Новый УникальныйИдентификатор(ТекстИзВнешнейСистемы), затемПолучитьСсылку(). - Храните пару «тип + GUID». Одного GUID для восстановления ссылки мало — нужен менеджер объекта.
Для внешних источников данных и прямых SQL-запросов учитывайте представление идентификатора. В тексте GUID — это 36 символов с дефисами, но в самой СУБД 1С хранит его как 16-байтовое двоичное поле. Если читаете таблицу 1С напрямую (через внешний источник данных или отчётную СУБД), приводите поле к строке на стороне базы и сопоставляйте с результатом Строка(УникальныйИдентификатор), чтобы форматы совпали.
Ещё один прикладной формат — навигационная ссылка вида e1cib/data/Справочник.Номенклатура?ref=a1b2c3d45d6e7f809a0b1c2d3e4f5a6b. Получить её на объект можно методом ПолучитьНавигационнуюСсылку(Ссылка). В параметре ref идёт тот же GUID, но без дефисов — это удобно для вставки ссылок в письма и во внешние порталы.
Отдельная проблема обмена — один и тот же GUID в источнике и приёмнике. Если вы создаёте объекты в приёмнике методом УстановитьСсылкуНового() с идентификатором из источника, связь получается автоматической: один GUID однозначно указывает на одну запись в обеих базах, и повторная загрузка того же объекта не задвоит его. Это основа идемпотентных обменов.
Когда перенести исходный GUID нельзя (объекты в приёмнике уже созданы со своими идентификаторами), применяют регистр соответствий: регистр сведений , где в измерениях хранят внешний ключ (GUID источника строкой), а в ресурсе — ссылку на локальный объект. При каждой загрузке вы ищете запись по внешнему ключу: нашли — обновляете существующий объект, нет — создаёте новый и дописываете строку соответствия. Так два GUID на одну сущность уживаются без конфликтов.
Типичные ошибки при работе с идентификаторами
Чаще всего спотыкаются на том, что GUID и ссылку используют не по назначению. Подсказка по симптомам:
Частые вопросы
Чем УникальныйИдентификатор отличается от ссылки на объект?
Меняется ли GUID объекта при переименовании или изменении кода?
Как получить GUID из строки, если он пришёл в фигурных скобках?
СтрЗаменить(Строка, "{", ""), СтрЗаменить(Строка, "}", ""), СокрЛП()), затем передайте чистую строку из 36 символов в Новый УникальныйИдентификатор().Можно ли по GUID узнать, из какого он справочника или документа?
ПолучитьСсылку().Как сгенерировать новый GUID без привязки к объекту?
Новый УникальныйИдентификатор() без параметра возвращает новое случайное значение. Его можно использовать как внешний ключ, имя временного файла или ключ идемпотентности до записи объекта.