Идентификатор объекта в запросе. Вы этого хотели?

12.01.23

Разработка - Механизмы платформы 1С

В платформе 8.3.22 появилась возможность получать идентификатор в запросе. Лично я ждал этого давно, но по итогу ждал большего. Что не так?

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Строка(БитаяСсылка);
КонецФункции 

Предупреждаю: Конструктор запроса будет ругаться и не давать вам сохранить запрос, просто напишите от руки.

 

   

             

Теперь создам битую ссылку:

&НаСервереБезКонтекста
Функция СоздатьБитуюСсылкуНаСервере()
	Возврат XMLЗначение(Тип("СправочникСсылка.Товары"), Строка(Новый УникальныйИдентификатор));  
КонецФункции

и выполню все варианты.

 

 

Результат схож, но что радует?

Я создал регистр, в котором сделал битые ссылки:

 

 

Простым запросом мы получаем все идентификаторы

 

 

Как ведет себя функция если ей дать NULL?

NULL как и заявлено возвращает NULL

 

 

Я поймал интересную вещь, обратите внимание на запрос ниже и результат.

 

 

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

 

 

Резюмирую: Мы получили новый функционал, который позволит закрыть часть задач, но есть еще к чему стремиться. Поэтому я, как всегда, создал письмо в никуда))

 

 

Надеюсь, информация была полезна!

8.3.22 УникальныйИдентификатор Запрос Строка NULL Битые ссылки

См. также

SALE! %

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

12000 10000 руб.

02.09.2020    93177    474    380    

530

MS SQL Server: изучаем планы запросов

Запросы HighLoad оптимизация Запросы Бесплатно (free)

Многие знают, что для ускорения работы запроса нужно «изучить план». При этом сам план обычно обескураживает: куча разноцветных иконок и стрелочек; ничего не понятно, но очень интересно! Аналитик производительности Александр Денисов на конференции Infostart Event 2021 Moscow Premiere рассказал, как выполняется план запроса и что нужно сделать, чтобы с его помощью находить проблемы производительности.

20.06.2023    7529    Филин    37    

92

Расширение глобального поиска 1С, или Глобальный поиск "на максималках"

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Мало кто знает, что поле "Глобального поиска" в 1С можно доработать. Добавить свои варианты поиска, кнопочки в результатах и даже целые пользовательские меню.

27.03.2023    5440    SeiOkami    10    

129

Все консоли запросов для 1С

Запросы Бесплатно (free)

Список всех популярных обработок.

17.03.2023    19048    kuzyara    70    

147

Версионирование объектов VS История данных

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Давайте разберемся в механизме «История данных» и поэкспериментируем для наглядности. Сравним «Версионирование объектов» и «Историю данных».

06.03.2023    10060    dsdred    48    

143

Практическая шпаргалка по новым возможностям языка запросов 1С

Механизмы платформы 1С Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

В предлагаемой статье решил привести примеры применения новых возможностей языка запросов 1С, начиная с версии платформы 8.3.20.

21.11.2022    19434    quazare    34    

120

Шпаргалка по функциям АСИНХ

Механизмы платформы 1С Платформа 1С v8.3 Россия Бесплатно (free)

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

29.07.2022    25379    zeltyr    19    

173

Динамическое обновление - это зло?

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Копнем глубже в тему "Что же такое динамическое обновление" и почему оно может привести к проблемам. И может ли?

09.05.2022    21329    Infostart    82    

232
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. kser87 2389 12.01.23 11:33 Сейчас в теме
Интересно, как до разработчиков платформы дошла необходимость подобного? Допустим, с сообществом они не особо контактируют. Но ведь есть например Конвертация данных. неужели разрабы этой конфигурации ни разу не выдвигали никаких требований?
2. dsdred 2718 12.01.23 11:44 Сейчас в теме
(1)Вообще контакт у 1с с разработчиками случается, нечасто но случается. Темболее они стали давать возможность побыть бетотестером. Я щупал 8.3.23 комунити например с предыдущего года и на последнем инфостарте подходил и жаловался на то что в 23 сделали возможность видеть метаданные конфигурации из расширения, но метаданные расширения из другого расширения не видно. Меня уверили что запросы такие уже поступали и скорее всего будет в будущем.
fatman78; user1835472; Жолтокнижниг; SagittariusA; Innuil; Andy_NTG; kser87; +7 Ответить
14. zakidonoff 23.05.23 14:59 Сейчас в теме
(2) На текущий момент использовать в расширении другое расширение - это нарушение самого принципа работы в расширении.

