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