Как программно установить отбор в динамическом списке по кнопке в 1С:Управляемые формы

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке пользовательских интерфейсов в 1С на управляемых формах часто возникает задача быстрой фильтрации данных в динамическом списке. Например, требуется вывести на форму списка панель кнопок для быстрого переключения статусов документов или задач (например, «В работе», «Принят в ремонт», «Выполнен»).

В этой статье мы подробно разберем, как реализовать программную установку и сброс отбора динамического списка при нажатии на кнопку, какие нюансы работы на клиенте важно учитывать и как избежать типичных ошибок платформы 1С:Предприятие 8.3.

Анализ задачи и частые ошибки начинающих разработчиков

Рассмотрим типовую ситуацию: в конфигурации есть документ Ремонт с формой списка. В таблице отображается реквизит СтатусРемонта, тип которого — ПеречислениеСсылка.СтатусВыполненияРаботПеречисление. Требуется настроить команду формы, которая при нажатии будет оставлять в списке только строки со значением ПринятВРемонт.

При реализации подобного функционала разработчики часто сталкиваются со следующими проблемами:

  1. Обращение к менеджеру перечислений на клиенте: конструкция вида Перечисления.СтатусВыполненияРаботПеречисление.ПринятВРемонт не работает в клиентских процедурах с директивой компиляции &НаКлиенте, так как глобальная коллекция Перечисления доступна только на сервере.
  2. Ошибки в имени типа при использовании функции ПредопределенноеЗначение: имя типа метаданных необходимо указывать в единственном числе (Перечисление, а не Перечисления).
  3. Дублирование элементов отбора: простое добавление нового элемента через метод Список.Отбор.Элементы.Добавить() при каждом клике создает повторяющиеся условия. Это приводит к ошибке платформы: «Невозможно применить фиксированные настройки. Пересекаются элементы отбора».
  4. Удаление пользовательских отборов: вызов метода Список.Отбор.Элементы.Очистить() удаляет не только фильтры разработчика, но и настройки, которые пользователь мог установить вручную через стандартное окно настройки списка.

Способ 1. Корректная установка отбора на чистом коде платформы (без БСП)

Проанализируем правильный алгоритм работы с коллекцией ЭлементыОтбораКомпоновкиДанных. Чтобы избежать ошибки пересечения условий, перед добавлением элемента отбора необходимо проверить, существует ли он уже в списке. Если элемент найден, мы просто меняем его правое значение и включаем использование, а если не найден — создаем новый.

Разберем универсальную клиентскую процедуру для модуля формы, которую можно вызывать из любых кнопок отбора:


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

КонецПроцедуры

Теперь рассмотрим, как привязать эту процедуру к командам кнопок на форме.

Обратите внимание на получение значения перечисления на клиенте: мы используем функцию ПредопределенноеЗначение, где путь указывается строкой в единственном числе: "Перечисление.ИмяПеречисления.ИмяЗначения".


&НаКлиенте
Процедура Ком_ПринятВР(Команда)
    
    Значение = ПредопределенноеЗначение("Перечисление.СтатусВыполненияРаботПеречисление.ПринятВРемонт");
    УстановитьОтборСписка("СтатусРемонта", Значение, Истина);
    
КонецПроцедуры

&НаКлиенте
Процедура Ком_СброситьОтбор(Команда)
    
    // Для сброса отбора достаточно отключить признак использования
    УстановитьОтборСписка("СтатусРемонта", Неопределено, Ложь);
    
КонецПроцедуры

Способ 2. Реализация через функции Библиотеки Стандартных Подсистем (БСП)

Если ваша конфигурация разработана на основе БСП или содержит подсистему базовой функциональности, писать собственный цикл поиска элементов отбора не требуется. В составе БСП есть готовый общий модуль ОбщегоНазначенияКлиентСервер.

Посмотрим на пример использования метода УстановитьЭлементОтбораДинамическогоСписка:


&НаКлиенте
Процедура Ком_ПринятВР(Команда)
    
    Значение = ПредопределенноеЗначение("Перечисление.СтатусВыполненияРаботПеречисление.ПринятВРемонт");
    
    ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
        Список,                                          // Динамический список формы
        "СтатусРемонта",                                 // Имя поля компоновки данных
        Значение,                                        // Правое значение
        ВидСравненияКомпоновкиДанных.Равно,             // Вид сравнения
        "Отбор по статусу документа",                   // Представление отбора
        Истина                                           // Использование
    );
    
КонецПроцедуры

Преимущество метода БСП заключается в том, что он автоматически проверяет коллекцию отборов, управляет пользовательскими представлениями и корректно перезаписывает существующие параметры отбора без риска возникновения ошибок пересечения настроек.

Способ 3. Выполнение отбора на сервере формы

В некоторых случаях логика фильтрации требует получения сложных серверных данных или работы с типами, недоступными на стороне клиента. В такой ситуации команду кнопки можно направить на серверную процедуру.

Рассмотрим, как выглядит установка отбора в серверном контексте:


&НаКлиенте
Процедура Ком_ПринятВР(Команда)
    УстановитьОтборПоСтатусуНаСервере(Перечисления.СтатусВыполненияРаботПеречисление.ПринятВРемонт);
КонецПроцедуры

&НаСервере
Процедура УстановитьОтборПоСтатусуНаСервере(ЗначениеСтатуса)
    
    ПолеОтбора = Новый ПолеКомпоновкиДанных("СтатусРемонта");
    ЭлементОтбора = Неопределено;
    
    Для Каждого Элемент Из Список.Отбор.Элементы Цикл
        Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") 
            И Элемент.ЛевоеЗначение = ПолеОтбора Тогда
            ЭлементОтбора = Элемент;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Если ЭлементОтбора = Неопределено Тогда
        ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    КонецЕсли;
    
    ЭлементОтбора.ЛевоеЗначение  = ПолеОтбора;
    ЭлементОтбора.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = ЗначениеСтатуса;
    ЭлементОтбора.Использование  = Истина;

КонецПроцедуры

В серверном контексте обращение к Перечисления.СтатусВыполненияРаботПеречисление.ПринятВРемонт выполняется напрямую без необходимости использовать функцию ПредопределенноеЗначение.

Рекомендации по организации интерфейса

Создание большого количества отдельных кнопок под каждый статус может перегрузить командную панель формы. Выделим альтернативные подходы к организации быстрых фильтров:

  1. Переключатель (Тумблер): добавьте на форму реквизит ОтборСтатус с типом перечисления и вынесите его как элемент с видом Поле переключателя или Поле выбора. В обработчике события ПриИзменении вызывайте процедуру установки отбора.
  2. Штатные быстрые отборы: в свойствах реквизита формы Список откройте Настройки компоновки данных, добавьте нужный отбор в список Пользовательские настройки и установите флаг Быстрый доступ. В этом случае платформа автоматически сформирует удобную панель отборов над списком без написания программного кода.
← На главную