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

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

Как выбрать GUID в запросе 1С

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

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

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

Ниже разобраны рабочие приёмы с примерами кода, ограничения каждого подхода и типичные ошибки, которые приводят к пустым выборкам и невозможности найти объект.

Что такое GUID ссылки и где он хранится

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

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

Как получить GUID из результата запроса

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

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

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

"ВЫБРАТЬ

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

|ИЗ

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

|ГДЕ

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

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

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

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

// Строковое представление: Строка(ГУИД)

КонецЦикла;

Метод УникальныйИдентификатор() доступен у любой ссылки и возвращает значение типа «УникальныйИдентификатор». Приведение его к строке даёт привычный формат с дефисами. Учитывайте, что обращение к методу для больших выборок выполняется быстро, так как GUID уже содержится в ссылке и не требует обращения к базе.

Как найти ссылку по известному GUID

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

ГУИД = Новый УникальныйИдентификатор("b3f4a2c1-1234-5678-9abc-def012345678");

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

Если СсылкаНаТовар.ПолучитьОбъект() = Неопределено Тогда

// Объект с таким GUID не найден (битая ссылка)

КонецЕсли;

Конструкция ПолучитьСсылку() всегда возвращает ссылку, даже если объекта с таким GUID в базе нет. Поэтому результат обязательно проверяют: либо через ПолучитьОбъект(), либо запросом с условием ГДЕ Ссылка = &Ссылка и проверкой пустоты выборки. Второй способ предпочтительнее при массовых проверках — он не вычитывает объект целиком.

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

Порядок поиска объекта по GUID
  1. 1
    Преобразуйте строку в тип УникальныйИдентификатор через Новый УникальныйИдентификатор(СтрокаГУИД)
  2. 2
    Вызовите ПолучитьСсылку(ГУИД) у менеджера нужного типа объекта
  3. 3
    Проверьте существование объекта запросом по ссылке или через ПолучитьОбъект()
  4. 4
    Если объект не найден — зафиксируйте это в журнале, не создавайте объект молча

Передача GUID в запрос параметром

Когда GUID приходит как строка (из HTTP-сервиса, файла обмена, COM-соединения), его нельзя напрямую сравнить со ссылкой в условии запроса — типы не совпадут. Правильный путь — сначала преобразовать строку в ссылку, а уже её передать параметром:

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

СсылкаНаДокумент = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(ГУИД);

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

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

"ВЫБРАТЬ

| Реализация.Номер,

| Реализация.Дата

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Ссылка = &Ссылка";

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

Такой запрос использует индекс по ссылке и выполняется быстро даже на больших таблицах. Передавать в параметр строку GUID и надеяться на неявное преобразование — ошибка: сравнение строки со ссылкой даст пустой результат без каких-либо сообщений.

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

Поиск «битых» ссылок через GUID

После удаления объектов без контроля ссылочной целостности или неудачного обмена в базе остаются ссылки на несуществующие объекты. Их GUID известен (он хранится в поле ссылки), но объекта нет. Найти такие записи можно запросом с левым соединением:

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

"ВЫБРАТЬ

| Заказ.Ссылка КАК Заказ,

| Заказ.Контрагент КАК КонтрагентСсылка

|ИЗ

| Документ.ЗаказПокупателя КАК Заказ

| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты

| ПО Заказ.Контрагент = Контрагенты.Ссылка

|ГДЕ

| Контрагенты.Ссылка ЕСТЬ NULL

| И НЕ Заказ.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)";

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

Внутреннее представление ссылки и ЗначениеВСтрокуВнутр

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

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

// Передача в другую базу или сохранение

ВосстановленнаяСсылка = ЗначениеИзСтрокиВнутр(СтрокаВнутр);

Этот способ сохраняет и GUID, и тип объекта, поэтому подходит, когда тип заранее неизвестен. Ограничения: формат внутренний, не предназначен для передачи в не-1С системы, и при восстановлении в другой базе объект с таким GUID должен существовать, иначе получите битую ссылку.

Сравнение способов работы с GUID

УникальныйИдентификатор() + ПолучитьСсылку()

Стандартный способ для интеграций и обмена. Требует знать тип объекта при обратном поиске.

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

Сохраняет тип и GUID, но формат пригоден только между базами 1С.

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

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

Производительность и ограничения

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

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

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

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

Выборка по ссылке из GUID
Норма

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

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

Пустая выборка — проверьте, что в параметр передана ссылка, а не строка

Строковое представление GUID
Норма

Формат вида xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

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

Вместо GUID выводится номер или наименование объекта — использовано Строка(Ссылка)

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

ПолучитьОбъект() вернул объект, реквизиты читаются

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

ПолучитьОбъект() вернул Неопределено — объект удалён или GUID из другой базы

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

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

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

Почему запрос с параметром-строкой GUID возвращает пустой результат?

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

Меняется ли GUID объекта при переносе в другую базу?

Нет, если перенос выполнен штатными средствами (обмен, выгрузка с сохранением ссылок). GUID специально спроектирован неизменным, чтобы сопоставлять объекты между базами. Новый GUID объект получит только при создании «с нуля», а не при переносе.

Как узнать GUID «битой» ссылки, если объект удалён?

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

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

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

Что быстрее: поиск по GUID или по коду/номеру?

Поиск по ссылке (то есть по GUID) обычно быстрее, поскольку ссылка — первичный ключ таблицы с кластерным индексом. Код и номер тоже индексированы, но не гарантируют уникальности в сложных настройках нумерации, поэтому для интеграций надёжнее GUID.

Итог

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

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