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