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

Разработка и Конфигурация · 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. 1
    Получите список строк ГУИД из внешнего источника и проверьте формат (36 символов, дефисы)
  2. 2
    Преобразуйте каждую строку в УникальныйИдентификатор, перехватывая исключения на некорректных значениях
  3. 3
    Сформируйте массив ссылок через ПолучитьСсылку() для нужного вида объекта
  4. 4
    Выполните запрос с условием В (&МассивСсылок)
  5. 5
    Сравните результат со входным списком и зафиксируйте ненайденные ГУИД

Перестановка байтов и представление ГУИД в СУБД

Разработчики, которые выгружают ГУИД через SQL, часто сталкиваются с тем, что строка из запроса не совпадает со строкой в 1С. Причина — порядок байтов: платформа хранит идентификатор в поле binary(16) с переставленными группами байтов относительно стандартного текстового представления UUID.

Практический вывод: нельзя просто применить к полю ссылки стандартное преобразование SQL в строку UUID и ожидать совпадения с тем, что показывает 1С. Группы байтов нужно переставить по определённой схеме, иначе поиск по такому «ГУИД» из 1С ничего не найдёт. Точная схема перестановки зависит от версии платформы и СУБД, поэтому перед использованием проверяйте соответствие на нескольких заведомо известных объектах: сравните строку из УникальныйИдентификатор() с результатом SQL-преобразования.

Из-за этой хрупкости прямую работу с СУБД стоит рассматривать только как инструмент разового анализа, а не как элемент продуктивной интеграции. Для постоянных обменов надёжнее передавать ГУИД из 1С в строковом виде через штатные механизмы.

Типичные ошибки и как их избежать

Первая и самая частая ошибка — попытка сравнить ссылку со строкой ГУИД прямо в запросе: ГДЕ Т.Ссылка = &ГУИДСтрокой. Запрос либо вернёт пустой результат, либо завершится ошибкой несовместимости типов. Строку всегда нужно сначала превращать в УникальныйИдентификатор, а затем в ссылку.

Вторая ошибка — доверие к данным извне без валидации. Конструктор Новый УникальныйИдентификатор(Строка) выбрасывает исключение на некорректной строке. Если ГУИД приходит от пользователя или внешней системы, оборачивайте преобразование в попытку/исключение, иначе один битый идентификатор оборвёт всю обработку.

Третья группа ошибок связана с регистром и форматом: лишние пробелы, фигурные скобки вокруг ГУИД (так его иногда отдают внешние системы), верхний регистр. Перед преобразованием нормализуйте строку: уберите пробелы и скобки. Регистр символов для конструктора не критичен, но чистый формат исключает сюрпризы.

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

Проверка результата и контрольные точки

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

Полезно также проверить граничные случаи: несуществующий ГУИД (должен корректно обрабатываться как «не найдено»), ГУИД объекта другого типа (не должен находиться в чужой таблице), строку в верхнем регистре и строку с фигурными скобками. Эти проверки занимают несколько минут, но отсекают большинство инцидентов на старте эксплуатации.

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

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

Обратный поиск контрольного объекта
Норма

Объект найден, ссылка совпадает с исходной

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

Пустой результат или найден другой объект — проверяйте тип и формат строки

Строка ГУИД на стороне приёмника
Норма

36 символов, дефисы, без скобок и пробелов

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

Лишние символы, обрезанная строка, иной порядок групп

Обработка несуществующего ГУИД
Норма

Фиксируется как «не найдено», обработка продолжается

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

Ошибка, прерывание обработки или создание объекта-призрака

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

Можно ли в запросе 1С написать функцию, возвращающую ГУИД ссылки?

Нет, в языке запросов такой встроенной функции не существует. Варианты обхода: получать ГУИД в цикле по выборке через УникальныйИдентификатор(), хранить ГУИД в отдельном строковом реквизите объекта либо читать поле ссылки напрямую из СУБД с учётом перестановки байтов.

Почему ПолучитьСсылку() вернула значение, а объекта в базе нет?

Метод ПолучитьСсылку() не обращается к базе для проверки — он просто конструирует ссылку с указанным ГУИД. Существование объекта нужно проверять отдельным запросом по этой ссылке. Если запрос пуст, объект с таким идентификатором в данной таблице отсутствует.

Совпадает ли ГУИД объекта в разных базах после выгрузки?

Зависит от способа переноса. При обменах, настроенных на сопоставление по уникальному идентификатору (типовые планы обмена, конвертация с сохранением ГУИД), идентификатор сохраняется. Если объект создаётся в приёмнике заново без передачи ГУИД, ему будет назначен новый идентификатор.

Как передать ГУИД в запрос, если их несколько тысяч?

Преобразуйте строки в массив ссылок и передайте его параметром с условием В (&МассивСсылок). При очень больших объёмах эффективнее поместить ссылки во временную таблицу через менеджер временных таблиц и соединиться с ней в основном запросе.

Чем ГУИД отличается от кода справочника или номера документа?

Код и номер — прикладные реквизиты, которые могут меняться, дублироваться при определённых настройках и зависят от периодичности нумерации. ГУИД назначается платформой один раз при создании объекта, не меняется и уникален в пределах таблицы, поэтому именно он используется для надёжной идентификации при интеграциях.

Безопасно ли получать ГУИД прямым SQL-запросом?

Для чтения в аналитических целях — приемлемо, но с оговорками: нужно учитывать перестановку байтов, такой доступ не поддерживается вендором, а структура хранения может измениться. Для продуктивных интеграций используйте штатные механизмы 1С. Прямая запись в таблицы СУБД недопустима ни при каких условиях.

Итог

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

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