Почему в запросах 1С нельзя получить GUID ссылки и как решить эту задачу

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Архитектурные причины: Ссылка vs GUID

Для начала разберем внутреннее устройство системы. Ссылка в 1С (тип ЛюбаяСсылка) — это не просто строка, это бинарный объект размером 16 байт. В СУБД (например, Microsoft SQL Server) это поле хранится в формате binary(16). Текстовое же представление GUID (например, "550e8400-e29b-41d4-a716-446655440000") — это строка из 36 символов. Если бы платформа автоматически преобразовывала каждый бинарный идентификатор в строку при выполнении запроса, это привело бы к колоссальным затратам ресурсов сервера БД.

Рассмотрим основные причины ограничений:

  1. Производительность: Операции со строками в SQL выполняются значительно медленнее, чем с бинарными данными. Индексация 36-символьных строк требует гораздо больше места и времени на обработку.
  2. Объем данных: Хранение GUID в виде строки в Unicode увеличивает объем данных в несколько раз (с 16 байт до 72 байт на одну запись).
  3. Инверсия байтов: 1С хранит ссылки в SQL в специфическом порядке, который отличается от стандарта RFC 4122. При записи в базу части идентификатора «переворачиваются». Прямое чтение через SQL-запрос без специальной функции преобразования выдаст «битый» GUID, который не совпадет с тем, что вы видите в коде 1С через Ссылка.УникальныйИдентификатор().

Революция в версии 8.3.12 и старше

Долгое время тип УникальныйИдентификатор был практически «персоной нон грата» в запросах. Однако, начиная с версии платформы 8.3.12, ситуация изменилась. Разберем, что теперь можно делать в языке запросов:

Однако, важно понимать: функции преобразования ссылки в GUID внутри самого запроса по-прежнему нет. Мы не можем написать ВЫРАЗИТЬ(Ссылка КАК УникальныйИдентификатор).

Решение 1: Использование дополнительного реквизита

Если ваша задача — постоянно передавать идентификаторы во внешние системы, самым надежным и быстрым способом будет создание дополнительного реквизита. Проанализируем этот подход:

Добавьте в справочник или документ реквизит ИдентификаторДляОбмена с типом Строка (36 символов) или УникальныйИдентификатор. При записи объекта программно заполняйте это поле:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Если ЭтоНовый() Тогда
        // Если это новый объект, GUID еще не назначен, 
        // его нужно получить методом УстановитьСсылкуНового() 
        // или использовать УникальныйИдентификатор после записи.
    КонецЕсли;
    
    // Для существующих объектов:
    ЭтотОбъект.ИдентификаторДляОбмена = ЭтотОбъект.Ссылка.УникальныйИдентификатор();
КонецПроцедуры

Теперь это поле доступно в любом запросе. Это решение является наиболее «чистым» с точки зрения архитектуры 1С, так как оно позволяет индексировать поле и мгновенно искать объекты при обратном обмене.

Решение 2: Пост-обработка результатов запроса

Когда нет возможности менять конфигурацию (например, база находится на поддержке), используем программный перебор результата запроса. Рассмотрим пример, как это сделать эффективно:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Номенклатура.Ссылка КАК Ссылка,
    |   Номенклатура.Наименование КАК Наименование
    |ИЗ
    |   Справочник.Номенклатура КАК Номенклатура";

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

Пока Выборка.Следующий() Цикл
    ТекстовыйGUID = Строка(Выборка.Ссылка.УникальныйИдентификатор());
    // Далее передаем данные в структуру или массив для отправки
КонецЦикла;

Важный нюанс: Метод УникальныйИдентификатор() при обращении через точку от ссылки вызывает обращение к базе данных, если объект не кэширован. Если записей десятки тысяч, это может замедлить работу. В таких случаях лучше выгрузить результат запроса в ТаблицуЗначений и добавить колонку программно.

Решение 3: Работа с GUID в строках табличных частей

Одной из серьезных проблем 1С является отсутствие встроенного идентификатора у строк табличных частей (ТЧ). У строки есть только НомерСтроки, который может измениться при сортировке или удалении других строк. Если вам нужно передать во внешнюю систему ссылку именно на строку ТЧ, выполним следующие шаги:

  1. Добавим в табличную часть реквизит КлючСтроки с типом УникальныйИдентификатор.
  2. В событии ПередЗаписью проверим заполнение этого ключа.

Для Каждого СтрокаТЧ Из ЭтотОбъект.Товары Цикл
    Если СтрокаТЧ.КлючСтроки.Пустой() Тогда
        СтрокаТЧ.КлючСтроки = Новый УникальныйИдентификатор;
    КонецЕсли;
КонецЦикла;

Такой подход позволяет однозначно идентифицировать строку даже после перемещения или частичного удаления данных в документе.

Решение 4: Использование OData (REST-интерфейс)

Если ваша цель — интеграция с сайтом или внешним приложением, выясним, нельзя ли использовать стандартный интерфейс OData. В 1С при публикации информационной базы на веб-сервере можно включить стандартный программный интерфейс. В OData идентификатор объекта является ключевым полем URL.

Запрос вида http://server/base/odata/standard.odata/Catalog_Номенклатура(guid'...') позволяет получать данные без написания сложных запросов внутри 1С. Платформа сама транслирует строковый GUID в бинарный вид и возвращает результат.

Продвинутый уровень: SQL-запросы (для экспертов)

Если вы работаете с прямыми SQL-запросами (что не рекомендуется для типовых задач, но иногда необходимо в высоконагруженных системах), помните о «перевернутых байтах». Чтобы получить GUID, соответствующий 1С, в MS SQL Server, придется использовать сложную конструкцию преобразования _IDRRef. Посмотрим, как выглядит логика перестановки байтов:

Нужно взять бинарное поле и переставить байты в следующем порядке: 13-16, 11-12, 9-10, 1-8. Это связано с разницей в хранении типов данных Uniqueidentifier в SQL и логикой платформы 1С.

Подведем итоги

Мы выяснили, что отсутствие прямой поддержки GUID в запросе — это не «забывчивость» разработчиков, а сознательное решение для обеспечения стабильности и скорости работы базы данных.

Рассмотрим краткий алгоритм выбора решения:

Использование современных возможностей платформы (начиная с 8.3.12) позволяет гибко передавать списки GUID во временные таблицы, что закрывает 90% потребностей программиста при работе со сложными алгоритмами поиска и синхронизации данных.

← На главную