К статье
Практический материал

Разработка и Конфигурация · 13 мин

1С: как получить GUID по ссылке

Как получить GUID по ссылке в 1С: метод УникальныйИдентификатор(), ЗначениеВСтрокуВнутр, запросы и обработчики. Примеры кода, ошибки и проверка результата.

GUID (глобальный уникальный идентификатор) в 1С — это 36-символьная строка вида «8b3f9c2a-1d4e-4a5b-9c6d-7e8f9a0b1c2d», которая однозначно идентифицирует объект базы данных. Он нужен при обмене данными между базами, интеграции с внешними системами, отладке и поиске «потерянных» объектов по строковому идентификатору.

Получить GUID из ссылки можно несколькими способами: штатным методом УникальныйИдентификатор(), через внутреннее представление ЗначениеВСтрокуВнутр(), запросом, а также через сериализацию XML. Выбор зависит от контекста: тонкий клиент или сервер, управляемые или обычные формы, нужен ли GUID одного объекта или пакетная обработка тысяч ссылок.

Важно понимать разницу: GUID существует только у объектов, у которых есть ссылка (справочники, документы, планы видов характеристик и т.п.). У записей регистров сведений, у перечислений и примитивных типов уникального идентификатора нет — попытка получить его приведёт к ошибке или пустому результату.

Что такое GUID в 1С и где он хранится

Каждый объект ссылочного типа в базе 1С имеет уникальный идентификатор, который платформа присваивает при создании объекта и хранит в служебном поле таблицы базы данных. Идентификатор не меняется при переименовании, изменении реквизитов и любых других правках объекта — он «приклеен» к объекту на всё время жизни.

Встроенный язык представляет GUID типом УникальныйИдентификатор. При выводе в строку получается привычный формат с дефисами: 8-4-4-4-12 шестнадцатеричных символов. Именно этот строковый вид используют при обмене с внешними системами, в веб-сервисах и HTTP-API.

Отдельный нюанс — порядок байтов. Внутри файловой базы и в SQL-таблицах GUID хранится в «перевёрнутом» виде, отличном от строкового представления встроенного языка. Поэтому сравнивать идентификатор из запроса напрямую к SQL с тем, что вывела 1С, нельзя без преобразования — это частая причина «не находится объект, хотя GUID правильный».

Основной способ: метод УникальныйИдентификатор()

Штатный и рекомендуемый способ — метод УникальныйИдентификатор(), доступный у любой ссылки. Он возвращает значение типа УникальныйИдентификатор, которое при необходимости приводится к строке:

// Получаем GUID как значение

Идентификатор = СсылкаНаКонтрагента.УникальныйИдентификатор();

// Получаем GUID строкой для передачи во внешнюю систему

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

Сообщить(СтрокаGUID); // например: 8b3f9c2a-1d4e-4a5b-9c6d-7e8f9a0b1c2d

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

bsl
Функция ПолучитьGUIDСтрокой(Ссылка)
	Если Не ЗначениеЗаполнено(Ссылка) Тогда
		Возврат "";
	КонецЕсли;
	Возврат Строка(Ссылка.УникальныйИдентификатор());
КонецФункции

Проверьте поведение с пустой ссылкой: у пустой ссылки GUID тоже существует — это идентификатор из одних нулей (00000000-0000-0000-0000-000000000000). Если логика обмена не должна передавать пустые ссылки, добавьте явную проверку ЗначениеЗаполнено() до получения идентификатора.

Обратное преобразование: из GUID получить ссылку

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

Идентификатор = Новый УникальныйИдентификатор("8b3f9c2a-1d4e-4a5b-9c6d-7e8f9a0b1c2d");

СсылкаНаКонтрагента = Справочники.Контрагенты.ПолучитьСсылку(Идентификатор);

// Проверяем, существует ли объект в базе

Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ Ссылка = &Ссылка");

Запрос.УстановитьПараметр("Ссылка", СсылкаНаКонтрагента);

Если Запрос.Выполнить().Пустой() Тогда

Сообщить("Объект с таким GUID не найден");

КонецЕсли;

Важный момент: ПолучитьСсылку() вернёт ссылку даже если объекта в базе нет — это будет «битая ссылка». Поэтому проверка существования объекта запросом обязательна, иначе при записи данных по несуществующей ссылке получите ошибки ссылочной целостности или «Объект не найден» в интерфейсе.

Альтернативные способы получения GUID

Через ЗначениеВСтрокуВнутр

Функция ЗначениеВСтрокуВнутр() сериализует ссылку во внутреннее строковое представление, из которого GUID можно извлечь разбором строки. Способ исторически использовался в обычных формах и обменах между базами на платформе 8.0–8.1:

СтрокаВнутр = ЗначениеВСтрокуВнутр(СсылкаНаКонтрагента);

