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

Бесплатная консультация юриста

+7 (800) 302-87-29

Реклама jurik.ru

В платформе 1С:Предприятие 8 каждый объект информационной базы (элемент справочника, документ, запись регистра и т․д․) обладает уникальным идентификатором — GUID (Globally Unique Identifier)․ Внутренне ссылка (Ссылка) на объект и есть представление этого GUID․ Часто разработчикам возникает задача: имея строковое представление GUID (например, полученное из внешней системы, логов или файла обмена), найти соответствующий объект или получить к нему ссылку прямо в тексте запроса к базе данных․

В данной статье подробно разберем способы получения ссылки по GUID в запросе, особенности работы с типами УникальныйИдентификатор и Ссылка, а также типичные ошибки и лучшие практики․

Теоретические основы: GUID, УникальныйИдентификатор и Ссылка

Перед тем как переходить к коду, важно понимать разницу между типами данных:

  • GUID (строка) — символьное представление идентификатора в формате xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ․ Приходит извне или хранится в строковых полях․
  • УникальныйИдентификатор (UniqueIdentifier) — встроенный тип платформы 1С, предназначенный для хранения и операций с GUID в памяти․ Создается конструктором Новый УникальныйИдентификатор(<Строка>)․
  • Ссылка (Ref) — тип данных, ссылающийся на конкретный объект метаданных (Справочник․Номенклатура, Документ․РеализацияТоваровУслуг и т;д․)․ Ссылка «знает» свой вид метаданных․

Ключевой момент: В запросах 1С нельзя напрямую сравнивать поле типа Ссылка со строкой․ Необходимо привести строку к типу УникальныйИдентификатор или использовать специальные функции языка запросов․

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

Хотя тема статьи — запросы, часто GUID преобразуют в ссылку в коде модуля перед передачей параметром в запрос․ Это самый производительный и читаемый способ для точечных операций․

Метод Менеджера ПолучитьСсылку

У каждого менеджера справочника, документа и т․д․ есть метод ПолучитьСсылку(<УникальныйИдентификатор>)․

// Пример: Получение ссылки на элемент справочника Номенклатура
ГуидСтрока = "09e5174f-551f-11e8-a22b-0800272d9f13";

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

Важно: Метод ПолучитьСсылку не обращается к базе данных для проверки существования объекта (в большинстве конфигураций на управляемых формах)․ Он лишь формирует структуру ссылки на основе GUID․ Проверка существования требует вызова ПолучитьОбъект или запроса к БД․

Универсальная функция для произвольного типа метаданных

Если тип метаданных неизвестен заранее (хранится в строке), можно использовать Метаданные:

Функция ПолучитьСсылкуПоГуиду(ИмяМетаданных, ГуидСтрока) Экспорт
 Попытка
 Гуид = Новый УникальныйИдентификатор(ГуидСтрока);
 Менеджер = Метаданные[ИмяМетаданных];
 Если Менеджер = Неопределено Тогда
 Возврат Неопределено;
 КонецЕсли;
 Возврат Менеджер․ПолучитьСсылку(Гуид);
 Исключение
 Возврат Неопределено;
 КонецПопытки;
КонецФункции

Работа с GUID в языке запросов (SQL-подобный синтаксис 1С)

В запросах к базе данных (объект Запрос) есть свои правила работы с GUID․

Литерал УникальныйИдентификатор в тексте запроса

Язык запросов 1С поддерживает литерал типа УНИКАЛЬНЫЙИДЕНТИФИКАТОР․ Синтаксис:

ВЫБРАТЬ
 Номенклатура․Ссылка,
 Номенклатура․Наименование
ИЗ
 Справочник․Номенклатура КАК Номенклатура
ГДЕ
 Номенклатура․Ссылка = ЗНАЧЕНИЕ(УНИКАЛЬНЫЙИДЕНТИФИКАТОР("09e5174f-551f-11e8-a22b-0800272d9f13"))
  • ЗНАЧЕНИЕ(․․․) — обязательная конструкция для задания константы в запросе․
  • УНИКАЛЬНЫЙИДЕНТИФИКАТОР(«строка») — функция приведения строки к типу УникальныйИдентификатор․
  • Сравнение Ссылка = УникальныйИдентификатор работает корректно, так как платформа неявно приводит типы․

