При разработке документов, помощников заполнения и спецформатов калькуляции часто возникает задача ограничить выбор элементов справочника Номенклатура конкретной группой (или несколькими определенными папками). Это необходимо для того, чтобы пользователи не выбирали ошибочные позиции из сторонних разделов справочника.
Разберем детально несколько проверенных способов решения этой задачи на платформе 1С:Предприятие 8.3 (Управляемые формы).
Разберем ситуацию, когда список допустимой номенклатуры или разрешенных групп заранее формируется программно (например, запросом) и передается в параметры открываемой формы выбора. В этом случае мы перехватываем событие НачалоВыбора у элемента формы, отменяем стандартное поведение платформы и формируем свои настройки.
Проанализируем пример кода для обработки события НачалоВыбора:
&НаКлиенте
Процедура НоменклатураНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Создаем фиксированные настройки компоновки данных
ФиксНастройки = Новый НастройкиКомпоновкиДанных;
// Добавляем элемент отбора
Отбор = ФиксНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
Отбор.ПравоеЗначение = СписокНоменклатуры; // Предварительно подготовленный массив или список значений
Отбор.Использование = Истина;
Отбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
// Передаем фиксированные настройки в параметры формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ФиксированныеНастройки", ФиксНастройки);
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры
В этом примере установка режима отображения в значение Недоступный запрещает пользователю случайно или намеренно отключить наложенный фильтр в окне выбора.
Если требуется установить прямой фильтр по родителю (конкретной группе), разберем более простой способ передать структуру параметров в процедуру ОткрытьФорму.
Рассмотрим следующий пример:
&НаКлиенте
Процедура НоменклатураПростаяНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ПараметрыОтбора = Новый Структура("Родитель", РазрешеннаяГруппа);
ПараметрыФормы = Новый Структура("Отбор", ПараметрыОтбора);
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры
Важное замечание: стандартный параметр формы Отбор накладывает условие строгого равенства по указанному реквизиту (в данном случае Родитель = РазрешеннаяГруппа). Если целевая группа содержит внутри себя другие подгруппы, элементы из этих подгрупп при прямом отборе по родителю отображаться не будут. Для полноценного иерархического отбора со всеми вложенными уровнями следует использовать первый способ (через компоновку данных) либо менять запрос динамического списка.
Посмотрим на платформенный механизм, который позволяет обойтись вообще без написания кода в событии НачалоВыбора. Это настраивается напрямую в Конфигураторе или программно при создании формы.
ПараметрыВыбора).Отбор.Родитель и укажем необходимую группу или массив разрешенных групп.Если целевая группа меняется динамически в зависимости от другого поля формы, проанализируем свойство Связи параметров выбора (СвязиПараметровВыбора). В нем настраивается связь между параметром Отбор.Родитель и соответствующим реквизитом формы. Платформа будет автоматически фильтровать список номенклатуры как в форме выбора, так и при вводе по строке.
В случаях, когда форму выбора нельзя модифицировать или в ней требуется сохранить полную видимость дерева справочника, логику ограничения переносят в событие ОбработкаВыбора.
Рассмотрим, как проверить выбранное значение на принадлежность к группе с учетом всех уровней иерархии с помощью метода ПринадлежитЭлементу():
&НаКлиенте
Процедура НоменклатураОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
Если ЗначениеЗаполнено(ВыбранноеЗначение) И Не ВыбранноеЗначение.ПринадлежитЭлементу(РазрешеннаяГруппа) Тогда
СтандартнаяОбработка = Ложь;
ПоказатьПредупреждение(, "Выбор ограничен! Выберите номенклатуру из группы 'Пример 1'.");
КонецЕсли;
КонецПроцедуры
Для предотвращения нежелательного выбора самих папок вместо элементов также следует убедиться, что у элемента формы или в параметрах формы установлен режим ВыборГруппИЭлементов.Элементы.