Как в запросе 1С преобразовать Уникальный Идентификатор в Строку?

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

Мы часто сталкиваемся с задачами интеграции, сверки данных между базами или необходимостью поиска объектов по их внутренним идентификаторам (GUID/UUID) — для такой сверки есть утилита сравнения и поиска расхождений данных между базами 1С. Для таких задач часто применяется продвинутая консоль запросов, позволяющая быстро отладить пакетные запросы. Казалось бы, задача тривиальная: получить уникальный идентификатор ссылки прямо в запросе и превратить его в строку для дальнейшего сравнения или выгрузки. Однако, при попытке сделать это "в лоб", мы сталкиваемся с неочевидным поведением платформы.

Чтобы проводить быстрый анализ данных без лишних сложностей, давайте подробно разберем, почему стандартные функции преобразования типов не работают с уникальными идентификаторами внутри языка запросов, и рассмотрим проверенные на практике способы решения этой задачи.

Почему не работает ВЫРАЗИТЬ?

Первое, что приходит в голову разработчику, — использовать оператор ВЫРАЗИТЬ (CAST). Логика подсказывает следующую конструкцию:


ВЫБРАТЬ
    ВЫРАЗИТЬ(Док.Ссылка.УникальныйИдентификатор() КАК СТРОКА(36)) КАК УИД_Строка
ИЗ
    Документ.РеализацияТоваровУслуг КАК Док

Но выполнив такой запрос, мы с удивлением обнаружим, что поле УИД_Строка либо пустое, либо содержит значение NULL (в зависимости от контекста). Давайте разберемся, почему так происходит.

Оператор ВЫРАЗИТЬ в языке запросов 1С предназначен не для конвертации данных из одного типа в другой (как это делает функция Строка() во встроенном языке), а для приведения типов. Это критически важное различие.

  1. Работа с составными типами: Если поле может содержать ссылки на разные документы (например, "ДокументОснование"), ВЫРАЗИТЬ позволяет отсечь все лишнее и оставить только значения конкретного типа.
  2. Ограничение длины: Для строк можно уменьшить длину (обрезать строку), но нельзя превратить число или бинарные данные в строку.

Уникальный идентификатор на уровне СУБД (SQL Server, PostgreSQL) хранится как бинарные данные (обычно BINARY(16)). Язык запросов 1С, обеспечивая независимость от конкретной СУБД, не предоставляет встроенного механизма трансляции этих бинарных данных в их шестнадцатеричное строковое представление (hex-string) непосредственно в момент выполнения SQL-запроса.

Таким образом, попытка "выразить" уникальный идентификатор как строку обречена на неудачу, так как эти типы данных несовместимы в контексте оператора приведения типов.

Способ №1: Использование функции ПРЕДСТАВЛЕНИЕ (Для вывода)

Если ваша задача — просто вывести уникальный идентификатор в отчет или удобную консоль запросов для визуального контроля, либо выгрузить его в простой список без дальнейшей обработки внутри этого же запроса, то самым простым решением будет использование функции ПРЕДСТАВЛЕНИЕ — для отладки таких запросов пригодится продвинутая консоль запросов и СК.

Посмотрим, как это выглядит в коде:


ВЫБРАТЬ
    // Получаем сам объект типа "УникальныйИдентификатор"
    УНИКАЛЬНЫЙИДЕНТИФИКАТОР(МойДокумент.Ссылка) КАК УИД_Поле,
    
    // Получаем его строковое представление
    ПРЕДСТАВЛЕНИЕ(УНИКАЛЬНЫЙИДЕНТИФИКАТОР(МойДокумент.Ссылка)) КАК УИД_Строка
ИЗ
    Документ.ЗаказКлиента КАК МойДокумент

Важные особенности этого метода:

Способ №2: Обработка через Таблицу Значений (Для логики и соединений)

Это наиболее универсальный и надежный метод, если вам нужно использовать строковый УИД для поиска, интеллектуального сравнения строк или соединения с данными из внешних источников (например, при загрузке данных из Excel/XML, где ID приходят в виде строк).

