Как программно установить отбор в списке документов через расширение

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

При разработке расширений для типовых конфигураций, таких как Управление торговлей 11.4, ERP или Комплексная автоматизация, часто возникает задача ограничить видимость данных в списках. Например, нам нужно, чтобы при открытии формы списка документов «Расходный кассовый ордер» пользователь видел только те записи, сумма которых превышает определенный порог. В этой статье мы подробно разберем, как правильно реализовать такой функционал, проанализируем типичные ошибки начинающих разработчиков и рассмотрим наиболее эффективные методы управления динамическими списками.

Разбор типичной ошибки: почему новый объект настроек не работает

Рассмотрим ситуацию, с которой часто сталкиваются программисты. Пытаясь установить отбор, разработчик создает в расширении процедуру-перехватчик ПриСозданииНаСервереПосле и пишет код, создающий новый объект НастройкиКомпоновкиДанных. Давайте выясним причину, по которой такой подход не дает результата.

Проблема заключается в том, что когда мы пишем Список = Новый НастройкиКомпоновкиДанных, мы создаем в памяти абсолютно новый, независимый объект, который никак не связан с тем динамическим списком, который отображается на форме. Даже если мы заполним этот объект правильными полями и видами сравнения, сама форма о них «не узнает», так как ее основной реквизит продолжает использовать свои старые настройки.

Важный момент: динамический список на форме — это уже существующий объект (реквизит формы), у которого есть свойство Отбор. Именно с этим свойством и нужно работать напрямую.

Правильный способ установки отбора через реквизит формы

Для того чтобы отбор заработал, нам необходимо обратиться к конкретному реквизиту формы, который является динамическим списком. В типовых конфигурациях имя этого реквизита часто совпадает с именем списка (например, Список или РасходныеКассовыеОрдера).

Разберем по шагам правильный алгоритм действий в расширении:

  1. Создаем процедуру ПриСозданииНаСервере с типом вызова «После».
  2. Обращаемся к коллекции элементов отбора динамического списка.
  3. Добавляем новый элемент и настраиваем его параметры: левое значение (поле), вид сравнения и правое значение.

Посмотрим на пример работающего кода:


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

Использование механизмов БСП для установки отбора

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

Проанализируем использование процедуры УстановитьЭлементОтбораДинамическогоСписка из общего модуля ОбщегоНазначенияКлиентСервер. Рассмотрим пример:


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

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

Установка «жесткого» отбора через фиксированные настройки

Иногда требуется установить такой отбор, который пользователь вообще не сможет увидеть или сбросить через меню «Настроить список». В этом случае обычное свойство Отбор не совсем подходит, так как оно смешивается с пользовательскими фильтрами.

Выясним, как использовать ФиксированныеНастройки. Отборы, помещенные в эту коллекцию, работают параллельно с пользовательскими. То есть, если мы зафиксируем отбор по сумме > 100, а пользователь сам поставит фильтр по конкретному контрагенту, система покажет документы, удовлетворяющие обоим условиям одновременно.

Рассмотрим пример реализации через фиксированные настройки:


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

Нюансы производительности и индексации

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

Для оптимизации работы списка рекомендуем:

Итоги

Мы рассмотрели несколько способов программного управления фильтрами в динамических списках. Подведем итоги: для простых задач в расширении достаточно использовать метод Добавить() в коллекции Список.Отбор.Элементы. Для более профессиональной разработки в типовых конфигурациях лучше применять методы БСП, а для создания скрытых от пользователя ограничений — Фиксированные настройки компоновщика данных. Помните, что правильное обращение к реквизитам формы — это залог стабильной работы вашего расширения.

← На главную