В процессе разработки и поддержки конфигураций на платформе 1С:Предприятие 8 часто возникает задача фильтрации списков справочников по критериям, которые хранятся во внешних (подчиненных) таблицах. Классический пример — фильтрация списка контрагентов по наличию, отсутствию или конкретному значению адреса электронной почты (Email), который хранится в регистре сведений РегистрСведений.КонтактнаяИнформация.
Сложность этой задачи заключается в том, что тип формы списка напрямую определяет доступные механизмы фильтрации. В обычных формах (например, в конфигурациях 1С:УПП 1.3, УТ 10.3, КА 1.1) и в управляемых формах (1С:ERP, КА 2, УТ 11, БП 3.0) подходы кардинально различаются. Разберем детально программные и штатные интерактивные методы решения этой задачи для обоих типов интерфейса.
В обычных формах основным источником данных для таблицы списка выступает объект СправочникСписок.<ИмяСправочника>. Данный объект напрямую связан с таблицей базы данных самого справочника и не позволяет выполнять произвольные левые соединения «на лету». Мы не можем напрямую обратиться к полям регистра сведений через свойства отбора СправочникСписок.Отбор, так как этих полей физически нет в метаданных справочника контрагентов.
Для решения этой проблемы мы применим проверенный программный метод: предварительно выберем нужных контрагентов с помощью запроса, поместим их ссылки в список значений и установим отбор по реквизиту Ссылка с видом сравнения ВСписке.
Выясним, как реализовать этот алгоритм по шагам:
РежимФильтрацииEmail типа Число). Определим три его положения:
Рассмотрим подробнее программный код, выполняющий фильтрацию при выборе режима «Только с заполненным Email»:
// 1. Получаем список контрагентов, у которых заполнен Email
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| КонтактнаяИнформация.Объект КАК Контрагент
|ИЗ
| РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
|ГДЕ
| КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты)
| И КонтактнаяИнформация.Представление <> """"";
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
СписокКонтрагентов = Новый СписокЗначений;
СписокКонтрагентов.ЗагрузитьЗначения(РезультатЗапроса.ВыгрузитьКолонку("Контрагент"));
// 2. Устанавливаем отбор в табличном поле списка
ОтборСсылка = СправочникСписок.Отбор.Ссылка;
ОтборСсылка.ВидСравнения = ВидСравнения.ВСписке;
ОтборСсылка.Значение = СписокКонтрагентов;
ОтборСсылка.Использование = Истина;
Теперь проанализируем ситуацию, когда пользователю необходимо выбрать контрагентов БЕЗ Email. Использовать вид сравнения НеВСписке по массиву заполненных адресов крайне не рекомендуется. Если база данных содержит десятки тысяч контрагентов, это приведет к сильному падению производительности. Вместо этого мы составим запрос с левым соединением справочника с регистром контактной информации и найдем те записи, у которых значение адреса равно NULL или пустой строке:
ЗапросБезEmail = Новый Запрос;
ЗапросБезEmail.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Контрагент
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
| ПО КонтактнаяИнформация.Объект = Контрагенты.Ссылка
| И КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты)
|ГДЕ
| (КонтактнаяИнформация.Представление ЕСТЬ NULL ИЛИ КонтактнаяИнформация.Представление = """")
| И НЕ Контрагенты.ЭтоГруппа"; // Исключаем группы для сохранения иерархии списка
РезультатЗапросаБезEmail = ЗапросБезEmail.txt = ЗапросБезEmail.Выполнить().Выгрузить();
СписокБезEmail = Новый СписокЗначений;
СписокБезEmail.ЗагрузитьЗначения(РезультатЗапросаБезEmail.ВыгрузитьКолонку("Контрагент"));
// Установка отбора аналогична первому варианту
ОтборСсылка = СправочникСписок.Отбор.Ссылка;
ОтборСсылка.ВидСравнения = ВидСравнения.ВСписке;
ОтборСсылка.Значение = СписокБезEmail;
ОтборСсылка.Использование = Истина;
Для сброса фильтра и отображения всех контрагентов достаточно отключить использование отбора по ссылке:
СправочникСписок.Отбор.Ссылка.Использование = Ложь;
Если перед вами стоит задача решить проблему быстро на уровне пользователя без изменения кода конфигурации, в 1С:УПП предусмотрен мощный штатный механизм поиска. Разберем по шагам, как его настроить:
Тип должно быть «Равно» значению «E-Mail», а поле Представление должно содержать символ «@» (или маску поиска, в зависимости от настроек системы).Переход на управляемый интерфейс и использование платформы 1С:Предприятие 8.3 существенно упрощает работу со списками. Здесь источником данных является объект ДинамическийСписок, который позволяет разработчику использовать произвольные SQL-подобные запросы для вывода информации.
Посмотрим на пример настройки динамического списка:
Справочник.Контрагенты с таблицей РегистрСведений.КонтактнаяИнформация.Email (непосредственно строку адреса) или булево поле ЕстьEmail.После этого мы можем легко управлять фильтрацией программно, добавляя элементы отбора компоновки данных. Рассмотрим пример кода для установки такого отбора:
// Очищаем старые программные отборы по полю Email, чтобы избежать дублирования
ИмяПоляКомпоновки = Новый ПолеКомпоновкиДанных("Email");
Для Каждого Элемент Из Список.Отбор.Элементы Цикл
Если Элемент.ЛевоеЗначение = ИмяПоляКомпоновки Тогда
Список.Отбор.Элементы.Удалить(Элемент);
КонецЕсли;
КонецЦикла;
// Накладываем новый отбор в зависимости от значения переключателя на форме
Если РежимФильтрацииEmail <> 0 Тогда
НовыйОтбор = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = ИмяПоляКомпоновки;
Если РежимФильтрацииEmail = 1 Тогда // С заполненным Email
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;
ИначеЕсли РежимФильтрацииEmail = 2 Тогда // Без Email
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
КонецЕсли;
НовыйОтбор.Использование = Истина;
// Скрываем отбор от пользователя, чтобы он не мог случайно его отключить в стандартных настройках
НовыйОтбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецЕсли;
Важное примечание для конфигураций на БСП: Если ваша база построена на Библиотеке Стандартных Подсистем (БСП), то ручное изменение запроса динамического списка может не потребоваться. Подсистема «Контактная информация» автоматически подключает доступные виды КИ к динамическим спискам в качестве дополнительных реквизитов. Пользователю достаточно зайти в меню Еще — Настроить список — Отбор, найти в списке полей «Контактная информация.Email» и перетащить его в область быстрых отборов.