Алгоритм действий следующий:

  1. Выбираем данные запросом, получая поле типа УникальныйИдентификатор.
  2. Выгружаем результат в ТаблицаЗначений.
  3. Добавляем в таблицу новую колонку строкового типа.
  4. Проходим циклом по таблице и заполняем строковую колонку, используя функцию встроенного языка Строка().
  5. При необходимости — загружаем эту таблицу обратно в запрос как параметр (временную таблицу).

Рассмотрим пример кода реализации этого подхода:


// 1. Создаем запрос для получения данных
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
|   УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Спр.Ссылка) КАК СсылкаУИД,
|   Спр.Наименование,
|   Спр.Код
|ИЗ
|   Справочник.Номенклатура КАК Спр
|ГДЕ
|   Спр.ЭтоГруппа = ЛОЖЬ";

// 2. Выгружаем в ТЗ
ТаблицаДанных = Запрос.Выполнить().Выгрузить();

// 3. Подготавливаем колонку для строкового представления
ТаблицаДанных.Колонки.Добавить("УИД_Строка", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(36)));

// 4. Преобразуем данные средствами платформы (на клиенте или сервере приложений)
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
    // Здесь работает стандартное преобразование 1С, которое недоступно в языке запросов
    СтрокаТЗ.УИД_Строка = Строка(СтрокаТЗ.СсылкаУИД);
КонецЦикла;

// Теперь у нас есть ТаблицаДанных, где есть и типизированный УИД, и его строковое представление.
// Мы можем использовать эту таблицу в другом запросе для соединения.

Этот метод требует больше кода, но он гарантирует корректность данных. Если вы столкнулись с падением производительности при таком подходе, рекомендуем изучить методы оптимизации отчетов с набором данных типа «объект».

Способ №3: Использование СКД (Система Компоновки Данных)

Если ваша задача лежит в плоскости создания отчетов, то Система Компоновки Данных (СКД) предоставляет элегантное решение без написания кода, особенно если использовать инструменты расширения возможностей СКД для работы на стороне клиента.

В языке запросов СКД действуют те же ограничения, что и в обычном запросе. Однако СКД имеет мощный механизм Вычисляемых полей, которые рассчитываются уже после выполнения основного запроса к базе данных.

Как это настроить:

  1. В наборе данных запроса выберите поле: УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Ссылка) КАК СсылкаУИД.
  2. Перейдите на вкладку Вычисляемые поля.
  3. Добавьте новое поле, например, СтрокаУИД.
  4. В колонке "Выражение" напишите: XMLСтрока(СсылкаУИД) или просто Строка(СсылкаУИД).

СКД выполнит запрос к СУБД, получит бинарные данные, а затем преобразует их в строку. В редких архитектурных задачах разработчики даже используют две разных схемы в одном отчете СКД, но для простого преобразования идентификатора достаточно базовых настроек вычисляемых полей.

Архитектурное решение (Best Practice)

Давайте проанализируем ситуацию, когда вам нужно регулярно выполнять поиск или соединение по строковому представлению УИДа в высоконагруженной системе. Использование способа с выгрузкой в таблицу значений может быть накладным по ресурсам памяти и времени.

В таких случаях профессиональным архитектурным решением считается добавление специального реквизита в объект метаданных.

Реализация:

  1. Добавляем в Справочник или Документ реквизит ИдентификаторСтрокой (Тип: Строка, Длина: 36, Фиксированная: Да).
  2. Обязательно включаем для этого реквизита свойство Индексировать (для ускорения поиска).
  3. В модуле объекта в подписке на событие ПередЗаписью добавляем код:

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

Такой подход позволяет в будущем делать прямые запросы с условиями вида ГДЕ Док.ИдентификаторСтрокой = &НужнаяСтрока, что будет работать мгновенно благодаря индексам СУБД.

Резюме

Подводя итог, можно сказать, что получить строку из уникального идентификатора непосредственно внутри запроса 1С для логических операций невозможно из-за ограничений трансляции типов в СУБД. Однако мы рассмотрели три надежных способа решения:

← На главную