Передача параметра типа УникальныйИдентификатор

Лучшая практика — использовать параметризованные запросы․ Это безопаснее (защита от инъекций) и быстрее (переиспользование плана запроса)․

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

ГуидОбъект = Новый УникальныйИдентификатор("09e5174f-551f-11e8-a22b-0800272d9f13");
Запрос․УстановитьПараметр("ГуидПараметр", ГуидОбъект);

Результат = Запрос․Выполнить;
Выборка = Результат․Выбрать;
Пока Выборка․Следующий Цикл
 // Выборка․Ссылка — это уже полноценная ссылка на объект
КонецЦикла;

Функция ССЫЛКА в запросе (для динамического определения типа)

Если нужно построить ссылку в запросе, зная только строку GUID и имя таблицы (вида метаданных), можно использовать функцию ССЫЛКА(<ВидМетаданных>, <УникальныйИдентификатор>)․

// Пример: Поиск в объединенном наборе данных (редкий кейс)
ВЫБРАТЬ
 ССЫЛКА(Справочник․Номенклатура, ЗНАЧЕНИЕ(УНИКАЛЬНЫЙИДЕНТИФИКАТОР("09e5174f-551f-11e8-a22b-0800272d9f13"))) КАК НайденнаяСсылка

Однако чаще всего используется простое сравнение поля Ссылка с параметром, как в п․ 3․2․

Типичные ошибки и подводные камни

Сравнение со строкой вместо УникальныйИдентификатор

Ошибка:

// НЕВЕРНО: Сравнение ссылки со строкой
ГДЕ Номенклатура․Ссылка = "09e5174f-551f-11e8-a22b-0800272d9f13"

Платформа выдаст ошибку несовместимости типов при выполнении запроса․ Всегда оборачивайте строку в ЗНАЧЕНИЕ(УНИКАЛЬНЫЙИДЕНТИФИКАТОР(․․․)) или передавайте параметр типа УникальныйИдентификатор․

Пустые ссылки и NULL

В запросах 1С существует три состояния «пустоты» для ссылочных полей:

  1. NULL — отсутствие значения в поле БД (например, внешний ключ не заполнен)․ Проверяется: Поле ЕСТЬ NULL․
  2. Пустая ссылка — значение ЗНАЧЕНИЕ(Справочник․Номенклатура․ПустаяСсылка)․ Это валидная ссылка, указывающая в никуда․ Проверяется: Поле = ЗНАЧЕНИЕ(Справочник․Номенклатура․ПустаяСсылка)․
  3. Неопределено — значение не задано в языке 1С (переменная не инициализирована)․ В запросах как таковом не встречается, но может быть результатом ПолучитьОбъект для битой ссылки․

При поиске по GUID, если GUID соответствует пустой ссылке (все нули), запрос вернет записи с пустой ссылкой․ Обычно это исключают условием:

ГДЕ Номенклатура․Ссылка = &Гуид
 И Номенклатура․Ссылка <> ЗНАЧЕНИЕ(Справочник․Номенклатура․ПустаяСсылка)

«Битые» ссылки

Битая ссылка — это ссылка (GUID), на которую в базе не существует объекта (удален, повреждена БД)․

  • Метод ПолучитьСсылку в коде НЕ проверяет существование объекта․ Он вернет ссылку даже для несуществующего GUID․
  • В запросе условие Ссылка = &Гуид просто не вернет строк, если объекта нет (так как нет записи в таблице)․
  • Проблема возникает, если битая ссылка уже записана в реквизит другого объекта․ Тогда Реквизит․ПолучитьОбъект вернет Неопределено․

Для поиска битых ссылок в запросе часто используют ЛЕВОЕ СОЕДИНЕНИЕ с целевой таблицей и проверку ЦелеваяТаблица․Ссылка ЕСТЬ NULL․

