Разработка и Конфигурация · 11 мин
Как получить уникальный идентификатор в запросе 1С
Способы получить уникальный идентификатор ссылки в запросе 1С: функция УникальныйИдентификатор(), параметры, сравнение GUID и обход ограничений языка запросов.
Уникальный идентификатор (GUID) — это 128-битное значение, которое платформа 1С присваивает каждой ссылке на объект базы данных: элементу справочника, документу, узлу плана обмена и т.д. Разработчики часто сталкиваются с задачей получить GUID непосредственно в запросе — например, для обмена данными с внешними системами, отладки или сопоставления записей между базами.
Здесь кроется главная особенность: язык запросов 1С не имеет встроенной функции, которая возвращает GUID ссылки в виде строки. Метод УникальныйИдентификатор() существует только у объекта Ссылка в коде встроенного языка, но не в тексте запроса. Поэтому задача решается обходными путями: передачей GUID через параметр, сравнением ссылок напрямую или вычислением идентификатора после выполнения запроса.
Ниже разобраны все рабочие сценарии: как передать GUID в запрос, как отобрать запись по известному идентификатору, как получить GUID для каждой строки результата и как организовать сопоставление объектов между базами без изменения конфигурации.
Почему в запросе нельзя получить GUID напрямую
Язык запросов 1С работает с данными на уровне таблиц и полей. Ссылка в запросе — это значение составного типа, которое платформа умеет сравнивать, соединять и проверять на NULL, но не преобразовывать в строку с идентификатором. Конструкция вида ВЫБРАТЬ Товары.Ссылка.УникальныйИдентификатор() вызовет ошибку синтаксиса, потому что вызов методов объектов в запросе не поддерживается.
Это осознанное ограничение платформы. Запрос транслируется в SQL, а GUID в 1С хранится в служебном двоичном поле таблицы, доступ к которому из языка запросов закрыт. Попытки обойти это через прямые SQL-запросы к базе нарушают лицензионное соглашение и могут повредить данные, поэтому такой путь использовать нельзя.
Получение GUID после выполнения запроса
Самый распространённый сценарий: запрос возвращает ссылки, а GUID нужен для каждой из них — например, для выгрузки в CSV или передачи во внешний API. В этом случае идентификатор вычисляется в цикле обхода результата.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
GUID = Выборка.Ссылка.УникальныйИдентификатор();
// GUID — значение типа УникальныйИдентификатор
СтрокаGUID = Строка(GUID); // "a1b2c3d4-..."
КонецЦикла;
Метод УникальныйИдентификатор() не выполняет обращения к базе — идентификатор уже содержится внутри значения ссылки. Поэтому вызов в цикле безопасен с точки зрения производительности и не создаёт дополнительных запросов к СУБД, в отличие от обращений к реквизитам через точку.
Если результат нужен в виде таблицы «ссылка — GUID», создайте таблицу значений и заполните её в том же цикле. Для больших выборок используйте Выгрузить() вместо Выбрать() и обходите таблицу результата — это снижает число итераций клиент-серверного взаимодействия.
- 1Сформируйте запрос, выбирающий поле Ссылка нужного объекта
- 2Выполните запрос и получите выборку или таблицу результата
- 3В цикле для каждой строки вызовите Ссылка.УникальныйИдентификатор()
- 4Преобразуйте результат в строку через Строка() при необходимости выгрузки
- 5Проверьте на контрольном элементе, что GUID совпадает со значением в другой базе
Поиск объекта по известному GUID в запросе
Обратная задача встречается чаще: из внешней системы пришёл GUID в виде строки, и нужно найти соответствующий объект в базе. Здесь запрос тоже не может принять строку GUID напрямую — сначала строку преобразуют в ссылку.
Создание ссылки из строки GUID
Для этого используется конструктор Новый УникальныйИдентификатор(Строка) и метод менеджера объекта ПолучитьСсылку():
СтрокаGUID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
GUID = Новый УникальныйИдентификатор(СтрокаGUID);
ИскомаяСсылка = Справочники.Номенклатура.ПолучитьСсылку(GUID);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Наименование,
| Номенклатура.Код
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", ИскомаяСсылка);
Важно понимать: ПолучитьСсылку() не проверяет существование объекта. Если записи с таким GUID нет, запрос просто вернёт пустой результат — это и есть признак отсутствия объекта. Дополнительно проверить существование можно методом ПолучитьОбъект() с обработкой исключения или через ОбщегоНазначения.СсылкаСуществует() в типовых конфигурациях на БСП.
Конструкция ЗначениеВСтрокуВнутр
В отчётах на СКД и консолях запросов, где нет возможности написать код, GUID можно передать через внутреннее представление значения. Функция ЗначениеВСтрокуВнутр(Ссылка) возвращает строку, которую затем обрабатывает обратная функция ЗначениеИзСтрокиВнутр(). Это позволяет передавать ссылки между базами через текстовые файлы, но формат внутреннего представления платформа не гарантирует между версиями, поэтому для постоянных интеграций лучше использовать чистый GUID.
Сравнение и фильтрация по ссылкам внутри запроса
Если цель — не получить GUID как строку, а отобрать или соединить данные, GUID вообще не нужен. Запрос сравнивает ссылки напрямую, и это работает быстрее любых строковых операций, потому что сравнение идёт по индексированному служебному полю.
Типовые приёмы фильтрации по ссылкам:
ГДЕ Товары.Номенклатура = &Ссылка— точное совпадение;ГДЕ Товары.Номенклатура В (&СписокСсылок)— отбор по массиву или списку значений, переданному параметром;ГДЕ Товары.Номенклатура В ИЕРАРХИИ (&Группа)— отбор по группе с учётом вложенности;- соединение таблиц по равенству ссылок — например, табличной части документа со справочником.
Передавать в параметр нужно именно ссылку, а не строку GUID. Если в руках только строка — сначала преобразуйте её, как показано выше. Сравнение строки с полем ссылочного типа приведёт либо к ошибке, либо к пустому результату в зависимости от контекста.
Сопоставление объектов между базами по GUID
При интеграции двух баз 1С GUID используется как ключ сопоставления. Типовая схема: при выгрузке из базы-источника для каждого объекта сохраняется строка GUID, а база-приёмник хранит соответствие в регистре сведений или в дополнительном реквизите.
Если конфигурацию изменять нельзя, соответствие можно держать во внешнем файле (таблица CSV «GUID источника — GUID приёмника») или использовать штатные механизмы: планы обмена и универсальный формат EnterpriseData сохраняют GUID при переносе, поэтому после обмена идентификаторы объектов в базах совпадают.
При ручной синхронизации помните о коллизиях: если объект в приёмнике создаётся копированием, а не обменом, он получит новый GUID, и связь по идентификатору потеряется. В таком случае сопоставление ведут по кодам, наименованиям или ИНН — а GUID фиксируют уже после первичной привязки.
Проверка результата и производительность
После реализации любого из сценариев проверьте результат на контрольном примере. Возьмите один известный элемент, получите его GUID через Ссылка.УникальныйИдентификатор() в окне «Вычислить выражение» (Shift+F9 в конфигураторе при отладке) и сверьте со значением, которое вернул ваш код или пришло из внешней системы. Строки должны совпадать посимвольно, регистр букв значения не имеет.
С точки зрения производительности вызов УникальныйИдентификатор() практически бесплатен — это чтение данных из уже полученной ссылки. Узкие места возникают в другом: при серверном вызове на каждую итерацию цикла в клиент-серверном режиме и при сериализации больших таблиц. Поэтому весь обход результата выполняйте в одном серверном вызове, а результат возвращайте на клиент готовой структурой или таблицей.
Как проверить результат
Значения совпадают посимвольно
Разные строки — объект не тот или базы не синхронизированы
Возвращается ровно одна строка с нужным объектом
Пустой результат — объект с таким GUID отсутствует или строка преобразована неверно
Обработка идёт в одном серверном вызове без видимых пауз
Заметные задержки — вероятно, код выполняется на клиенте с обращениями к серверу в цикле
FAQ
Можно ли вывести GUID в отчёте СКД без программирования?
Напрямую — нет, поскольку язык запросов не возвращает GUID. Обходной вариант: добавить в конфигурацию вычисляемый реквизит с хранимой строкой идентификатора или использовать внешний источник данных. На практике чаще выводят код или наименование, а GUID получают программно там, где он действительно нужен для интеграции.
Чем УникальныйИдентификатор() отличается от ЗначениеВСтрокуВнутр()?
Первый возвращает стандартный GUID в формате «xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx», понятный любым внешним системам. Вторая функция возвращает внутреннее сериализованное представление значения 1С, которое понимает только платформа 1С и формат которого не гарантирован между версиями. Для интеграций используйте GUID.
Как найти объект по GUID, если неизвестен его тип?
По одному GUID тип объекта определить нельзя — идентификатор не содержит информации о таблице. Нужно либо знать тип заранее, либо перебирать менеджеры объектов (справочники, документы) и проверять существование ссылки в каждом. В типовых конфигурациях на БСП для этого есть служебные механизмы поиска по идентификатору.
Изменится ли GUID объекта после перезаписи или обмена?
При обычной перезаписи GUID не меняется — он присваивается один раз при создании объекта и хранится всё время его жизни. Новый идентификатор появится только если объект удалить и создать заново. При штатном обмене данными GUID сохраняется, поэтому в связанных базах один и тот же объект имеет одинаковый идентификатор.
Можно ли сгенерировать новый GUID в запросе для временной таблицы?
Нет, генерация идентификаторов в языке запросов не предусмотрена. Новый GUID создаётся в коде: Новый УникальныйИдентификатор без параметров. Если нужен уникальный ключ строки в выборке, используйте автоинкремент при заполнении таблицы значений или номер строки.
Безопасно ли вызывать УникальныйИдентификатор() в цикле на миллион записей?
Сам вызов безопасен — он не обращается к базе. Но обход миллиона строк в клиент-серверном режиме должен выполняться целиком на сервере в одном вызове, иначе сетевые задержки сделают операцию очень долгой. Также заранее оцените объём памяти под итоговую таблицу со строковыми GUID.
Что важно запомнить
GUID нельзя получить внутри текста запроса — его вычисляют методом Ссылка.УникальныйИдентификатор() при обходе результата. Для поиска по известному GUID строку преобразуют в ссылку через ПолучитьСсылку(Новый УникальныйИдентификатор(Строка)) и передают параметром. Для сравнения и соединений внутри запроса GUID не нужен — ссылки сравниваются напрямую.