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

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

Как в запросе получить уникальный идентификатор в 1С 8.3

Как получить уникальный идентификатор ссылки в запросе 1С 8.3: функция УникальныйИдентификатор, значение в запросе, обратное преобразование, типичные ошибки.

Уникальный идентификатор (GUID) — внутренний идентификатор ссылки в 1С, строка из 36 символов вида «8b3f7c2e-1a4d-11e7-9f2a-00155d0a1b02». Он нужен при обмене данными между базами, при интеграции с внешними системами и при поиске «потерянных» объектов. Проблема в том, что в языке запросов 1С нет прямой функции, возвращающей GUID ссылки: конструкция Ссылка.УникальныйИдентификатор() в тексте запроса недоступна и вызовет ошибку.

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

Почему GUID нельзя получить прямо в тексте запроса

Язык запросов 1С работает на уровне СУБД и оперирует полями таблиц, а не объектами встроенного языка. Метод УникальныйИдентификатор() принадлежит объектному уровню — он вызывается у значения типа «ссылка» уже после того, как платформа материализовала результат. Поэтому конструкция вида ВЫБРАТЬ Товары.Ссылка.УникальныйИдентификатор() синтаксически невозможна: запрос просто не скомпилируется.

Также нельзя вывести GUID через функцию ПРЕДСТАВЛЕНИЕ() — она вернёт наименование или другое представление объекта, а не идентификатор. Внутреннее двоичное представление ссылки в таблице СУБД тоже не предназначено для чтения запросом и зависит от формата хранения, поэтому любые «хаки» с прямым обращением к служебным полям нестабильны и не поддерживаются платформой.

Из этого следует главное правило: запрос возвращает ссылку, а GUID извлекается на уровне встроенного языка — либо в цикле обхода выборки, либо через СКД с вычисляемым полем, либо GUID передаётся в запрос извне как параметр.

Способ 1: получение GUID при обходе результата запроса

Самый распространённый сценарий: запрос выбирает ссылки, а GUID вычисляется в цикле. Это быстро, потому что ссылка уже получена запросом, и метод УникальныйИдентификатор() не выполняет дополнительных обращений к базе.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Наименование КАК Наименование

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| НЕ Номенклатура.ПометкаУдаления";

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

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

GUID = XMLСтрока(Выборка.Ссылка);

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

КонецЦикла;

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

Если результат нужно выгрузить в таблицу значений с колонкой GUID, заполните её постобработкой: добавьте колонку типа «Строка(36)» и заполните в цикле обхода. Это честнее и прозрачнее, чем попытки «вытащить» идентификатор внутри запроса.

Способ 2: передать GUID в запрос параметром (поиск ссылки по GUID)

Обратная задача встречается чаще: из внешней системы пришёл GUID, и нужно найти объект. Здесь запрос используется как раз напрямую — сначала GUID преобразуется в ссылку, затем ссылка передаётся параметром.

СтрокаGUID = "8b3f7c2e-1a4d-11e7-9f2a-00155d0a1b02";

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

СсылкаНаТовар = Справочники.Номенклатура.ПолучитьСсылку(НовыйGUID);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Наименование КАК Наименование

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Ссылка = &Ссылка";

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

Результат = Запрос.Выполнить();

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

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

Способ 3: GUID в отчёте на СКД через вычисляемое поле

Если GUID нужно показать пользователю в отчёте, используют вычисляемое поле СКД с выражением на встроенном языке. В настройках набора данных добавьте вычисляемое поле, например «GUID», и в выражении укажите вызов функции из общего модуля:

// В общем серверном модуле с флагом "Вызов сервера"

Функция GUIDСсылки(Ссылка) Экспорт

Возврат XMLСтрока(Ссылка);

КонецФункции

// Выражение вычисляемого поля СКД:

// ОбщийМодуль.GUIDСсылки(Ссылка)

Модуль должен быть серверным и с разрешённым вызовом сервера, иначе выражение не скомпилируется. Учтите, что вычисляемые поля с вызовом функций замедляют формирование больших отчётов — функция вызывается для каждой строки результата.

Сравнение способов и выбор подходящего

Сравнение вариантов

