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