18.11.2021 на зазеркалье появился анонс: Получение уникального идентификатора объекта из ссылки в запросе
Я в основном занимаюсь интеграцией и поэтому с момента анонса на зазеркалье ждал этой возможности, но, наученный горьким опытом, не ставил последнюю версию платформы даже когда вышла 8.3.22. Благодаря событиям от 14.11.2022 Экстренные обновления для решения проблем платформы "1С:Предприятие 8" мы на работе решили ставить последнюю 8.3.22, так как понимали, что все платформы теперь одного качества.
Что ожидал я?
В платформе мы можем получать идентификатор:
Ссылка.УникальныйИдентификатор()
// ИЛИ
Новый УникальныйИдентификатор(XMLСтрока(Ссылка))
И идентификатор строкой:
XMLСтрока(Ссылка)
// ИЛИ
Строка(Ссылка.УникальныйИдентификатор())
Я ожидал, что будет возможность получить идентификатор в запросе как «УникальныйИдентификатор», так и Строка(36), тем более в платформе 8.3.20 в язык запросов добавляются функции:
Строка() – преобразует значение примитивного типа в строку с учетом национальных установок.
Что получили?
В запросе мы получаем «УникальныйИдентификатор»
Если мы возьмем ERP и поищем слово «Идентификатор», то всплывет много объектов в которых этот реквизит, может быть, Строка или УникальныйИдентификатор. Вообще тот, кто занимается интеграциями, наверняка сталкивался с потребностью преобразования типа УникальныйИдентификатор в строку в запросе.
Вот простая задача:
В ERP и не только в ней есть регистр сведений «ПубличныеИдентификаторыСинхронизируемыхОбъектов»
В данном регистре 3 реквизита:
УзелИнформационнойБазы – ПланОбменаСсылка
Ссылка – ДокументСсылка, ПланВидовХарактеристикСсылка, СправочникСсылка
Идентификатор – Строка(36)
Вопрос: Как нам одним запросом сравнить идентификатор во внешней системе с идентификатором объекта текущей конфигурации?
Ответ: По большому счету нужно получить идентификатор ссылки и сравнить с идентификатором, но тут понадобится либо реквизит Идентификатор преобразовать в УникальныйИдентификатор, либо идентификатор ссылки преобразовать в строку.
На СКД такая задача решается легко:
Можно ли УникальныйИдентификатор преобразовать в строку в запросе?
Увы и ах, можно только через одно место… Самое противное, что потом никакие операции с этой строкой в запросе уже не сделать.
Попытка использовать Строка()
Попытка использовать Выразить()
Вообще я проделал много попыток и получить строку можно только через ПРЕДСТАВЛЕНИЕ, а с ним в запросе не поработать.
Работает УНИКАЛЬНЫЙИДЕНТИФИКАТОР() в режиме совместимости?
Я попробовал режим совместимости «Версия 8.3.1». Работает.
Тогда я включил режим совместимости «Версия 8.2.13». Работает.
Делаем вывод, что все работает, а значит на программиста возлагается большая ответственность. Так как данный функционал появился только в 8.3.22, значит, написанный запрос и запущенный на более ранних версиях вызовет ошибку.
Что с «Битыми ссылками»?
Есть много вариантов получить идентификатор из «битой ссылки»
1 Дедушкин способ:
&НаСервереБезКонтекста
Функция ПолучитьУИБитойССылкиОтДеда(ГУИДУдОбъкта) Экспорт
ГУИДУдОбъктаСтр = СтрЗаменить(ГУИДУдОбъкта,"<Объект не найден> (","");
ГУИДУдОбъктаСтр = СтрЗаменить(ГУИДУдОбъктаСтр,")","");
ГУИДУдОбъктаСтр = СтрЗаменить(ГУИДУдОбъктаСтр,"0x","");
ГУИДУдОбъктаСтр = Сред(ГУИДУдОбъктаСтр, Найти(ГУИДУдОбъктаСтр,":")+1, СтрДлина(ГУИДУдОбъктаСтр));
// Преобразуем GUID
ГУИД = Сред(ГУИДУдОбъктаСтр,25,8)+"-"+Сред(ГУИДУдОбъктаСтр,21,4)+"-"+Сред(ГУИДУдОбъктаСтр,17,4)+"-"+Сред(ГУИДУдОбъктаСтр,1,4)+"-"+Сред(ГУИДУдОбъктаСтр,5,12);
Возврат ГУИД;
КонецФункции
2 Современный метод:
&НаСервереБезКонтекста
Функция ПолучитьУИБитойССылкиНаСервере(БитаяСсылка)
Возврат XMLСтрока(БитаяСсылка);
КонецФункции
3 Запросом:
&НаСервереБезКонтекста
Функция ПолучитьУИБитойССылкиЗапросомНаСервере(БитаяСсылка)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| УНИКАЛЬНЫЙИДЕНТИФИКАТОР(&БитаяСсылка) КАК УИ";
Запрос.УстановитьПараметр("БитаяСсылка", БитаяСсылка);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
УИ = ВыборкаДетальныеЗаписи.УИ;
Иначе
УИ = XMLСтрока(Справочники.Товары.ПустаяСсылка());
КонецЕсли;
Возврат УИ;
КонецФункции
Предупреждаю: Конструктор запроса будет ругаться и не давать вам сохранить запрос, просто напишите от руки.
Теперь создам битую ссылку:
&НаСервереБезКонтекста
Функция СоздатьБитуюСсылкуНаСервере()
Возврат XMLЗначение(Тип("СправочникСсылка.Товары"), Строка(Новый УникальныйИдентификатор));
КонецФункции
и выполню все варианты.
Результат схож, но что радует?
Я создал регистр, в котором сделал битые ссылки:
Простым запросом мы получаем все идентификаторы
Как ведет себя функция если ей дать NULL?
NULL как и заявлено возвращает NULL
Я поймал интересную вещь, обратите внимание на запрос ниже и результат.
Добавив промежуточную временную таблицу, я получил нормальный результат.
Резюмирую: Мы получили новый функционал, который позволит закрыть часть задач, но есть еще к чему стремиться. Поэтому я, как всегда, создал письмо в никуда))
Надеюсь, информация была полезна!