Как программно установить отбор и сортировку в динамическом списке по нажатию кнопки?

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

В практике разработки на платформе 1С:Предприятие часто встречаются ситуации, когда заказчику требуется максимальная простота интерфейса. Классический пример: руководитель хочет видеть "одну большую кнопку", которая сразу отфильтрует список документов по нужному статусу и отсортирует их, чтобы важные записи оказались наверху. При этом стандартные механизмы настройки списка («Ещё — Настроить список») могут казаться пользователю слишком сложными.

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

Постановка задачи

У нас есть динамический список (журнал документов, список справочника и т.д.). Требуется создать команду и кнопку на форме (для ускорения разработки полезно применять готовые модули для программного изменения форм), при нажатии на которую:

  1. Устанавливается отбор по конкретному полю (например, "СостояниеРемонта").
  2. Одновременно устанавливается сортировка по этому же (или другому) полю.

Решение 1: Административный подход (без программирования)

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

Алгоритм действий (для более продвинутых манипуляций можно использовать специальный редактор форм в режиме предприятия — есть готовая настройка условий и отборов без программирования):

  1. Запустите режим "1С:Предприятие" под учетной записью данного пользователя.
  2. В нужном списке откройте меню Ещё — Настроить список.
  3. Установите нужный отбор и на закладке "Сортировка" задайте порядок вывода.
  4. Нажмите "Завершить редактирование".

Платформа автоматически сохранит эти настройки для данного пользователя. Это самый быстрый способ, если логика не требует динамического переключения условий "на лету" (кстати, существуют способы сохранять настройки формы для всех пользователей через БСП). Однако, если нужна именно кнопка-переключатель, переходим к программному решению.

Решение 2: Программная реализация

Для программного управления списком на управляемой форме мы будем работать с объектом ДинамическийСписок (обычно реквизит формы называется Список). У него есть свойства, отвечающие за настройки Компоновки Данных (СКД). Чтобы упростить написание такого кода, можно использовать специальные обертки для программного создания СКД.

Для решения задачи нам понадобятся два свойства:

Давайте посмотрим на базовый код процедуры, которая выполняет оба действия. Обратите внимание, что мы работаем на клиенте.


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

Углубленный разбор и улучшение кода

Приведенный выше код работает, но он имеет существенный недостаток: использование метода Очистить(). Этот метод безвозвратно удаляет все настройки, которые пользователь мог установить вручную (например, отбор по дате или контрагенту). Это может вызвать раздражение пользователя.

Давайте усовершенствуем механизм. Мы сделаем кнопку "триггерной" (вкл/выкл) и будем управлять только конкретным элементом отбора и сортировки, не трогая остальные настройки пользователя.

Для этого нам понадобится использовать свойство кнопки Пометка (визуально показывает, нажата кнопка или нет) и идентификаторы настроек.

Рассмотрим улучшенный вариант кода:


&НаКлиенте
Процедура ОтборПоСтатусу(Команда)
    
    // Получаем кнопку, чтобы менять её пометку
    Кнопка = Элементы.Найти("ИмяВашейКнопкиНаФорме");
    Кнопка.Пометка = НЕ Кнопка.Пометка; // Инвертируем состояние
    
    ИмяПоля = "СостояниеРемонта";
    
    // --- РАБОТА С ОТБОРОМ ---
    
    // Ищем, есть ли уже наш программный отбор. 
    // Для надежности лучше использовать UserSettingID, но здесь рассмотрим поиск по полю.
    НашЭлементОтбора = Неопределено;
    Для Каждого Эл Из Список.Отбор.Элементы Цикл
        // Проверяем, является ли элемент отбором (не группой) и по нужному ли он полю
        Если ТипЗнч(Эл) = Тип("ЭлементОтбораКомпоновкиДанных") 
           И Строка(Эл.ЛевоеЗначение) = ИмяПоля Тогда
            НашЭлементОтбора = Эл;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Если Кнопка.Пометка Тогда
        // ВКЛЮЧАЕМ ОТБОР
        Если НашЭлементОтбора = Неопределено Тогда
            НашЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
            НашЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяПоля);
            НашЭлементОтбора.ВидСравнения  = ВидСравненияКомпоновкиДанных.НеРавно; // Как в примере автора
            НашЭлементОтбора.ПравоеЗначение = ВыданПокупателю(); 
        КонецЕсли;
        НашЭлементОтбора.Использование = Истина;
        
        // ВКЛЮЧАЕМ СОРТИРОВКУ
        Список.Порядок.Элементы.Очистить(); // Сортировку обычно лучше сбрасывать жестко
        ЭлементПорядка = Список.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
        ЭлементПорядка.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
        ЭлементПорядка.ТипУпорядочивания = ТипУпорядочиванияКомпоновкиДанных.Возрастание;
        
    Иначе
        // ВЫКЛЮЧАЕМ ОТБОР (снимаем галочку)
        Если НашЭлементОтбора <> Неопределено Тогда
            НашЭлементОтбора.Использование = Ложь;
        КонецЕсли;
        
        // СБРАСЫВАЕМ СОРТИРОВКУ (или возвращаем дефолтную)
        Список.Порядок.Элементы.Очистить();
        // Например, возвращаем сортировку по Дате
        ЭлементПорядка = Список.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
        ЭлементПорядка.Поле = Новый ПолеКомпоновкиДанных("Дата");
        ЭлементПорядка.ТипУпорядочивания = ТипУпорядочиванияКомпоновкиДанных.Убывание;
        
    КонецЕсли;
    
КонецПроцедуры

Ключевые моменты реализации

Давайте разберем важные детали, которые мы использовали в коде:

  1. Типы данных СКД: Мы используем типы ЭлементОтбораКомпоновкиДанных и ЭлементПорядкаКомпоновкиДанных. Это специальные объекты платформы, управляющие представлением данных.
  2. ПолеКомпоновкиДанных: Конструктор Новый ПолеКомпоновкиДанных("Имя") обязателен. Передавать просто строку с именем поля в свойства ЛевоеЗначение или Поле нельзя — платформа выдаст ошибку несоответствия типов.
  3. Интерактивность: Использование Кнопка.Пометка дает пользователю четкий сигнал: фильтр сейчас активен. Это повышает удобство работы (юзабилити).

Влияние на производительность

При добавлении сортировки, особенно по неиндексированным полям (например, строковым комментариям или сложным вычисляемым полям), открытие списка может замедлиться при большом объеме базы данных.

Рекомендация: Если поле СостояниеРемонта является ссылкой на перечисление или справочник, сортировка будет работать достаточно быстро. Старайтесь избегать сортировок по строкам неограниченной длины.

Альтернатива: Условное оформление

Иногда пользователю не нужно скрывать "лишние" документы (поможет модуль управления отображением данных в списках), а нужно просто выделить важные. В этом случае вместо манипуляций с Список.Отбор можно использовать Список.УсловноеОформление. Программно добавив элемент оформления, вы можете покрасить строки с нужным статусом в красный цвет или жирный шрифт, что тоже решит задачу привлечения внимания, но оставит остальные документы доступными для просмотра.

← На главную