Как программно добавить условие ИЛИ в отбор динамического списка 1С?

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

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

Постановка задачи и базовые принципы

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

  1. Поле ОтправительСлужбаДоставки равно текущей организации.
  2. Поле ПолучательСлужбаДоставки равно текущей организации.
  3. Поле ПолучательПлатежа равно текущей организации.

Для реализации такой логики в управляемых формах используется объект КомпоновщикНастроек, а именно коллекция Отбор. По умолчанию все элементы в ней соединяются логическим «И». Чтобы изменить это, мы должны создать специальный объект типа ГруппаЭлементовОтбораКомпоновкиДанных.

Пошаговая реализация программного отбора

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

Проанализируем структуру кода:


&НаКлиенте
Процедура УстановитьПараметрыОтбораПользователя()
    // Получаем коллекцию элементов отбора динамического списка
    ЭлементыОтбора = Список.Отбор.Элементы;
    ЭлементыОтбора.Очистить();

    Если Не Организация.Пустая() Тогда
        // 1. Создаем группу компоновки с типом "ГруппаИЛИ"
        ГруппаКомпоновкиОтбор = ЭлементыОтбора.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
        ГруппаКомпоновкиОтбор.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
        ГруппаКомпоновкиОтбор.Использование = Истина;

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

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

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

Важный момент: обратите внимание, что мы добавляем новые элементы не напрямую в Список.Отбор.Элементы, а в коллекцию ГруппаКомпоновкиОтбор.Элементы. Это критически важно для того, чтобы условия сгруппировались по правилу «ИЛИ».

Почему отбор может не работать? Разбор причин

Если вы написали код, но список документов не изменился или выдает ошибку, проанализируем ситуацию по шагам.

1. Проверка доступности полей

Программный отбор можно установить только по тем полям, которые «видит» система компоновки данных. Чтобы убедиться, что поле ПолучательПлатежа доступно, воспользуйтесь отладчиком. Посмотрите значение свойства: Список.Отбор.ДоступныеПоляОтбора.Элементы. Если вашего поля нет в этом списке, 1С проигнорирует попытку фильтрации.

Причиной отсутствия поля часто бывает использование произвольного запроса в динамическом списке, где поле просто не выбрано или ему назначен другой псевдоним (через КАК). В этом случае в Новый ПолеКомпоновкиДанных("...") нужно передавать именно имя псевдонима из запроса.

2. Конфликт типов данных

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

3. Фиксированные настройки против пользовательских

Код Список.Отбор.Элементы работает с пользовательскими настройками. Если пользователь самостоятельно зайдет в меню «Настроить список» и установит там свои фильтры, они могут вступить в конфликт с программными. Если вы хотите «жестко» закрепить отбор, чтобы пользователь не мог его отключить, следует использовать ФиксированныеНастройки:


// Пример установки фиксированного отбора (фрагмент)
ФиксированныеНастройки = Список.КомпоновщикНастроек.ФиксированныеНастройки;
Группа = ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
// ... дальнейшая настройка аналогична

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

Оптимизация и производительность

Когда мы добавляем несколько условий через «ИЛИ», нагрузка на базу данных возрастает. Выясним, как это влияет на скорость работы. Если в таблице документов сотни тысяч записей, поиск по неиндексированным полям приведет к значительному замедлению открытия формы.

Рекомендация: Убедитесь, что для реквизитов ОтправительСлужбаДоставки, ПолучательСлужбаДоставки и ПолучательПлатежа в конфигураторе установлено свойство Индексировать. Это позволит СУБД быстро находить нужные строки без полного сканирования таблицы.

Дополнительные проверки при инициализации

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


Организация = Пользователи.ПолучитьЗначениеПоУмолчанию(ПараметрыСеанса.ТекущийПользователь, "ОсновнаяОрганизация");

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

Подводя итог: для корректной работы сложного отбора в 1С необходимо четко соблюдать иерархию элементов компоновки данных, следить за соответствием типов переменных и обеспечивать наличие необходимых индексов в базе данных. Программное управление группой «ИЛИ» — это мощный инструмент, позволяющий сделать интерфейс системы максимально удобным и персонализированным для каждого пользователя.

← На главную