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