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

28.11.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Значение(Тип("СправочникСсылка.Товары"), Строка(Новый УникальныйИдентификатор));  
КонецФункции

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

 

 

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

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

 

 

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

 

 

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

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

 

 

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

 

 

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

 

 

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

 

 

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

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

См. также

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

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

10000 руб.

02.09.2020    140672    772    391    

803

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

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    4054    bayselonarrend    18    

142

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

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    8880    dsdred    44    

123

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    17768    skovpin_sa    14    

102

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

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    21096    SeiOkami    46    

129

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

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    11569    YA_418728146    7    

154

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

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    7444    sebekerga    54    

102

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

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    19876    SeiOkami    31    

108
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. kser87 2453 12.01.23 11:33 Сейчас в теме
Интересно, как до разработчиков платформы дошла необходимость подобного? Допустим, с сообществом они не особо контактируют. Но ведь есть например Конвертация данных. неужели разрабы этой конфигурации ни разу не выдвигали никаких требований?
2. dsdred 3473 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" создаёшь с типом "Дополнение". И указываешь что оно зависимо от Базового расширения "Общий функционал".
Красиво и понятно.
Было бы.
user1300191; it_depDi; dsdred; +3 Ответить
3. SeiOkami 3482 12.01.23 11:57 Сейчас в теме
Полгода назад тоже делал обзор по эту возможность и её косяки: https://youtu.be/1rywI70iScc
abasovit; Dimka74; kamisov; json; dsdred; +5 Ответить
4. dsdred 3473 12.01.23 12:10 Сейчас в теме
(3)спасибо, вечером посмотрю.
7. WI_IL 124 12.01.23 12:32 Сейчас в теме
А выразить в строку представление нельзя интересно?
10. dsdred 3473 12.01.23 13:51 Сейчас в теме
(7)нельзя

Даже больше скажу это плохо кончится.
Прикрепленные файлы:
AleksAaron; Innuil; mikl79; +3 Ответить
5. dsdred 3473 12.01.23 12:22 Сейчас в теме
(3)Посмотрел. Видео полезное, но эксперимент некорректен.
На 13:22 в состовной тип добавляется Число, а на 16:08 в проверке отсекается Строка.
6. SeiOkami 3482 12.01.23 12:24 Сейчас в теме
(5) да, там в комментариях меня поправили, но ошибка всё равно одиаковая была) Даже если Строку число отсекать
8. sapervodichka 6865 12.01.23 12:34 Сейчас в теме
Я это в расширениях использую, где сложно составной тип указать. Связываю списки с регистрами расширений, где измерение регистра УИОбъекта имеет тип УникальныйИдентификатор (Не Строка)
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.провдок_ПроверенныеДокументы КАК провдок_ПроверенныеДокументы
|ПО УникальныйИдентификатор(Документ.Ссылка) = провдок_ПроверенныеДокументы.УИОбъекта
Прикрепленные файлы:
begemot; dsdred; +2 Ответить
9. dsdred 3473 12.01.23 12:39 Сейчас в теме
(8)Механизм хороший и вам уже пригодился. Это хорошо.
Я просто жду от него большего.
dim369; sandr13; +2 Ответить
11. mikl79 119 12.01.23 16:08 Сейчас в теме
спасибо за освещение
да механизм хороший, тоже пригодился
переносил из базы в базу через ком-соединение регистр сведений
сразу в запросе выбрал УИ, а так бы пришлось в выборке еще вызывать XMLЗначение
хотя по времени вышло одинаково
sandr13; Innuil; dima_home; dsdred; +4 Ответить
12. vladnet 366 13.01.23 09:44 Сейчас в теме
А ещё почему то нет возможности преобразовать строку в уид и в ссылку. Мне вот было бы это очень нужно. Но конечно даже это шаг вперёд просто можно было бы сразу про длиннее его сделать
13. dsdred 3473 13.01.23 10:24 Сейчас в теме
(12)согласен, было бы хорошо получать и ссылки в запросе.
Это позволило бы хранить данные в запросе минуя константы и прочие вещи.
15. dsdred 3473 23.05.23 15:22 Сейчас в теме
16. fixin 4263 01.06.23 08:26 Сейчас в теме
а что значит, нельзя работать с представлением? Не совсем понял. Разве нельзя сравнивать это представление с строкой?
17. dsdred 3473 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 3473 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 3473 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 3473 09.07.23 12:25 Сейчас в теме
(22)на какой-то 8.3.22 проверял когда писал статью.
Я честно скажу я попробовал эту возможность и понял, что мне от нее пока толка нет. в работе ей не пользуюсь.
К сожалению фирма 1С как обычно, что то сделала, но толку от этого почти ноль...

По этому в статье я добавил "Вы этого хотели?"
Лично я хотел ни этого ))
24. supp 3 21.07.23 10:09 Сейчас в теме
25. el_nov 10 28.11.23 20:02 Сейчас в теме
В функции ПолучитьУИБитойССылкиЗапросомНаСервере(БитаяСсылка)
УИ вычисляется в запросе, а возвращается Xml как в предыдущем примере
26. dsdred 3473 28.11.23 20:07 Сейчас в теме
(25) Действительно. Опечатка. Поправил.

Спасибо.
Оставьте свое сообщение