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

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

При разработке сложных механизмов интеграции и алгоритмов обработки данных в 1С разработчики часто сталкиваются с необходимостью соединения таблиц базы данных по полю типа УникальныйИдентификатор с временными таблицами. Однако в языке запросов платформы существуют жесткие ограничения: в запрос напрямую нельзя передать ТаблицуЗначений с колонкой типа УникальныйИдентификатор, а приведение GUID к строковому представлению не позволяет корректно выполнить условие связи с полем типа УникальныйИдентификатор.

Рассмотрим подробно причины возникновения этой проблемы и проанализируем проверенные способы ее решения в зависимости от версии платформы 1С и архитектуры решения.

Суть проблемы и ограничения языка запросов

Сформулируем основные сложности, с которыми сталкивается разработчик:

  1. Передать во временную таблицу запроса колонку с типом УникальныйИдентификатор из ТаблицаЗначений невозможно — платформа выдает ошибку при передаче параметров.
  2. Оператор ВЫРАЗИТЬ не умеет преобразовывать тип Строка в УникальныйИдентификатор и наоборот в самом языке запросов.
  3. Функция ПРЕДСТАВЛЕНИЕ() формирует строковый результат, но его запрещено использовать в секциях ПО (условия соединения), ГДЕ и ГРУППИРОВАТЬ ПО.

Разберем основные практические методы, позволяющие обойти эти ограничения.

Способ 1. Встроенная функция УникальныйИдентификатор() (начиная с платформы 8.3.22)

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

В этом случае в ТаблицуЗначений помещаем строку с GUID, передаем ее во временную таблицу и выполняем соединение следующими образом:


ВЫБРАТЬ
    ВТ_Данные.УИДСтрокой КАК УИДСтрокой,
    ВТ_Данные.Количество КАК Количество
ПОМЕСТИТЬ ВТ_ИсходныеДанные
ИЗ
    &ТЗДанных КАК ВТ_Данные;

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

Способ 2. Предварительное получение ссылок в коде 1С

Когда требуется связать строковые представление УИД из ТаблицаЗначений со ссылочной таблицей БД, оптимальным подходом до платформы 8.3.22 является предварительное получение объектов ссылочного типа через менеджер объекта.

Проанализируем алгоритм подготовки данных перед передачей в запрос:


// Добавляем колонку под полноценную ссылку в исходную ТЗ
ТЗ.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("ДокументСсылка.РеализацияТоваровУслуг"));

Для Каждого Стр Из ТЗ Цикл
    УИД = Новый УникальныйИдентификатор(Стр.УИДСтрокой);
    Стр.Ссылка = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(УИД);
КонецЦикла;

// Передаем ТЗ во временную таблицу запроса
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВТ.Ссылка КАК Ссылка,
    |	ВТ.Значение КАК Значение
    |ПОМЕСТИТЬ ВТ_Данные
    |ИЗ
    |	&ТЗ КАК ВТ;
    |
    |ВЫБРАТЬ
    |	ВТ.Ссылка КАК Ссылка,
    |	ТаблицаБД.СуммаДокумента КАК Суммировать
    |ИЗ
    |	ВТ_Данные КАК ВТ
    |	ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК ТаблицаБД
    |		ПО ВТ.Ссылка = ТаблицаБД.Ссылка";

Запрос.УстановитьПараметр("ТЗ", ТЗ);
Результат = Запрос.Выполнить();

Метод ПолучитьСсылку() формирует ссылку на объект по его УникальныйИдентификатор без обращения к базе данных, что обеспечит высокую скорость работы алгоритма.

Способ 3. Передача массива объектов УникальныйИдентификатор в параметры

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

Рассмотрим пример фильтрации:


МассивУИД = Новый Массив;
Для Каждого Стр Из ТЗ Исходная Цикл
    МассивУИД.Добавить(Новый УникальныйИдентификатор(Стр.УИДСтрокой));
КонецЦикла;

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Таблица.Ссылка КАК Ссылка,
    |	Таблица.УИДЭтапа КАК УИДЭтапа
    |ИЗ
    |	РегистрСведений.ЭтапыПроцессов КАК Таблица
    |ГДЕ
    |	Таблица.УИДЭтапа В (&МассивУИД)";

Запрос.УстановитьПараметр("МассивУИД", МассивУИД);
Результат = Запрос.Выполнить();

Способ 4. Использование регистра сведений вместо Таблицы Значений

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

← На главную