// Результат вида: {"#",e7d93d8d-...} — GUID внутри структуры

У способа есть ограничения: функция недоступна на тонком и веб-клиенте (только сервер и толстый клиент), формат строки — внутренний формат платформы, который теоретически может меняться. Для новых разработок используйте УникальныйИдентификатор(), а ЗначениеВСтрокуВнутр оставьте для совместимости со старыми механизмами обмена.

Через XML-сериализацию

Если объект уже передаётся через XML (например, в планах обмена или EnterpriseData), GUID присутствует в атрибуте Ref узла ссылки. Извлечь его можно при записи через ЗаписьXML:

Запись = Новый ЗаписьXML;

Запись.УстановитьСтроку();

ЗаписатьXML(Запись, СсылкаНаКонтрагента);

СтрокаXML = Запись.Закрыть(); // GUID в атрибуте элемента

Этот путь оправдан, только когда XML-представление и так формируется для обмена. Ради одного GUID сериализовать объект в XML нерационально — это заметно медленнее прямого вызова метода.

Получение GUID запросом

В языке запросов нет функции, возвращающей GUID ссылки напрямую. Если идентификаторы нужны пакетно (например, выгрузить 10 000 товаров с GUID), выгружайте ссылки запросом, а GUID получайте в цикле по выборке — это всё равно быстро, так как обращений к базе метод не делает:

Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура");

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

GUID = Строка(Выборка.Ссылка.УникальныйИдентификатор());

// ... запись в файл обмена

КонецЦикла;

Сравнение способов получения GUID

УникальныйИдентификатор()

Штатный способ. Работает везде, быстрый, без обращения к БД. Рекомендуется всегда, когда доступна ссылка.

ЗначениеВСтрокуВнутр()

Только сервер и толстый клиент. Нужен разбор внутреннего формата. Подходит для совместимости со старыми обменами.

XML-сериализация

GUID в атрибуте Ref. Оправдан, только если XML уже формируется для обмена, иначе избыточен и медленен.

Внешние обработки

Готовые обработки «показать GUID» удобны разработчику для разового просмотра, но не для встраивания в код.

Типовые сценарии использования

Обмен между базами 1С

При самописном обмене между двумя базами GUID — основной ключ сопоставления объектов. Типовая схема: при выгрузке передаёте GUID строкой, при загрузке ищете объект через ПолучитьСсылку() с проверкой существования, а если объект не найден — создаёте новый и принудительно присваиваете ему полученный идентификатор через УстановитьСсылкуНового():

НовыйОбъект = Справочники.Контрагенты.СоздатьЭлемент();

НовыйОбъект.УстановитьСсылкуНового(Справочники.Контрагенты.ПолучитьСсылку(Идентификатор));

НовыйОбъект.Наименование = НаименованиеИзФайла;

НовыйОбъект.Записать();

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

Интеграция с сайтом и внешними API

При публикации HTTP-сервиса в 1С GUID объекта обычно передаётся в URL или теле запроса. Приняли строку — преобразуйте в УникальныйИдентификатор внутри обработчика, обернув конструктор в попытку: если внешняя система пришлёт некорректную строку, конструктор выбросит исключение, и без обработки сервис вернёт ошибку 500 вместо понятного ответа.

Порядок действий при поиске объекта по GUID извне
  1. 1
    Примите строку GUID из внешней системы или файла
  2. 2
    Проверьте формат: 36 символов, дефисы на позициях 9, 14, 19, 24
  3. 3
    Создайте значение: Новый УникальныйИдентификатор(СтрокаGUID) внутри Попытка/Исключение
  4. 4
    Получите ссылку через менеджер нужного типа: Справочники.Товары.ПолучитьСсылку(Ид)
  5. 5
    Проверьте существование объекта запросом
  6. 6
    Работайте с объектом или верните осмысленную ошибку вызывающей системе

Частые ошибки и ограничения

Первая группа ошибок связана с типами без ссылок. Попытка вызвать УникальныйИдентификатор() у записи регистра сведений, у строки табличной части или у значения перечисления приведёт к ошибке «Метод объекта не обнаружен». Перед вызовом убедитесь, что значение — именно ссылка, например через Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)).

Вторая группа — путаница с представлениями GUID. Строковый GUID встроенного языка, двоичное представление в SQL и GUID в файлах выгрузки конфигурации могут отличаться порядком байтов. Если сопоставляете данные на уровне SQL-запросов напрямую к базе, учитывайте перестановку байтов — либо выполняйте сравнение средствами 1С, где представление единообразно.

