GUID объекта в 1С: получение, генерация и поиск по идентификатору

· 9 мин

Содержание

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 и ссылку используют не по назначению. Подсказка по симптомам:

Диагностика: выберите симптом

Частые вопросы

Чем УникальныйИдентификатор отличается от ссылки на объект?
Ссылка знает свой тип (справочник, документ) и умеет открывать объект. УникальныйИдентификатор — только 16 байт самого идентификатора без привязки к таблице. Поэтому по одному GUID тип объекта не определить.
Меняется ли GUID объекта при переименовании или изменении кода?
Нет. GUID задаётся один раз при создании записи и не меняется за всё время её жизни — ни при смене наименования, ни при смене кода или номера. На этом и строят обмены.
Как получить GUID из строки, если он пришёл в фигурных скобках?
Уберите скобки и пробелы (СтрЗаменить(Строка, "{", ""), СтрЗаменить(Строка, "}", ""), СокрЛП()), затем передайте чистую строку из 36 символов в Новый УникальныйИдентификатор().
Можно ли по GUID узнать, из какого он справочника или документа?
Нет, напрямую нельзя — тип в идентификаторе не хранится. В обмене GUID всегда передают вместе с именем типа объекта, чтобы на приёмнике вызвать нужный ПолучитьСсылку().
Как сгенерировать новый GUID без привязки к объекту?
Новый УникальныйИдентификатор() без параметра возвращает новое случайное значение. Его можно использовать как внешний ключ, имя временного файла или ключ идемпотентности до записи объекта.