Разработка и Конфигурация · 14 мин
Ссылка как ГУИД в 1С: как получить и использовать уникальный идентификатор в запросах
Как в запросе 1С получить ГУИД из ссылки, найти объект по уникальному идентификатору, сравнить ссылки и избежать типичных ошибок при работе с UUID.
Уникальный идентификатор (ГУИД, UUID) — это внутренний 36-символьный ключ, который платформа 1С присваивает каждому объекту базы: элементу справочника, документу, записи плана видов характеристик. По нему можно однозначно найти объект даже после изменения кода, номера или наименования. Проблема в том, что в языке запросов 1С нет прямой функции, возвращающей ГУИД ссылки, — и это регулярно ставит в тупик разработчиков, особенно при интеграциях.
Задача «ссылка как ГУИД» возникает в трёх типовых сценариях: нужно выгрузить идентификаторы во внешнюю систему (сайт, CRM, REST-сервис), нужно найти объект по строке ГУИД, полученной извне, или нужно сравнить ссылки между двумя базами. Для каждого сценария есть рабочий приём: часть решается средствами встроенного языка, часть — через СУБД или хитрости с XML-представлением значения.
Ниже разобраны все практические способы: от штатных методов ПолучитьСсылку() и УникальныйИдентификатор() до получения ГУИД прямо в тексте запроса без обхода выборки. Отдельно рассмотрены ограничения, подводные камни с перестановкой байтов и типичные ошибки, из-за которых объект «не находится», хотя существует.
Что такое ГУИД ссылки и чем он отличается от самой ссылки
Ссылка в 1С — это типизированное значение, которое хранит не только идентификатор, но и тип объекта (какой это справочник или документ). ГУИД — лишь 128-битное число в строковом виде вида 8d4f1a2b-3c5e-4f6a-9b8c-7d0e1f2a3b4c. Один и тот же ГУИД в разных таблицах теоретически может встретиться, поэтому поиск объекта по ГУИД всегда выполняется в контексте конкретного типа.
Важное следствие: одна строка ГУИД без указания таблицы не даёт однозначного ответа, что это за объект. При интеграциях вместе с идентификатором всегда передавайте тип сущности (или используйте составной ключ «тип + ГУИД»), иначе внешняя система не сможет корректно адресовать объект.
Как получить ГУИД из ссылки во встроенном языке
Штатный способ — метод УникальныйИдентификатор(), доступный у любой ссылки на объект базы данных (справочник, документ, план счетов и т.д.). Результат — значение типа УникальныйИдентификатор, которое при приведении к строке даёт привычный вид с дефисами.
Типовой фрагмент кода выглядит так:
// Получаем ссылку любым способом
СсылкаНаТовар = Справочники.Номенклатура.НайтиПоКоду("000000123");
// Извлекаем ГУИД
ГУИД = СсылкаНаТовар.УникальныйИдентификатор();
// Строковое представление для передачи наружу
СтрокаГУИД = Строка(ГУИД); // "8d4f1a2b-3c5e-4f6a-9b8c-7d0e1f2a3b4c"
Если ссылки у вас ещё нет, а есть только объект (например, внутри обработчика перед записью), метод тот же: Объект.Ссылка.УникальныйИдентификатор(). Для нового, ещё не записанного объекта ссылка уже существует — платформа назначает её при создании, поэтому ГУИД доступен до первой записи в базу.
При массовой выгрузке не вызывайте этот метод в цикле через точку от выборки запроса, если выборка возвращает сами ссылки — это нормально. А вот обращение к реквизитам объекта через ссылку (например, Выборка.Ссылка.Наименование) порождает отдельные запросы к базе и резко замедляет выгрузку. Реквизиты выбирайте в тексте запроса, а ГУИД получайте из уже выбранной ссылки.
Как найти объект по строке ГУИД
Обратная задача решается методом менеджера ПолучитьСсылку(), которому передаётся значение типа УникальныйИдентификатор, сконструированное из строки:
СтрокаГУИД = "8d4f1a2b-3c5e-4f6a-9b8c-7d0e1f2a3b4c";
ГУИД = Новый УникальныйИдентификатор(СтрокаГУИД);
СсылкаНаТовар = Справочники.Номенклатура.ПолучитьСсылку(ГУИД);
// Проверяем, существует ли объект реально
Запрос = Новый Запрос(
"ВЫБРАТЬ Т.Ссылка ИЗ Справочник.Номенклатура КАК Т ГДЕ Т.Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", СсылкаНаТовар);
Если Запрос.Выполнить().Пустой() Тогда
// Объект с таким ГУИД отсутствует в базе
КонецЕсли;
Критически важный момент: ПолучитьСсылку() не проверяет существование объекта. Она просто конструирует ссылку с заданным ГУИД. Если объекта нет, вы получите «битую» ссылку, обращение к реквизитам которой вызовет ошибку. Поэтому после получения ссылки всегда проверяйте её существование запросом, как показано выше, либо через проверку на пустое представление с осторожностью.
Если тип объекта заранее неизвестен (внешняя система прислала только ГУИД), придётся перебирать менеджеры нужных видов объектов и проверять каждый. Для ускорения такого поиска ограничивайте список проверяемых таблиц — полный перебор всех справочников и документов конфигурации на большой базе ощутимо нагружает сервер.
Можно ли получить ГУИД прямо в тексте запроса
Короткий ответ — штатной функции языка запросов для этого нет. Операторы ВЫРАЗИТЬ, ПРЕДСТАВЛЕНИЕ и другие не возвращают ГУИД: ПРЕДСТАВЛЕНИЕ(Ссылка) даёт человекочитаемое представление (наименование или номер), а не идентификатор.
Есть три обходных пути, каждый со своими ограничениями:
- Два прохода. Запрос выбирает ссылки, затем в цикле по выборке для каждой ссылки вызывается
УникальныйИдентификатор(). Самый надёжный и переносимый способ — рекомендуется в большинстве случаев. - Запрос к СУБД напрямую. В MS SQL Server поле ссылки хранится как binary(16), и его можно преобразовать в строку ГУИД с учётом перестановки байтов, свойственной 1С. Способ завязан на конкретную СУБД, нарушает лицензионные ограничения на прямой доступ к данным и ломается при смене структуры хранения — применять только для разовых аналитических задач.
- Хранение ГУИД в отдельном реквизите. При записи объекта (в подписке на событие) в строковый реквизит сохраняется
Строка(Ссылка.УникальныйИдентификатор()). Тогда ГУИД доступен в любом запросе как обычное поле. Цена — дополнительное поле и необходимость заполнить его для существующих объектов.
Для интеграций, где ГУИД нужен регулярно и в запросах, третий вариант с отдельным реквизитом — самый производительный. Для разовых выгрузок достаточно первого.
Способы получить ГУИД
Универсально, работает на любой СУБД, не требует изменения конфигурации. Минус — нельзя отфильтровать или сгруппировать по ГУИД в самом запросе.
ГУИД доступен в запросах, отборах и СКД как обычное поле. Требует доработки конфигурации и заполнения исторических данных.
Быстро для аналитики, но зависит от СУБД, требует учёта перестановки байтов и не поддерживается вендором.
Поиск по ГУИД в запросе через параметр
Частая задача — отобрать в запросе объекты по списку ГУИД, присланных извне. Поскольку запрос не умеет сравнивать ссылку со строкой ГУИД напрямую, строки сначала преобразуются в ссылки в коде, а затем передаются в запрос параметром-массивом:
МассивСсылок = Новый Массив;
Для Каждого СтрокаГУИД Из СписокГУИД Цикл
ГУИД = Новый УникальныйИдентификатор(СтрокаГУИД);
МассивСсылок.Добавить(Справочники.Номенклатура.ПолучитьСсылку(ГУИД));
КонецЦикла;
Запрос = Новый Запрос(
"ВЫБРАТЬ Т.Ссылка, Т.Наименование
|ИЗ Справочник.Номенклатура КАК Т
|ГДЕ Т.Ссылка В (&МассивСсылок)");
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
Результат = Запрос.Выполнить().Выгрузить();
Такой подход заодно решает проблему «битых» идентификаторов: в результат запроса попадут только реально существующие объекты. Сопоставив входной список ГУИД с выборкой, легко вычислить, какие идентификаторы не нашлись, и залогировать их для разбора.
Если входных ГУИД очень много (десятки тысяч), массив в параметре может работать медленно. В этом случае загрузите идентификаторы во временную таблицу через пакетный запрос или используйте менеджер временных таблиц — это заметно эффективнее на больших объёмах.
- 1Получите список строк ГУИД из внешнего источника и проверьте формат (36 символов, дефисы)
- 2Преобразуйте каждую строку в УникальныйИдентификатор, перехватывая исключения на некорректных значениях
- 3Сформируйте массив ссылок через ПолучитьСсылку() для нужного вида объекта
- 4Выполните запрос с условием В (&МассивСсылок)
- 5Сравните результат со входным списком и зафиксируйте ненайденные ГУИД
Перестановка байтов и представление ГУИД в СУБД
Разработчики, которые выгружают ГУИД через SQL, часто сталкиваются с тем, что строка из запроса не совпадает со строкой в 1С. Причина — порядок байтов: платформа хранит идентификатор в поле binary(16) с переставленными группами байтов относительно стандартного текстового представления UUID.
Практический вывод: нельзя просто применить к полю ссылки стандартное преобразование SQL в строку UUID и ожидать совпадения с тем, что показывает 1С. Группы байтов нужно переставить по определённой схеме, иначе поиск по такому «ГУИД» из 1С ничего не найдёт. Точная схема перестановки зависит от версии платформы и СУБД, поэтому перед использованием проверяйте соответствие на нескольких заведомо известных объектах: сравните строку из УникальныйИдентификатор() с результатом SQL-преобразования.
Из-за этой хрупкости прямую работу с СУБД стоит рассматривать только как инструмент разового анализа, а не как элемент продуктивной интеграции. Для постоянных обменов надёжнее передавать ГУИД из 1С в строковом виде через штатные механизмы.
Типичные ошибки и как их избежать
Первая и самая частая ошибка — попытка сравнить ссылку со строкой ГУИД прямо в запросе: ГДЕ Т.Ссылка = &ГУИДСтрокой. Запрос либо вернёт пустой результат, либо завершится ошибкой несовместимости типов. Строку всегда нужно сначала превращать в УникальныйИдентификатор, а затем в ссылку.
Вторая ошибка — доверие к данным извне без валидации. Конструктор Новый УникальныйИдентификатор(Строка) выбрасывает исключение на некорректной строке. Если ГУИД приходит от пользователя или внешней системы, оборачивайте преобразование в попытку/исключение, иначе один битый идентификатор оборвёт всю обработку.
Третья группа ошибок связана с регистром и форматом: лишние пробелы, фигурные скобки вокруг ГУИД (так его иногда отдают внешние системы), верхний регистр. Перед преобразованием нормализуйте строку: уберите пробелы и скобки. Регистр символов для конструктора не критичен, но чистый формат исключает сюрпризы.
Проверка результата и контрольные точки
После реализации обмена по ГУИД проверьте цепочку целиком на контрольном примере. Возьмите конкретный объект, получите его ГУИД через УникальныйИдентификатор(), передайте строку через ваш канал интеграции и выполните обратный поиск. Объект должен найтись, и найденная ссылка должна совпадать с исходной — сравнение ссылок оператором равенства в 1С работает корректно.
Полезно также проверить граничные случаи: несуществующий ГУИД (должен корректно обрабатываться как «не найдено»), ГУИД объекта другого типа (не должен находиться в чужой таблице), строку в верхнем регистре и строку с фигурными скобками. Эти проверки занимают несколько минут, но отсекают большинство инцидентов на старте эксплуатации.
Как проверить результат
Объект найден, ссылка совпадает с исходной
Пустой результат или найден другой объект — проверяйте тип и формат строки
36 символов, дефисы, без скобок и пробелов
Лишние символы, обрезанная строка, иной порядок групп
Фиксируется как «не найдено», обработка продолжается
Ошибка, прерывание обработки или создание объекта-призрака
Частые вопросы
Можно ли в запросе 1С написать функцию, возвращающую ГУИД ссылки?
Нет, в языке запросов такой встроенной функции не существует. Варианты обхода: получать ГУИД в цикле по выборке через УникальныйИдентификатор(), хранить ГУИД в отдельном строковом реквизите объекта либо читать поле ссылки напрямую из СУБД с учётом перестановки байтов.
Почему ПолучитьСсылку() вернула значение, а объекта в базе нет?
Метод ПолучитьСсылку() не обращается к базе для проверки — он просто конструирует ссылку с указанным ГУИД. Существование объекта нужно проверять отдельным запросом по этой ссылке. Если запрос пуст, объект с таким идентификатором в данной таблице отсутствует.
Совпадает ли ГУИД объекта в разных базах после выгрузки?
Зависит от способа переноса. При обменах, настроенных на сопоставление по уникальному идентификатору (типовые планы обмена, конвертация с сохранением ГУИД), идентификатор сохраняется. Если объект создаётся в приёмнике заново без передачи ГУИД, ему будет назначен новый идентификатор.
Как передать ГУИД в запрос, если их несколько тысяч?
Преобразуйте строки в массив ссылок и передайте его параметром с условием В (&МассивСсылок). При очень больших объёмах эффективнее поместить ссылки во временную таблицу через менеджер временных таблиц и соединиться с ней в основном запросе.
Чем ГУИД отличается от кода справочника или номера документа?
Код и номер — прикладные реквизиты, которые могут меняться, дублироваться при определённых настройках и зависят от периодичности нумерации. ГУИД назначается платформой один раз при создании объекта, не меняется и уникален в пределах таблицы, поэтому именно он используется для надёжной идентификации при интеграциях.
Безопасно ли получать ГУИД прямым SQL-запросом?
Для чтения в аналитических целях — приемлемо, но с оговорками: нужно учитывать перестановку байтов, такой доступ не поддерживается вендором, а структура хранения может измениться. Для продуктивных интеграций используйте штатные механизмы 1С. Прямая запись в таблицы СУБД недопустима ни при каких условиях.
Что важно запомнить
Прямой функции «ссылка как ГУИД» в языке запросов 1С нет: идентификатор получают методом УникальныйИдентификатор() во встроенном языке, а обратный поиск выполняют через ПолучитьСсылку() с обязательной проверкой существования объекта. Для регулярных интеграций удобно хранить ГУИД в отдельном реквизите, а прямой доступ к СУБД оставить для разового анализа с учётом перестановки байтов.