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