Тут больше подошла бы возможность выстраивать иерархию расширений.
Устанавливаешь некое расширение "Общий функционал" в тип "Базовое", куда кидаешь некие фундаментальные процедурки.
А разные расширения под доработки типа "Интеграция EDI" создаёшь с типом "Дополнение". И указываешь что оно зависимо от Базового расширения "Общий функционал".
Красиво и понятно.
Было бы.
it_depDi; dsdred; +2 Ответить
3. SeiOkami 3086 12.01.23 11:57 Сейчас в теме
Полгода назад тоже делал обзор по эту возможность и её косяки: https://youtu.be/1rywI70iScc
abasovit; Dimka74; kamisov; json; dsdred; +5 Ответить
4. dsdred 2718 12.01.23 12:10 Сейчас в теме
(3)спасибо, вечером посмотрю.
7. wizard.ilmir02 119 12.01.23 12:32 Сейчас в теме
А выразить в строку представление нельзя интересно?
10. dsdred 2718 12.01.23 13:51 Сейчас в теме
(7)нельзя

Даже больше скажу это плохо кончится.
Прикрепленные файлы:
Innuil; mikl79; +2 Ответить
5. dsdred 2718 12.01.23 12:22 Сейчас в теме
(3)Посмотрел. Видео полезное, но эксперимент некорректен.
На 13:22 в состовной тип добавляется Число, а на 16:08 в проверке отсекается Строка.
6. SeiOkami 3086 12.01.23 12:24 Сейчас в теме
(5) да, там в комментариях меня поправили, но ошибка всё равно одиаковая была) Даже если Строку число отсекать
8. sapervodichka 6559 12.01.23 12:34 Сейчас в теме
Я это в расширениях использую, где сложно составной тип указать. Связываю списки с регистрами расширений, где измерение регистра УИОбъекта имеет тип УникальныйИдентификатор (Не Строка)
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.провдок_ПроверенныеДокументы КАК провдок_ПроверенныеДокументы
|ПО УникальныйИдентификатор(Документ.Ссылка) = провдок_ПроверенныеДокументы.УИОбъекта
Прикрепленные файлы:
begemot; dsdred; +2 Ответить
9. dsdred 2718 12.01.23 12:39 Сейчас в теме
(8)Механизм хороший и вам уже пригодился. Это хорошо.
Я просто жду от него большего.
dim369; sandr13; +2 Ответить
11. mikl79 117 12.01.23 16:08 Сейчас в теме
спасибо за освещение
да механизм хороший, тоже пригодился
переносил из базы в базу через ком-соединение регистр сведений
сразу в запросе выбрал УИ, а так бы пришлось в выборке еще вызывать XMLЗначение
хотя по времени вышло одинаково
sandr13; Innuil; dima_home; dsdred; +4 Ответить
12. vladnet 359 13.01.23 09:44 Сейчас в теме
А ещё почему то нет возможности преобразовать строку в уид и в ссылку. Мне вот было бы это очень нужно. Но конечно даже это шаг вперёд просто можно было бы сразу про длиннее его сделать
13. dsdred 2718 13.01.23 10:24 Сейчас в теме
(12)согласен, было бы хорошо получать и ссылки в запросе.
Это позволило бы хранить данные в запросе минуя константы и прочие вещи.
15. dsdred 2718 23.05.23 15:22 Сейчас в теме
(14) Да, звучит хорошо.
16. fixin 4207 01.06.23 08:26 Сейчас в теме
а что значит, нельзя работать с представлением? Не совсем понял. Разве нельзя сравнивать это представление с строкой?
17. dsdred 2718 01.06.23 08:41 Сейчас в теме
(16) В запросе получив представление от УИ при сравнении со строкой увидим ошибку "Нельзя сравнивать поля неограниченной длины".
Если попробуем выразить в строку(36), увидим ошибку.
18. Akam 07.07.23 04:24 Сейчас в теме
не могу понять - и ПРЕДСТАВЛЕНИЕ как-то выводит "не такую" строку, что ли? Заменил
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ПодразделенияОрганизаций.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.ПодразделенияОрганизаций КАК ПодразделенияОрганизаций";
	МассивРезультат = Новый Массив;
	Результат = Запрос.Выполнить().Выбрать();
	Пока Результат.Следующий() Цикл
		НоваяЗапись = Новый Структура;
		НоваяЗапись.Вставить("ПодразделениеGUID", XMLСтрока(Результат.Ссылка));
		МассивРезультат.Добавить(НоваяЗапись);
	КонецЦикла;
Показать
на новое
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ПРЕДСТАВЛЕНИЕ(УникальныйИдентификатор(ПодразделенияОрганизаций.Ссылка)) КАК Ссылка
	|ИЗ
	|	Справочник.ПодразделенияОрганизаций КАК ПодразделенияОрганизаций";
	МассивРезультат = Новый Массив;
	Результат = Запрос.Выполнить().Выбрать();
	Пока Результат.Следующий() Цикл
		НоваяЗапись = Новый Структура;
		НоваяЗапись.Вставить("ПодразделениеGUID", Результат.Ссылка);
		МассивРезультат.Добавить(НоваяЗапись);
	КонецЦикла;
