Разработка и Конфигурация · 11 мин
Как получить GUID объекта в 1С в запросе
Как получить GUID (уникальный идентификатор) объекта в запросе 1С: функция УникальныйИдентификатор(), ссылка, XMLСтрока, решение через СКД и обходные приёмы.
Задача получить GUID (уникальный идентификатор) объекта прямо в тексте запроса 1С возникает регулярно: при обмене данными между базами, интеграции с внешними системами, выгрузке в веб-сервисы или при сопоставлении записей в разных информационных базах. Проблема в том, что язык запросов 1С не имеет встроенной функции, которая возвращала бы строковое представление GUID ссылки напрямую.
Тем не менее рабочие способы существуют. Часть из них опирается на неочевидные особенности платформы (например, поведение параметра запроса с типом «УникальныйИдентификатор»), часть — на постобработку результата запроса в коде, а часть — на хранение GUID в отдельном реквизите. Выбор зависит от того, где именно нужен идентификатор: в консоли запросов, в отчёте на СКД, в выгрузке или в коде модуля.
Ниже разобраны все основные приёмы с конкретными примерами кода, ограничениями каждого подхода и типичными ошибками, которые приводят к пустым значениям или некорректному сопоставлению данных.
Почему в запросе 1С нельзя просто выбрать GUID
Язык запросов 1С работает со ссылками как с единым типом данных «ссылка», не предоставляя доступа к её внутреннему представлению. Поля вида Ссылка в таблицах — это не строка и не составное значение, а специальный тип, для которого в запросе доступны только реквизиты объекта и предопределённые поля (Представление, ПометкаУдаления и т.д.).
Функция УникальныйИдентификатор() существует только во встроенном языке 1С (метод объекта «Ссылка»), но не в языке запросов. Поэтому конструкция ВЫБРАТЬ Товары.Ссылка.УникальныйИдентификатор() синтаксически невозможна — консоль запросов выдаст ошибку ещё на этапе проверки текста.
Это архитектурное ограничение, а не недоработка конкретной версии платформы: поведение одинаково на платформах 8.2 и 8.3. Поэтому все решения строятся вокруг обхода этого ограничения.
Способ 1: получить GUID в коде после выполнения запроса
Самый надёжный и универсальный вариант — выбрать в запросе ссылку, а GUID получать при обходе результата. Это работает в любой конфигурации и не зависит от настроек базы.
Пример кода:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ГУИД = Выборка.Ссылка.УникальныйИдентификатор();
Сообщить(Строка(ГУИД));
КонецЦикла;
Метод УникальныйИдентификатор() возвращает значение типа «УникальныйИдентификатор», которое приведением к строке превращается в привычный 36-символьный вид. Обратная операция — получение ссылки по GUID — выполняется через Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаГУИД)).
Если результат запроса большой (сотни тысяч строк), обход с вызовом метода для каждой ссылки работает быстро: GUID хранится вместе со ссылкой, обращения к СУБД не происходит. Этот приём безопасно использовать и в фоновых заданиях, и в обработчиках обмена.
Способ 2: приём с параметром типа «УникальныйИдентификатор»
Существует известный приём, позволяющий увидеть GUID прямо в консоли запросов. Он основан на том, что если параметру запроса присвоить значение типа «УникальныйИдентификатор», а затем сравнить его со ссылкой или использовать в конструкции, платформа в ряде режимов показывает строковое представление.
Более практичный вариант для консоли — использовать функцию встроенного языка через внешнюю обработку консоли запросов, которая поддерживает вычисление выражений. В типовой «Консоли запросов» из инструментов разработчика (ИР) или аналогичных обработках можно выбрать ссылку и рядом вычислить Выборка.Ссылка.УникальныйИдентификатор() как дополнительное поле постобработки.
Ещё один рабочий трюк для отладки — временно вывести GUID через запрос к таблице, где он уже хранится в строковом виде (например, в регистрах соответствия при настроенной синхронизации данных). Запрос к такой таблице вернёт GUID как обычную строку без дополнительных ухищрений.
Способ 3: хранить GUID в отдельном реквизите объекта
Если GUID нужен в запросах регулярно — например, для отчётов, выгрузок в Excel или интеграции по расписанию — рационально хранить его в явном виде. Для этого в объект добавляют строковый реквизит длиной 36 (или 50 с запасом) и заполняют его при записи.
Типовой код подписки на событие «ПриЗаписи» или обработчика в модуле объекта:
Если ПустаяСтрока(ГУИДСтрокой) Тогда
ГУИДСтрокой = Строка(Ссылка.УникальныйИдентификатор());
КонецЕсли;
После этого GUID доступен в любом запросе как обычное поле: ВЫБРАТЬ Номенклатура.ГУИДСтрокой ИЗ Справочник.Номенклатура. Это единственный способ получить GUID непосредственно текстом запроса без постобработки — и потому единственный вариант для СКД-отчётов, где результат уходит пользователю без программной обработки.
У подхода есть цена: нужно заполнить реквизит для уже существующих объектов (разовой обработкой), контролировать заполнение при всех способах создания объекта, включая обмены и загрузки, и помнить, что при переносе объекта между базами с сохранением ссылки GUID совпадёт, а при создании новой ссылки — изменится.
Сравнение способов получения GUID
Универсально и надёжно; не требует изменения конфигурации. Не подходит для чистых СКД-отчётов без кода.
GUID доступен прямо в запросе и в СКД. Требует доработки конфигурации, заполнения старых данных и контроля целостности.
GUID уже лежит в базе в строковом виде. Работает только там, где настроен обмен через универсальный формат или планы обмена.
Способ 4: GUID в СКД и динамических списках
В схеме компоновки данных вычисляемые поля ограничены языком выражений СКД, где метода УникальныйИдентификатор() тоже нет. Поэтому для отчёта на СКД, который должен показать GUID, вариантов фактически два.
Первый — использовать строковый реквизит с GUID (способ 3) и просто добавить его в набор данных. Это самое чистое решение, если доработка конфигурации допустима.
Второй — программная компоновка: выполнить запрос, обойти результат, заполнить таблицу значений с колонкой «GUID» и передать её в СКД как внешний набор данных через КомпоновщикМакета и объект ВнешниеНаборыДанных. Такой подход не требует изменения метаданных, но усложняет модуль отчёта.
Для динамических списков аналогично: произвольный запрос динамического списка не выведет GUID без реквизита, поэтому либо добавляется реквизит, либо список формируется программно.
- 1Определите, допустима ли доработка конфигурации (своя или типовая на поддержке)
- 2Если доработка допустима — добавьте строковый реквизит GUID и заполните его подпиской на запись
- 3Выполните разовую обработку заполнения GUID для существующих объектов
- 4Если доработка недопустима — реализуйте отчёт с внешним набором данных и заполнением GUID в коде
- 5Проверьте отчёт на объектах, созданных через обмен: GUID должен быть заполнен и там
Проверка результата и типичные ошибки
После реализации любого из способов результат стоит проверить на контрольных примерах. Берёте несколько объектов разных видов (справочник, документ), получаете их GUID выбранным способом и сверяете с тем, что показывает, например, команда «Вывести список» с колонкой ссылки или получение GUID через отладчик.
Как проверить результат
36 символов, формат 8-4-4-4-12 с дефисами
32 символа без дефисов или пустая строка — значение получено некорректно или реквизит не заполнен
ПолучитьСсылку(Новый УникальныйИдентификатор(GUID)) возвращает тот же объект
Возвращается битая ссылка или другой объект — GUID не соответствует ссылке
У всех объектов, включая загруженные, реквизит GUID заполнен
У части объектов реквизит пуст — подписка не сработала при загрузке
Отдельный класс проблем — битые ссылки. У объекта вида «<Объект не найден>» метод УникальныйИдентификатор() вернёт GUID, но обратное получение ссылки даст несуществующий объект. При выгрузках для интеграции такие значения стоит фильтровать проверкой ссылки на существование.
Ограничения и риски при работе с GUID
GUID гарантированно уникален только в пределах одной базы и связанных с ней через обмен баз, где объекты переносятся с сохранением ссылки. Если один и тот же по смыслу объект создавался независимо в двух базах, его GUID будут разными — сопоставлять такие данные по GUID нельзя, нужны регистры соответствия или поиск по ключевым полям.
При доработке конфигурации реквизитом GUID помните о рисках: изменение типовых объектов усложняет обновление, а массовая разовая обработка заполнения реквизита на большой базе может занять заметное время и создать нагрузку — выполняйте её в нерабочие часы и порциями. Перед любыми доработками сделайте резервную копию базы.
Частые вопросы
Можно ли получить GUID документа так же, как справочника?
Да, метод УникальныйИдентификатор() есть у ссылки любого объектного типа: документы, справочники, планы счетов, задачи и т.д. Все описанные способы работают одинаково для любых ссылочных типов.
Как по строке GUID найти объект в базе?
Через метод менеджера объекта: Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)). Если вид объекта заранее неизвестен, GUID можно сопоставить через перебор менеджеров типов или через XMLТипСсылки.
Совпадёт ли GUID объекта после выгрузки и загрузки через XML?
Если загрузка выполняется с сохранением ссылки (обработки выгрузки/загрузки XML, планы обмена), GUID сохраняется. Если объект создаётся заново как новый, платформа назначит новый GUID.
Почему в консоли запросов нельзя вывести GUID одной колонкой?
Язык запросов не имеет функции преобразования ссылки в GUID — это ограничение платформы. Консоли с расширенными возможностями (например, инструменты разработчика) вычисляют GUID на этапе постобработки результата, а не в самом запросе.
Нужно ли индексировать строковый реквизит с GUID?
Если по реквизиту выполняется поиск или соединение в запросах — да, добавьте его в индексы, иначе на больших таблицах запросы будут выполняться полным сканированием. Для редких выгрузок индекс не обязателен.
Чем GUID отличается от предопределённого имени и кода?
Код и наименование — пользовательские данные, которые могут меняться и дублироваться. GUID назначается платформой, не меняется в течение жизни объекта и уникален в базе, поэтому именно он используется для однозначной идентификации при обменах.
Что важно запомнить
Прямой функции получения GUID в языке запросов 1С нет. В коде используйте Ссылка.УникальныйИдентификатор() при обходе результата; для отчётов и СКД добавляйте строковый реквизит с GUID или внешний набор данных. Контролируйте заполнение реквизита при обменах, фильтруйте битые ссылки и приводите строковый формат GUID к единому виду во всех системах.