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

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

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

Разбираем архитектуру компоновщика настроек

Динамический список в 1С:Предприятие 8.3 — это не просто таблица, а мощный механизм, построенный на базе Системы компоновки данных (СКД). Чтобы понять, почему Список.Отбор пуст, проанализируем структуру объекта КомпоновщикНастроек, который управляет поведением списка. В нем существует три независимых слоя (уровня) настроек:

  1. Настройки (Settings): Это базовый слой, который задается разработчиком в конфигураторе. Когда вы пишете в коде Список.Отбор, вы фактически обращаетесь к Список.КомпоновщикНастроек.Настройки.Отбор.
  2. Пользовательские настройки (UserSettings): Именно здесь живут изменения, внесенные пользователем через кнопку "Настроить список", быстрые фильтры или стандартные команды отбора. Этот слой накладывается поверх основных настроек.
  3. Фиксированные настройки (FixedSettings): Эти настройки устанавливаются только программно и не видны пользователю в окне настроек. Они имеют наивысший приоритет.

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

Способ 1: Получение настроек через ПользовательскиеНастройки

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


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

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

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

Способ 2: Использование метода ПолучитьИсполняемыеНастройкиКомпоновкиДанных

Если наша задача — получить финальный результат (то есть список всех условий, которые реально применяются к запросу динамического списка в данный момент), самым надежным методом будет ПолучитьИсполняемыеНастройкиКомпоновкиДанных(). Этот метод собирает "пирог" из всех трех слоев: фиксированных, основных и пользовательских настроек.

Рассмотрим, как это работает на практике. Важно помнить, что этот метод вызывается у элемента формы (таблицы), связанного с динамическим списком:


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

Преимущество этого метода заключается в том, что он учитывает даже сложные системные механизмы, такие как "Поиск по строке" (желтая панель поиска) или результаты Ctrl + F, которые технически могут не отображаться как стандартные элементы в коллекции ПользовательскиеНастройки.

Почему в старых статьях пишут Список.Отбор?

Разберем причину путаницы в учебных материалах. В платформе 1С 8.1 и в обычных формах 8.2 динамические списки работали на базе "Построителя запроса". Там коллекция отборов была плоской и прямой. С переходом на управляемые формы и СКД объект ДинамическийСписок стал гораздо сложнее.

Свойство Список.Отбор было сохранено разработчиками платформы для частичной обратной совместимости и быстрого доступа к "базовому" слою настроек. Если вы добавите отбор прямо в конфигураторе в свойствах списка, то Список.Отбор его покажет. Но всё, что происходит динамически в процессе работы пользователя, уходит в другие слои компоновщика.

Как правильно устанавливать отбор программно

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

  1. Найдите нужный элемент в Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.
  2. Если элемента нет — создайте его, обязательно указав связь с полем компоновки.
  3. Установите свойство РежимОтображения в значение БыстрыйДоступ или Авто, чтобы пользователь видел этот фильтр в интерфейсе.

Если же вы хотите установить "жесткое" ограничение, которое пользователь не сможет увидеть или отключить (например, фильтрация данных по текущему подразделению сотрудника), используйте Фиксированные настройки:


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

Подведем итоги

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

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

← На главную