В процессе разработки на платформе 1С:Предприятие 8 часто возникает необходимость фильтрации данных в списках. Одной из специфических проблем, с которой сталкиваются разработчики при поддержке или разработке конфигураций на обычных формах, является ограничение работы с типом данных Уникальный идентификатор (UUID). Попытка установить отбор с видом сравнения ВСписке для такого поля приводит к ошибке: «Ошибка при установке значения атрибута контекста (ВидСравнения) по причине: Недопустимый тип сравнения».
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем ограничения платформы и рассмотрим несколько эффективных способов решения этой задачи.
Разберем ситуацию с технической стороны. Начиная с версии платформы 8.3.12, разработчики 1С расширили возможности работы с типом Уникальный идентификатор в языке запросов. Теперь в запросах можно использовать оператор В для массивов UUID, что значительно упростило жизнь. Однако эти изменения практически не коснулись объектной модели обычных форм.
Объект Отбор в динамических списках обычных форм жестко завязан на внутренние реестры типов метаданных. Для системы «обычного» интерфейса тип Уникальный идентификатор до сих пор считается атомарным типом, который поддерживает только простейшие операции сравнения: Равно и Не равно. Вид сравнения ВСписке для него попросту не зарегистрирован в реестре допустимых типов самого объекта метаданных в рамках старой модели форм. Даже если версия вашей платформы — 8.3.13 или выше, программный интерфейс Отбор в обычных формах остается в рамках ограничений обратной совместимости.
Рассмотрим типичный код, который вызывает ошибку:
Форма = РегистрыСведений.Спецификации.ПолучитьФормуСписка();
Форма.РежимВыбора = Истина;
СписокУИД = Новый СписокЗначений;
// Допустим, мы заполнили список значениями типа УникальныйИдентификатор
СписокУИД.Добавить(Новый УникальныйИдентификатор("..."));
ОтборПоПолю = Форма.Отбор.Найти("ИдентификаторОбъекта");
// На следующей строке возникнет ошибка: Недопустимый тип сравнения
ОтборПоПолю.ВидСравнения = ВидСравнения.ВСписке;
ОтборПоПолю.Значение = СписокУИД;
ОтборПоПолю.Использование = Истина;
Проанализируем самый надежный способ обхода ограничения, который часто выбирают опытные разработчики. Если платформа не позволяет наложить сложный отбор на стандартную форму списка, мы можем заменить отображение данных. Вместо использования ФормаСписка регистра, мы создаем общую форму или произвольную форму, на которую помещаем элемент управления ТаблицаЗначений.
Алгоритм действий следующий:
ПриОткрытии или при нажатии кнопки фильтра выполняем запрос к регистру сведений.ГДЕ УИД В (&МассивУИД), так как язык запросов это позволяет.Пример реализации запроса для такой формы:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Спецификации.Период,
| Спецификации.Номенклатура,
| Спецификации.УникальныйИдентификатор
|ИЗ
| РегистрСведений.Спецификации КАК Спецификации
|ГДЕ
| Спецификации.УникальныйИдентификатор В (&МассивУИД)";
Запрос.УстановитьПараметр("МассивУИД", МассивНужныхИдентификаторов);
ТЗ_Результат = Запрос.Выполнить().Выгрузить();
// Далее загружаем ТЗ_Результат в элемент формы ТабличноеПоле
Этот метод полностью решает проблему визуализации данных, хотя и требует создания дополнительного интерфейсного объекта.
Выясним, как можно использовать стандартные механизмы отбора, если нам критически важно остаться в рамках стандартной формы списка. Платформа 1С отлично работает с отбором ВСписке для строковых данных.
Мы можем модифицировать структуру регистра сведений, добавив дополнительный реквизит (или измерение), например, УникальныйИдентификаторСтрока с типом Строка(36).
Важный нюанс: Чтобы поиск и отбор по этому полю работали быстро, для реквизита обязательно нужно установить свойство Индексировать.
Для автоматизации заполнения этого поля пропишем код в модуле набора записей регистра сведений:
Процедура ПередЗаписью(Отказ, Замещение)
Для Каждого Запись Из ЭтотОбъект Цикл
Запись.УникальныйИдентификаторСтрока = Строка(Запись.УникальныйИдентификатор);
КонецЦикла;
КонецПроцедуры
Теперь в форме списка вы сможете устанавливать отбор по строковому представлению UUID. Система воспримет это как обычную строку и позволит использовать вид сравнения ВСписке без каких-либо ошибок.
Если ваша конфигурация позволяет использовать элементы управляемого функционала (или вы работаете в режиме совместимости, позволяющем настраивать динамические списки), разберем вариант с использованием Произвольного запроса в свойствах списка.
В настройках динамического списка (даже в некоторых версиях обычных форм, если используется расширение подсистемы компоновки данных) можно указать текст запроса. В тексте запроса мы можем заранее предусмотреть параметр:
ВЫБРАТЬ * ИЗ РегистрСведений.МойРегистр ГДЕ УникальныйИдентификатор В (&СписокДляОтбора)
В программном коде формы достаточно будет установить значение параметра:
СправочникСписок.Параметры.УстановитьЗначениеПараметра("СписокДляОтбора", НужныйМассив);
Подведем итоги. Ошибка при использовании отбора по UUID в обычных формах — это архитектурное ограничение старой модели объектов 1С. Для его преодоления мы рекомендуем:
Использование данных методов позволит вам избежать системных ошибок и обеспечит корректную работу пользователей с реестрами данных.