Продвинутые сценарии

Пакетное получение ссылок (массив GUID)

Если нужно найти объекты по списку GUID (например, 1000 штук), неэффективно выполнять 1000 запросов или вызовов ПолучитьСсылку․

Вариант А: Временная таблица (наиболее производительно для больших объемов)․

// 1․ Создаем временную таблицу с полем Гуид (УникальныйИдентификатор)
МенеджерВТ = Новый МенеджерВременныхТаблиц;
ТаблицаГуидов = МенеджерВТ․ПолучитьВременнуюТаблицу("ГуидыДляПоиска");
ТаблицаГуидов․Колонки․Добавить("Гуид", Новый ОписаниеТипов("УникальныйИдентификатор"));

// 2․ Заполняем её массивом ГУИДов
НаборЗаписей = ТаблицаГуидов․СоздатьНаборЗаписей;
Для Каждого СтрГуид Из МассивСтрокГуидов Цикл
 Запись = НаборЗаписей․Добавить;
 Запись․Гуид = Новый УникальныйИдентификатор(СтрГуид);
КонецЦикла;
НаборЗаписей․Записать;

// 3․ Делаем один запрос с JOIN
Запрос․Текст = 
"ВЫБРАТЬ
 | Номенклатура․Ссылка
 |ИЗ
 | Справочник․Номенклатура КАК Номенклатура
 | ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Гуиды КАК ГУИДЫ
 | ПО Номенклатура․Ссылка = ГУИДЫ․Гуид";
Запрос․УстановитьПараметр("ВТ_Гуиды", ТаблицаГуидов);

Вариант Б: Оператор В (IN) для небольших списков (до нескольких сотен)․

МассивГуидовОбъектов = Новый Массив;
Для Каждого СтрГуид Из МассивСтрокГуидов Цикл
 МассивГуидовОбъектов․Добавить(Новый УникальныйИдентификатор(СтрГуид));
КонецЦикла;

Запрос․Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник․Номенклатура ГДЕ Ссылка В(&МассивГуидов)";
Запрос․УстановитьПараметр("МассивГуидов", МассивГуидовОбъектов);

Извлечение GUID из ссылки в запросе

Обратная задача: получить строковое представление GUID из поля Ссылка․

ВЫБРАТЬ
 Номенклатура․Ссылка,
 ВЫРАЗИТЬ(Номенклатура․Ссылка КАК СТРОКА(36)) КАК ГуидСтрока
ИЗ
 Справочник․Номенклатура КАК Номенклатура

Функция ВЫРАЗИТЬ(․․․ КАК СТРОКА(36)) преобразует УникальныйИдентификатор (внутреннее представление ссылки) в читаемую строку формата ․

Резюме: чек-лист лучших практик

  1. Всегда используйте параметризованные запросы․ Передавайте Новый УникальныйИдентификатор(Строка) в УстановитьПараметр․
  2. В тексте запроса используйте конструкцию ЗНАЧЕНИЕ(УНИКАЛЬНЫЙИДЕНТИФИКАТОР("․․․")) для констант․
  3. Не сравнивайте Ссылку со строкой напрямую — ошибка типов․
  4. Помните про ПустуюСсылку․ GUID из нулей (000․․․0) — это валидная пустая ссылка, она существует в любой таблице как значение по умолчанию․
  5. Для пакетной обработки используйте временные таблицы или оператор В с массивом УникальныйИдентификатор․
  6. Проверку существования объекта делайте через запрос (проверка на пустой результат) или Ссылка;ПолучитьОбъект <> Неопределено в коде․

Работа с GUID в 1С запросах требует понимания системы типов платформы․ Главное правило: в запросах оперируйте типом УникальныйИдентификатор, а не строкой․ Использование параметров запроса с объектами УникальныйИдентификатор, это стандарт де-факто, обеспечивающий типобезопасность, производительность и защиту от ошибок форматирования строки․ При необходимости массового поиска применяйте временные таблицы для минимизации нагрузки на СУБД․