Показать
и после этого записываю в JSON (там еще в запросе данные берутся, но они к этому не имеют отношения)
	ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, , Истина);
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
	НастройкаСериализации = Новый НастройкиСериализацииJSON();
	НастройкаСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДата;
	НастройкаСериализации.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
	ЗаписатьJSON(ЗаписьJSON, МассивРезультат, НастройкаСериализации);
так вот в старом варианте отрабатывает, а в новом - "Ошибка при вызове метода контекста (ЗаписатьJSON)"
Хотя и там и там ПодразделениеGUID выдается как строка.
19. dsdred 2718 07.07.23 14:30 Сейчас в теме
(18) Проверил, работает.
Код который проверял:
	Запрос = Новый Запрос;
	Запрос.Текст = 		
    "ВЫБРАТЬ
    |    Ссылка КАК Ссылка
    |ИЗ
    |    Справочник.Товар";
    МассивРезультат = Новый Массив;
    Результат = Запрос.Выполнить().Выбрать();
    Пока Результат.Следующий() Цикл
        НоваяЗапись = Новый Структура;
        НоваяЗапись.Вставить("ТоварGUID", XMLСтрока(Результат.Ссылка));
        МассивРезультат.Добавить(НоваяЗапись);
    КонецЦикла;
	
	ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, , Истина);
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
    НастройкаСериализации = Новый НастройкиСериализацииJSON();
    НастройкаСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДата;
    НастройкаСериализации.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
    ЗаписатьJSON(ЗаписьJSON, МассивРезультат, НастройкаСериализации);
	                            
	iJSON = ЗаписьJSON.Закрыть();
	
	Запрос.Текст =
    "ВЫБРАТЬ
    |    ПРЕДСТАВЛЕНИЕ(УникальныйИдентификатор(Ссылка)) КАК Ссылка
    |ИЗ
    |    Справочник.Товар";
    МассивРезультат = Новый Массив;
    Результат = Запрос.Выполнить().Выбрать();
    Пока Результат.Следующий() Цикл
        НоваяЗапись = Новый Структура;
        НоваяЗапись.Вставить("ПодразделениеGUID", Результат.Ссылка);
        МассивРезультат.Добавить(НоваяЗапись);
    КонецЦикла;
	
	
	ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, , Истина);
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
    НастройкаСериализации = Новый НастройкиСериализацииJSON();
    НастройкаСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДата;
    НастройкаСериализации.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
    ЗаписатьJSON(ЗаписьJSON, МассивРезультат, НастройкаСериализации);
	                            
	iJSON = ЗаписьJSON.Закрыть();
Показать
Прикрепленные файлы:
20. Akam 09.07.23 11:14 Сейчас в теме
(19) Я точно также и делаю. В первом случае с XMLСтрока работает, так было и раньше до возможности получения уникального идентификатора в запросе. Так у меня сейчас и происходит. Я решил переписать с использованием новых возможностей, а не работает. Нашел Вашу статью - тоже не работает. Конечно у меня в коде есть закрытие записи JSON, но все не работает на предыдущей стадии - ошибка при ЗаписатьJSON.
Единственное что разницу увидел, то Вы пишете
 "ВЫБРАТЬ
    |    ПРЕДСТАВЛЕНИЕ(УникальныйИдентификатор(Ссылка)) КАК Ссылка
    |ИЗ
    |    Справочник.Товар";
, а не
 "ВЫБРАТЬ
    |    ПРЕДСТАВЛЕНИЕ(УникальныйИдентификатор(Товар.Ссылка)) КАК Ссылка
    |ИЗ
    |    Справочник.Товар КАК Товар";
Не пойму почему не получается. В МассивРезультат перед выполнением ЗаписатьJSON Структура и в ней ПодразделениеGUID типа Строка.
8.3.22.2106
21. dsdred 2718 09.07.23 11:45 Сейчас в теме
(20) я просто показал что проверил и все отрабатывает в 8.3.23 и 8.3.24. Видимо платформенный косяк.
22. Akam 09.07.23 12:16 Сейчас в теме
(21) А на 22 не пробовали что Вы написали? Эх, жаль, еще один косяк. Мелочь, а неприятно.
Еще есть косяк, что подписка на событие с 8.3.22 не отрабатывает когда источник определяемый в расширении тип, вот и бесит.
Ну ладно. Спасибо что попробовали!
23. dsdred 2718 09.07.23 12:25 Сейчас в теме
(22)на какой-то 8.3.22 проверял когда писал статью.
Я честно скажу я попробовал эту возможность и понял, что мне от нее пока толка нет. в работе ей не пользуюсь.
К сожалению фирма 1С как обычно, что то сделала, но толку от этого почти ноль...

По этому в статье я добавил "Вы этого хотели?"
Лично я хотел ни этого ))
24. supp 3 21.07.23 10:09 Сейчас в теме
Оставьте свое сообщение