Обход выборки + XMLСтрока()

Универсальный и самый быстрый способ получить GUID для списка объектов. Подходит для выгрузок и обменов. Ограничение: GUID доступен только в коде, не в тексте запроса.

Параметр запроса со ссылкой из GUID

Единственный корректный путь, когда нужен отбор по известному GUID. Требует знать тип объекта заранее.

Вычисляемое поле СКД

Подходит для отчётов, где GUID должен видеть пользователь. Минус — вызов функции на каждую строку и требования к общему модулю.

Выбор определяется направлением задачи. Если GUID нужно получить — работайте после запроса. Если по GUID нужно найти объект — преобразуйте GUID в ссылку до запроса и передайте параметром. Если объект неизвестного типа, переберите менеджеры нужных видов объектов или используйте XMLЗначение() совместно с типом, переданным из внешней системы.

Частые ошибки при работе с GUID в запросах

Типичные ошибки
01
Попытка написать Ссылка.УникальныйИдентификатор() в тексте запроса — ошибка компиляции, метод недоступен в языке запросов.
02
Сравнение ссылки со строкой GUID в условии ГДЕ — типы несовместимы, отбор ничего не вернёт или выдаст ошибку.
03
Использование ПРЕДСТАВЛЕНИЕ(Ссылка) вместо GUID — возвращается наименование объекта, а не идентификатор.
04
Отсутствие проверки существования объекта после ПолучитьСсылку() — несуществующая ссылка выглядит как валидная и приводит к битым ссылкам в данных.
05
Передача GUID между базами с разным форматом строки (с фигурными скобками, в верхнем регистре) — перед сравнением приводите строку к единому виду.

Отдельно отметим несуществующие («битые») ссылки. Если в поле запроса оказалась ссылка на удалённый объект, УникальныйИдентификатор() у неё вызвать можно, но любое обращение к реквизитам через точку в запросе даст NULL. Для диагностики таких случаев проверяйте поля на ЕСТЬ NULL и отдельно обрабатывайте эти строки.

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

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

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

Формат полученного GUID
Норма

Строка из 36 символов: 8-4-4-4-12 шестнадцатеричных знаков через дефисы

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

Наименование объекта, пустая строка или значение вида «Объект не найден»

Поиск ссылки по GUID
Норма

Запрос вернул ровно одну строку с нужным объектом

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

Пустой результат — объекта нет, либо GUID от другого типа объекта

Обратное преобразование
Норма

XMLЗначение/ПолучитьСсылку дают ссылку, у которой ПолучитьОбъект() не равен Неопределено

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

ПолучитьОбъект() вернул Неопределено — объект физически отсутствует

Быстрая ручная проверка в консоли кода: выполните Сообщить(XMLСтрока(Ссылка)) для известного объекта и сравните со значением, которое возвращает ваша процедура. Значения должны совпадать посимвольно, регистр букв при этом не влияет на корректность преобразования обратно.

Итог

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

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

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

Можно ли отфильтровать запрос по части GUID, например по первым символам?

Нет. Ссылка в запросе — не строка, к ней неприменимы строковые функции и оператор ПОДОБНО. Отбор возможен только по полному равенству ссылки, которую предварительно получают из GUID.

Чем XMLСтрока(Ссылка) отличается от Строка(Ссылка.УникальныйИдентификатор())?

Результат идентичен — строковое представление GUID. XMLСтрока удобнее в универсальном коде, так как работает с любой ссылкой единообразно и используется в механизмах сериализации платформы.

Как найти объект по GUID, если неизвестен его тип?

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

Сохраняется ли GUID объекта при обмене между базами?

Да, при штатных обменах (план обмена, универсальный формат) GUID переносится вместе с объектом и остаётся одинаковым в обеих базах. Именно поэтому GUID — основной ключ сопоставления при интеграциях.

Почему запрос с условием Ссылка = &GUID, где параметр — строка, ничего не возвращает?

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

Можно ли получить GUID в консоли запросов без написания кода?

Нет, консоль запросов работает только языком запросов, где GUID недоступен. Используйте консоль кода: выберите ссылку запросом и выведите XMLСтрока(Ссылка) в цикле обхода.