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