Вопрос получения уникального идентификатора (GUID) напрямую в языке запросов 1С является «вечнозеленой» темой для разработчиков. Часто при создании интеграций, выгрузок на сайты или обменов с внешними системами нам требуется получить текстовое строковое представление ссылки. Однако платформа 1С:Предприятие накладывает определенные ограничения на использование типа УникальныйИдентификатор в запросах. В этой статье мы подробно разберем, почему это реализовано именно так, и рассмотрим все доступные способы решения задачи.
Для начала разберем внутреннее устройство системы. Ссылка в 1С (тип ЛюбаяСсылка) — это не просто строка, это бинарный объект размером 16 байт. В СУБД (например, Microsoft SQL Server) это поле хранится в формате binary(16). Текстовое же представление GUID (например, "550e8400-e29b-41d4-a716-446655440000") — это строка из 36 символов. Если бы платформа автоматически преобразовывала каждый бинарный идентификатор в строку при выполнении запроса, это привело бы к колоссальным затратам ресурсов сервера БД.
Рассмотрим основные причины ограничений:
Ссылка.УникальныйИдентификатор().Долгое время тип УникальныйИдентификатор был практически «персоной нон грата» в запросах. Однако, начиная с версии платформы 8.3.12, ситуация изменилась. Разберем, что теперь можно делать в языке запросов:
ТаблицыЗначений, содержащей колонки с типом УникальныйИдентификатор.ГДЕ и в операторе В.Однако, важно понимать: функции преобразования ссылки в GUID внутри самого запроса по-прежнему нет. Мы не можем написать ВЫРАЗИТЬ(Ссылка КАК УникальныйИдентификатор).
Если ваша задача — постоянно передавать идентификаторы во внешние системы, самым надежным и быстрым способом будет создание дополнительного реквизита. Проанализируем этот подход:
Добавьте в справочник или документ реквизит ИдентификаторДляОбмена с типом Строка (36 символов) или УникальныйИдентификатор. При записи объекта программно заполняйте это поле:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если ЭтоНовый() Тогда
// Если это новый объект, GUID еще не назначен,
// его нужно получить методом УстановитьСсылкуНового()
// или использовать УникальныйИдентификатор после записи.
КонецЕсли;
// Для существующих объектов:
ЭтотОбъект.ИдентификаторДляОбмена = ЭтотОбъект.Ссылка.УникальныйИдентификатор();
КонецПроцедуры
Теперь это поле доступно в любом запросе. Это решение является наиболее «чистым» с точки зрения архитектуры 1С, так как оно позволяет индексировать поле и мгновенно искать объекты при обратном обмене.
Когда нет возможности менять конфигурацию (например, база находится на поддержке), используем программный перебор результата запроса. Рассмотрим пример, как это сделать эффективно:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
ТекстовыйGUID = Строка(Выборка.Ссылка.УникальныйИдентификатор());
// Далее передаем данные в структуру или массив для отправки
КонецЦикла;
Важный нюанс: Метод УникальныйИдентификатор() при обращении через точку от ссылки вызывает обращение к базе данных, если объект не кэширован. Если записей десятки тысяч, это может замедлить работу. В таких случаях лучше выгрузить результат запроса в ТаблицуЗначений и добавить колонку программно.
Одной из серьезных проблем 1С является отсутствие встроенного идентификатора у строк табличных частей (ТЧ). У строки есть только НомерСтроки, который может измениться при сортировке или удалении других строк. Если вам нужно передать во внешнюю систему ссылку именно на строку ТЧ, выполним следующие шаги:
КлючСтроки с типом УникальныйИдентификатор.ПередЗаписью проверим заполнение этого ключа.
Для Каждого СтрокаТЧ Из ЭтотОбъект.Товары Цикл
Если СтрокаТЧ.КлючСтроки.Пустой() Тогда
СтрокаТЧ.КлючСтроки = Новый УникальныйИдентификатор;
КонецЕсли;
КонецЦикла;
Такой подход позволяет однозначно идентифицировать строку даже после перемещения или частичного удаления данных в документе.
Если ваша цель — интеграция с сайтом или внешним приложением, выясним, нельзя ли использовать стандартный интерфейс OData. В 1С при публикации информационной базы на веб-сервере можно включить стандартный программный интерфейс. В OData идентификатор объекта является ключевым полем URL.
Запрос вида http://server/base/odata/standard.odata/Catalog_Номенклатура(guid'...') позволяет получать данные без написания сложных запросов внутри 1С. Платформа сама транслирует строковый GUID в бинарный вид и возвращает результат.
Если вы работаете с прямыми SQL-запросами (что не рекомендуется для типовых задач, но иногда необходимо в высоконагруженных системах), помните о «перевернутых байтах». Чтобы получить GUID, соответствующий 1С, в MS SQL Server, придется использовать сложную конструкцию преобразования _IDRRef. Посмотрим, как выглядит логика перестановки байтов:
Нужно взять бинарное поле и переставить байты в следующем порядке: 13-16, 11-12, 9-10, 1-8. Это связано с разницей в хранении типов данных Uniqueidentifier в SQL и логикой платформы 1С.
Мы выяснили, что отсутствие прямой поддержки GUID в запросе — это не «забывчивость» разработчиков, а сознательное решение для обеспечения стабильности и скорости работы базы данных.
Рассмотрим краткий алгоритм выбора решения:
УникальныйИдентификатор непосредственно в ТЧ.Использование современных возможностей платформы (начиная с 8.3.12) позволяет гибко передавать списки GUID во временные таблицы, что закрывает 90% потребностей программиста при работе со сложными алгоритмами поиска и синхронизации данных.