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