Как в запросе 1С получить ссылку из ГУИД: разбор ограничений и готовые решения

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

В практике разработчика 1С часто возникает задача, когда идентификаторы объектов (GUID) приходят из внешних систем в виде строк или хранятся в отдельной базе данных. Попытка использовать эти данные напрямую в запросе для получения полноценной ссылки на справочник или документ часто приводит к ошибкам. Рассмотрим подробнее, почему стандартный подход не работает и какими методами можно решить эту задачу эффективно.

Почему нельзя использовать ВЫРАЗИТЬ в запросе для преобразования ГУИД

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

Важно понимать: Ссылка в базе данных 1С — это не просто строка, это 16-байтовое двоичное число. Хотя мы привыкли видеть ГУИД как строку из 36 символов, в самой СУБД (SQL Server или PostgreSQL) хранение и индексация происходят в бинарном виде. Прямого механизма "кастинга" (преобразования типов) строки в ссылку внутри SQL-запроса платформой 1С не предусмотрено.

Способ 1. Получение ссылки программно перед выполнением запроса

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

Рассмотрим пример кода, где мы преобразуем строковый ГУИД в ссылку и передаем его в запрос как параметр:


// Допустим, у нас есть строковый идентификатор
СтрокаГуд = "550e8400-e29b-41d4-a716-446655440000";
УникальныйИд = Новый УникальныйИдентификатор(СтрокаГуд);

// Получаем ссылку без обращения к БД
СсылкаНаНоменклатуру = Справочники.Номенклатура.ПолучитьСсылку(УникальныйИд);

// Теперь передаем эту ссылку в запрос
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Наименование,
    |	Номенклатура.Артикул
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.Ссылка = &Ссылка";

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

Этот метод идеален, когда идентификаторов немного. Однако помните о риске "битых ссылок": если в базе данных нет объекта с таким ГУИДом, 1С все равно создаст ссылку, но при попытке получить ее поля в запросе вы увидите NULL или текст "Объект не найден".

Способ 2. Использование временных таблиц для массовой обработки

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

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

  1. Создаем таблицу значений с колонкой типа СправочникСсылка....
  2. Заполняем таблицу, преобразуя входящие строки ГУИД в ссылки методом ПолучитьСсылку().
  3. Передаем таблицу в запрос и помещаем ее во временную таблицу.
  4. Соединяем временную таблицу с реальными таблицами базы данных.

Посмотрим на пример реализации этого метода:


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

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

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

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

Преимущество: Этот способ работает максимально быстро, так как поиск по ссылкам в 1С оптимизирован на уровне индексов СУБД. Мы "скармливаем" запросу уже готовые типизированные данные.

Способ 3. Использование функционала БСП (Соответствия объектов)

В современных конфигурациях (ERP, КА, УТ 11, БП 3.0), построенных на Библиотеке стандартных подсистем (БСП), часто используется регистр сведений СоответствияОбъектовИнформационныхБаз. Если ваша задача связана с обменом данными, проанализируем, как получить ссылку через этот регистр.

В этом регистре хранятся строковые уникальные идентификаторы внешних систем и соответствующие им ссылки в текущей базе. В этом случае нам вообще не нужно преобразовывать ГУИД — мы просто делаем запрос к регистру:


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

Запрос.УстановитьПараметр("СтрокаГуд", НужныйГудВВидеСтроки);

Такой подход позволяет избежать создания "битых" ссылок, так как в регистре фиксируются только реально существующие сопоставления.

Технические нюансы: Хранение ГУИД в SQL

Разберем глубокий технический момент, упомянутый опытными разработчиками. В 1С представление ГУИДа отличается от того, как его видит SQL. Если вы планируете писать прямые SQL-запросы (через ADODB или внешние источники данных), помните, что порядок байтов в binary(16) у 1С "развернут".

Внутри 1С ГУИД выглядит как XXXX-YY-ZZ-..., но в SQL-таблицах группы байтов переставлены местами для оптимизации индексации. Поэтому при работе через внешние источники данных лучше использовать встроенные механизмы сопоставления типов, которые предоставляет платформа 1С, чтобы не заниматься ручной перестановкой символов в строке.

Выводы

Подведем итоги нашего анализа. Прямого способа превратить строку в ссылку внутри текста запроса не существует. Для решения задачи мы:

Выбор конкретного метода зависит от объема данных и того, используются ли в вашей системе стандартные механизмы обмена БСП. Для разовых задач оптимален Способ 1, для массовой обработки — Способ 2.

← На главную