Типичные ошибки
01
Вызов УникальныйИдентификатор() у нессылочного типа — ошибка 'Метод объекта не обнаружен'. Проверяйте тип перед вызовом.
02
Использование ПолучитьСсылку() без проверки существования — появление битых ссылок в базе.
03
Сравнение GUID из SQL-запроса со строкой из 1С без учёта порядка байтов — объект 'не находится'.
04
Передача GUID пустой ссылки (все нули) в обмен как валидного идентификатора — на приёмной стороне создаётся мусор.
05
Сериализация в XML ради одного GUID в цикле — лишняя нагрузка при пакетной обработке.

Третья группа — архитектурная: использование GUID как единственного ключа поиска там, где нужен человекочитаемый ключ. GUID неизменен, но нечитаем; для поиска пользователем лучше подходят код и наименование, а GUID оставьте машинной интеграции.

Для разового просмотра GUID объекта удобно добавить в форму списка или карточку вычисляемую колонку либо воспользоваться консолью кода: выполните Сообщить(Ссылка.УникальныйИдентификатор()) для выбранного объекта. Это быстрее, чем писать отдельную обработку.
ПЗ
Практическое замечание

Проверка результата

После получения GUID убедитесь, что результат корректен. Строка должна содержать ровно 36 символов: 32 шестнадцатеричных знака и 4 дефиса. Обратное преобразование должно давать ту же ссылку — это надёжный круговой тест:

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

Проверка = Справочники.Контрагенты.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID));

Если Проверка <> Ссылка Тогда

ВызватьИсключение "Круговое преобразование GUID не сошлось";

КонецЕсли;

Контрольные точки

Как проверить результат

Формат строки GUID
Норма

36 символов, дефисы на позициях 9, 14, 19, 24

Тревожный признак

Другая длина, русские буквы, фигурные скобки без необходимости

Круговое преобразование
Норма

GUID → ссылка → GUID даёт исходную строку

Тревожный признак

Полученная ссылка не равна исходной

Существование объекта
Норма

Запрос по ссылке возвращает строку

Тревожный признак

Пустой результат запроса — ссылка битая

Пустая ссылка
Норма

GUID из нулей обработан отдельной веткой логики

Тревожный признак

Нулевой GUID уходит в обмен как валидный

FAQ

Можно ли получить GUID объекта, не открывая транзакцию и не обращаясь к базе?

Да. Метод УникальныйИдентификатор() работает с самой ссылкой, которая уже находится в памяти, и не выполняет обращений к СУБД. Если у вас есть ссылка — например, из результата запроса или реквизита формы — GUID извлекается мгновенно и без блокировок.

Как получить GUID элемента, который ещё не записан в базу?

У нового объекта ссылка появляется только после записи, но её можно назначить заранее: создайте ссылку через Справочники.Имя.ПолучитьСсылку(Новый УникальныйИдентификатор) и установите её методом УстановитьСсылкуНового(). После этого GUID объекта известен до записи — так делают при двустороннем обмене.

Чем GUID отличается от навигационной ссылки?

Навигационная ссылка (вида e1cib/data/Справочник.Контрагенты?ref=...) — это строка для открытия объекта в клиенте 1С, она содержит GUID в закодированном виде. GUID — только сам идентификатор. Из навигационной ссылки GUID можно извлечь функцией ПолучитьСсылкуИзНавигационнойСсылки() с последующим вызовом УникальныйИдентификатор().

Почему GUID одинаковых объектов в разных базах отличается?

Потому что объекты создавались независимо: платформа генерирует новый идентификатор при создании каждого элемента. Чтобы GUID совпадали, нужно либо переносить объекты с сохранением ссылок (через УстановитьСсылкуНового или выгрузку/загрузку данных), либо вести таблицу соответствия идентификаторов между базами.

Можно ли изменить GUID существующего объекта?

Штатными средствами встроенного языка — нет, идентификатор неизменен. Обходной путь: создать новый объект с нужным GUID через УстановитьСсылкуНового(), перенести в него данные и заменить ссылки во всех связанных объектах, а старый удалить. Операция рискованная — выполняйте на копии базы и с резервной копией.

Работает ли УникальныйИдентификатор() на тонком клиенте?

Да, метод доступен на тонком и веб-клиенте без переноса кода на сервер. Это одно из его преимуществ перед ЗначениеВСтрокуВнутр(), которая на тонком клиенте недоступна и требует серверного вызова.

Итог

Что важно запомнить

GUID ссылки в 1С получают методом УникальныйИдентификатор() — он быстрый, доступен на клиенте и сервере и не обращается к базе. Обратное преобразование делается через Новый УникальныйИдентификатор() и ПолучитьСсылку() с обязательной проверкой существования объекта. Альтернативы (ЗначениеВСтрокуВнутр, XML) оставьте для специфических задач обмена, а пустые ссылки и нессылочные типы обрабатывайте отдельно.