При разработке на платформе 1С:Предприятие 8.3 программисты часто сталкиваются со стандартным поведением системы: при передаче структуры в параметре Отбор функции ОткрытьФорму все условия объединяются по логическому «И». Однако в реальных бизнес-задачах, например, при выборе ресурсных спецификаций в ERP, часто требуется отобразить записи, которые соответствуют либо конкретной номенклатуре, либо определенному виду номенклатуры. Рассмотрим подробнее, как обойти ограничение «И» и реализовать гибкий фильтр.
Разберем самый простой и быстрый в реализации способ. Если нам нужно показать записи, подходящие под условие «А» или условие «Б», мы можем сначала выполнить запрос к базе данных, получить список подходящих ссылок и передать их в форму выбора.
Проанализируем ситуацию на примере поиска спецификаций. Сначала создадим функцию на сервере, которая соберет нужные нам данные:
&НаСервереБезКонтекста
Функция ПолучитьСпецификацииПоНоменклатуре(Номенклатура)
ТекстЗапроса =
"ВЫБРАТЬ
| РесурсныеСпецификации.Ссылка КАК Ссылка
|ИЗ
| Справочник.РесурсныеСпецификации КАК РесурсныеСпецификации
|ГДЕ
| (РесурсныеСпецификации.ОсновноеИзделиеНоменклатура = &Номенклатура
| ИЛИ РесурсныеСпецификации.ОсновноеИзделиеВидНоменклатуры = &ВидНоменклатуры)
| И РесурсныеСпецификации.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыСпецификаций.Действует)";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Запрос.УстановитьПараметр("ВидНоменклатуры", Номенклатура.ВидНоменклатуры);
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецФункции
После того как массив ссылок получен, мы вызываем форму выбора, передавая этот массив в стандартный параметр Отбор. В этом случае система отработает условие «Ссылка В Списке».
&НаКлиенте
Процедура ВыбратьСпецификацию(Команда)
МассивСсылок = ПолучитьСпецификацииПоНоменклатуре(ТекущаяНоменклатура);
ПараметрыВыбора = Новый Структура;
ПараметрыВыбора.Вставить("Отбор", Новый Структура("Ссылка", МассивСсылок));
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораСпецификации", ЭтаФорма);
ОткрытьФорму("Справочник.РесурсныеСпецификации.ФормаВыбора", ПараметрыВыбора, ЭтаФорма, , , , ОписаниеОповещения);
КонецПроцедуры
Важный нюанс: данный метод хорош при небольшом количестве данных. Если запрос вернет десятки тысяч ссылок, передача такого массива может замедлить работу системы или привести к ошибкам SQL-запроса из-за ограничения на количество параметров.
Выясним причину, по которой стандартный отбор нам не подходит: он слишком линеен. Более профессиональный подход заключается в манипуляции настройками компоновки данных (СКД), на которой базируется ДинамическийСписок открываемой формы. Мы можем программно создать группу «ИЛИ».
Рассмотрим алгоритм действий:
ГруппаЭлементовОтбораКомпоновкиДанных.ГруппаИли.Посмотрим на пример реализации этой логики:
&НаКлиенте
Процедура ОткрытьФормуСГруппойИли()
// 1. Получаем форму
ФормаВыбора = ПолучитьФорму("Справочник.РесурсныеСпецификации.ФормаВыбора", , ЭтаФорма);
// 2. Очищаем старые настройки, если это необходимо
ФормаВыбора.Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Очистить();
// 3. Создаем группу ИЛИ
ГруппаИли = ФормаВыбора.Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаИли.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
ГруппаИли.Использование = Истина;
// 4. Добавляем первое условие (по номенклатуре)
ЭлементОтбора1 = ГруппаИли.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора1.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ОсновноеИзделиеНоменклатура");
ЭлементОтбора1.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора1.ПравоеЗначение = Объект.Номенклатура;
ЭлементОтбора1.Использование = Истина;
// 5. Добавляем второе условие (по виду номенклатуры)
ЭлементОтбора2 = ГруппаИли.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора2.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ОсновноеИзделиеВидНоменклатуры");
ЭлементОтбора2.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора2.ПравоеЗначение = Объект.Номенклатура.ВидНоменклатуры;
ЭлементОтбора2.Использование = Истина;
// 6. Открываем настроенную форму
ФормаВыбора.Открыть();
КонецПроцедуры
Этот способ является наиболее производительным, так как платформа сама сформирует оптимальный SQL-запрос с условием WHERE (... OR ...).
Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), мы можем упростить код, используя общие модули. В БСП предусмотрены функции для удобной работы с отборами динамических списков.
Проанализируем использование модуля ОбщегоНазначенияКлиентСервер. Хотя стандартная функция УстановитьЭлементОтбораДинамическогоСписка чаще используется для простых отборов, через БСП можно лаконично настраивать параметры открытия формы.
Пример использования структуры фиксированных настроек:
&НаКлиенте
Процедура ОткрытьСИспользованиемБСП()
Настройки = Новый НастройкиКомпоновкиДанных;
Отбор = Настройки.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
Отбор.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
// Используем БСП для добавления элементов (упрощенно)
ОбщегоНазначенияКлиентСервер.ДобавитьЭлементКомпоновки(Отбор, "ОсновноеИзделиеНоменклатура", ВидСравненияКомпоновкиДанных.Равно, Объект.Номенклатура);
ОбщегоНазначенияКлиентСервер.ДобавитьЭлементКомпоновки(Отбор, "ОсновноеИзделиеВидНоменклатуры", ВидСравненияКомпоновкиДанных.Равно, Объект.ВидНоменклатуры);
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ФиксированныеНастройки", Настройки);
ОткрытьФорму("Справочник.РесурсныеСпецификации.ФормаВыбора", ПараметрыФормы, ЭтаФорма);
КонецПроцедуры
Использование параметра ФиксированныеНастройки удобно тем, что эти настройки жестко закрепляются за списком и пользователь не сможет случайно отключить их через меню «Настроить список».
При реализации сложных отборов в 1С стоит помнить о производительности:
ОсновноеИзделиеНоменклатура, ВидНоменклатуры), проиндексированы. В противном случае при большом объеме данных форма будет открываться очень долго.ФиксированныеНастройки для программной логики и ПользовательскиеНастройки, если хотите, чтобы пользователь видел этот отбор и мог им управлять.ПриСозданииНаСервере. Там можно анализировать переданные параметры и настраивать список «изнутри» формы.Таким образом, мы разобрали три ключевых подхода к реализации отборов с условием «ИЛИ». Выбор метода зависит от сложности вашей задачи и объема данных в справочнике.