При разработке внешних отчетов и обработок в конфигурациях на обычных формах (таких как 1С:Управление торговлей 10.3, Управление производственным предприятием 1.3 или Комплексная автоматизация 1.1) часто возникает задача ограничить выбор свойств объектов. Например, нам требуется предоставить пользователю возможность выбирать свойства (элементы плана видов характеристик) исключительно для справочника Номенклатура, скрыв все остальные свойства (контрагентов, договоров и т.д.).
В этой статье мы подробно разберем, почему стандартные механизмы отбора в свойствах реквизита не всегда работают на обычных формах, и рассмотрим правильный программный способ решения этой задачи.
В управляемом интерфейсе (начиная с платформы 8.2 и 8.3) большинство задач фильтрации данных решается простой настройкой свойств пути к данным, связей параметров выбора или параметров выбора непосредственно в конфигураторе. Однако в обычных формах этот функционал ограничен.
Если мы попытаемся настроить отбор стандартными методами, мы столкнемся со следующими проблемами:
ПараметрыВыбора и СвязиПараметровВыбора в палитре свойств реквизита на обычных формах не обладают гибкостью управляемых форм и часто возвращают пустые значения.СвойстваНоменклатуры.Отбор) вызывает ошибку выполнения: «Поле объекта не обнаружено (Отбор)», поскольку у ссылки ПВХ нет свойства «Отбор».Давайте пошагово разберем, как правильно реализовать программное ограничение списка выбора.
Рассмотрим базовый сценарий: нам нужно открыть форму выбора плана видов характеристик СвойстваОбъектов и показать там только те свойства, у которых реквизит НазначениеСвойства равен значению Справочник_Номенклатура.
Для реализации этого решения нам понадобится перехватить событие начала выбора у поля ввода. Выполним следующие шаги:
Шаг 1. Откроем форму нашего отчета или обработки в конфигураторе, выберем нужное поле ввода (в котором выбирается свойство) и перейдем в его свойства.
Шаг 2. Найдем событие НачалоВыбора и создадим для него процедуру-обработчик на клиенте.
Шаг 3. Пропишем внутри обработчика следующий программный код:
Процедура СвойстваНоменклатурыНачалоВыбора(Элемент, СтандартнаяОбработка)
// Отменяем стандартное открытие формы выбора платформой
СтандартнаяОбработка = Ложь;
// Получаем форму выбора плана видов характеристик программно
ФормаВыбора = ПланыВидовХарактеристик.СвойстваОбъектов.ПолучитьФормуВыбора("ФормаВыбора", Элемент);
// Обращаемся к отбору табличного поля (списка) на форме выбора
// Название списка по умолчанию в ПВХ — "ПланВидовХарактеристикСписок"
ЭлементОтбора = ФормаВыбора.ПланВидовХарактеристикСписок.Отбор.НазначениеСвойства;
// Настраиваем параметры отбора
ЭлементОтбора.Значение = ПланыВидовХарактеристик.НазначенияСвойствКатегорийОбъектов.Справочник_Номенклатура;
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
// КРИТИЧЕСКИ ВАЖНО: Включаем использование отбора, иначе он не применится!
ЭлементОтбора.Использование = Истина;
// По желанию: запрещаем пользователю отключать или изменять этот отбор в форме выбора
ФормаВыбора.ЭлементыФормы.ПланВидовХарактеристикСписок.НастройкаОтбора.НазначениеСвойства.Доступность = Ложь;
// Открываем форму выбора
ФормаВыбора.Открыть();
КонецПроцедуры
В этом коде ключевым моментом является установка свойства Использование = Истина. Без этой строки платформа проигнорирует переданное значение отбора и выведет весь список свойств объектов, включая свойства контрагентов, складов и документов.
В реальных бизнес-задачах конфигурации УТ 10.3 свойства редко назначаются сразу всей номенклатуре. Чаще всего свойства привязываются к конкретным папкам (группам) номенклатуры. Например, свойство «Размер обуви» актуально только для группы «Обувь», а «Объем памяти» — для группы «Электроника».
Связь свойств с группами номенклатуры хранится не в самом плане видов характеристик, а в регистре сведений НазначенияСвойствОбъектов. Если мы применим простое решение №1, то пользователь не увидит специфические свойства, закрепленные за конкретными папками.
Давайте разберем более сложный алгоритм, который определяет выбранную в отчете группу номенклатуры, собирает все родительские группы (так как свойства наследуются по иерархии вниз) и выводит только актуальные свойства.
Предположим, что на форме нашего внешнего отчета есть реквизит ГруппаНоменклатуры. Тогда код обработчика начала выбора будет выглядеть следующим образом:
Процедура СвойстваНоменклатурыНачалоВыбора(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// 1. Формируем список групп для поиска (с учетом иерархии родителей)
СписокНазначений = Новый СписокЗначений;
Если ЗначениеЗаполнено(ГруппаНоменклатуры) Тогда
СписокНазначений.Добавить(ГруппаНоменклатуры);
// Рекурсивно поднимаемся вверх по дереву групп номенклатуры
ТекущийРодитель = ГруппаНоменклатуры.Родитель;
Пока ЗначениеЗаполнено(ТекущийРодитель) Цикл
СписокНазначений.Добавить(ТекущийРодитель);
ТекущийРодитель = ТекущийРодитель.Родитель;
КонецЦикла;
КонецЕсли;
// 2. Выбираем свойства запросом из регистра сведений "НазначенияСвойствОбъектов"
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| СвойстваОбъектов.Ссылка КАК Ссылка
|ИЗ
| ПланВидовХарактеристик.СвойстваОбъектов КАК СвойстваОбъектов
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НазначенияСвойствОбъектов КАК НазначенияСвойствОбъектов
| ПО НазначенияСвойствОбъектов.Свойство = СвойстваОбъектов.Ссылка
|ГДЕ
| СвойстваОбъектов.НазначениеСвойства = &НазначениеНоменклатура
| И (НазначенияСвойствОбъектов.Объект ЕСТЬ NULL
| ИЛИ НазначенияСвойствОбъектов.Объект В (&СписокНазначений))";
Запрос.УстановитьПараметр("НазначениеНоменклатура", ПланыВидовХарактеристик.НазначенияСвойствКатегорийОбъектов.Справочник_Номенклатура);
Запрос.УстановитьПараметр("СписокНазначений", СписокНазначений);
Выгрузка = Запрос.Выполнить().Выгрузить();
МассивРазрешенныхСвойств = Выгрузка.ВыгрузитьКолонку("Ссылка");
СписокРазрешенныхСвойств = Новый СписокЗначений;
СписокРазрешенныхСвойств.ЗагрузитьЗначения(МассивРазрешенныхСвойств);
// 3. Открываем форму выбора и накладываем отбор "В списке" по ссылкам ПВХ
ФормаВыбора = ПланыВидовХарактеристик.СвойстваОбъектов.ПолучитьФормуВыбора("ФормаВыбора", Элемент);
ОтборСсылка = ФормаВыбора.ПланВидовХарактеристикСписок.Отбор.Ссылка;
ОтборСсылка.ВидСравнения = ВидСравнения.ВСписке;
ОтборСсылка.Значение = СписокРазрешенныхСвойств;
ОтборСсылка.Использование = Истина;
ФормаВыбора.Открыть();
КонецПроцедуры
Этот способ является наиболее профессиональным и юзабильным для конечного пользователя, так как он динамически сужает список доступных свойств до тех, которые действительно имеют смысл для выбранного сегмента номенклатуры.
При работе с планами видов характеристик на обычных формах всегда помните следующие правила:
Использование = Истина. По умолчанию в платформе 1С новые параметры отбора создаются выключенными.СтандартнаяОбработка = Ложь) — единственный надежный способ внедрить сложную логику фильтрации при интерактивном выборе.ПланВидовХарактеристикСписок, а для справочников — СправочникСписок.Используя предложенные варианты программного кода, вы сможете легко и безошибочно настроить любые сложные отборы в своих внешних отчетах и обработках.