Как программно отфильтровать элементы формы списка по контактной информации

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

В процессе разработки и поддержки конфигураций на платформе 1С:Предприятие 8 часто возникает задача фильтрации списков справочников по критериям, которые хранятся во внешних (подчиненных) таблицах. Классический пример — фильтрация списка контрагентов по наличию, отсутствию или конкретному значению адреса электронной почты (Email), который хранится в регистре сведений РегистрСведений.КонтактнаяИнформация.

Сложность этой задачи заключается в том, что тип формы списка напрямую определяет доступные механизмы фильтрации. В обычных формах (например, в конфигурациях 1С:УПП 1.3, УТ 10.3, КА 1.1) и в управляемых формах (1С:ERP, КА 2, УТ 11, БП 3.0) подходы кардинально различаются. Разберем детально программные и штатные интерактивные методы решения этой задачи для обоих типов интерфейса.

Решение для обычных форм (1С:УПП, УТ 10.3)

В обычных формах основным источником данных для таблицы списка выступает объект СправочникСписок.<ИмяСправочника>. Данный объект напрямую связан с таблицей базы данных самого справочника и не позволяет выполнять произвольные левые соединения «на лету». Мы не можем напрямую обратиться к полям регистра сведений через свойства отбора СправочникСписок.Отбор, так как этих полей физически нет в метаданных справочника контрагентов.

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

Выясним, как реализовать этот алгоритм по шагам:

  1. Добавим на форму списка элемент управления — переключатель или поле выбора со связанным реквизитом (например, РежимФильтрацииEmail типа Число). Определим три его положения:
    • 0 — Отображать всех контрагентов;
    • 1 — Только с заполненным Email;
    • 2 — Только с незаполненным Email.
  2. Создадим обработчик события изменения этого переключателя, в котором будем управлять отбором списка.

Рассмотрим подробнее программный код, выполняющий фильтрацию при выборе режима «Только с заполненным Email»:


// 1. Получаем список контрагентов, у которых заполнен Email
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	КонтактнаяИнформация.Объект КАК Контрагент
    |ИЗ
    |	РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
    |ГДЕ
    |	КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты)
    |	И КонтактнаяИнформация.Представление <> """"";

РезультатЗапроса = Запрос.Выполнить().Выгрузить();
СписокКонтрагентов = Новый СписокЗначений;
СписокКонтрагентов.ЗагрузитьЗначения(РезультатЗапроса.ВыгрузитьКолонку("Контрагент"));

// 2. Устанавливаем отбор в табличном поле списка
ОтборСсылка = СправочникСписок.Отбор.Ссылка;
ОтборСсылка.ВидСравнения = ВидСравнения.ВСписке;
ОтборСсылка.Значение = СписокКонтрагентов;
ОтборСсылка.Использование = Истина;

Теперь проанализируем ситуацию, когда пользователю необходимо выбрать контрагентов БЕЗ Email. Использовать вид сравнения НеВСписке по массиву заполненных адресов крайне не рекомендуется. Если база данных содержит десятки тысяч контрагентов, это приведет к сильному падению производительности. Вместо этого мы составим запрос с левым соединением справочника с регистром контактной информации и найдем те записи, у которых значение адреса равно NULL или пустой строке:


ЗапросБезEmail = Новый Запрос;
ЗапросБезEmail.Текст = 
    "ВЫБРАТЬ
    |	Контрагенты.Ссылка КАК Контрагент
    |ИЗ
    |	Справочник.Контрагенты КАК Контрагенты
    |	ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
    |		ПО КонтактнаяИнформация.Объект = Контрагенты.Ссылка
    |		И КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты)
    |ГДЕ
    |	(КонтактнаяИнформация.Представление ЕСТЬ NULL ИЛИ КонтактнаяИнформация.Представление = """")
    |	И НЕ Контрагенты.ЭтоГруппа"; // Исключаем группы для сохранения иерархии списка

РезультатЗапросаБезEmail = ЗапросБезEmail.txt = ЗапросБезEmail.Выполнить().Выгрузить();
СписокБезEmail = Новый СписокЗначений;
СписокБезEmail.ЗагрузитьЗначения(РезультатЗапросаБезEmail.ВыгрузитьКолонку("Контрагент"));

// Установка отбора аналогична первому варианту
ОтборСсылка = СправочникСписок.Отбор.Ссылка;
ОтборСсылка.ВидСравнения = ВидСравнения.ВСписке;
ОтборСсылка.Значение = СписокБезEmail;
ОтборСсылка.Использование = Истина;

Для сброса фильтра и отображения всех контрагентов достаточно отключить использование отбора по ссылке:

СправочникСписок.Отбор.Ссылка.Использование = Ложь;

Штатный метод фильтрации в 1С:УПП (без изменения конфигурации)

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

  1. В форме списка справочника «Контрагенты» обратите внимание на панель поиска.
  2. В меню панели выберите пункт «Настроить новый отбор...». При этом откроется форма обработки «Универсальный поиск объектов».
  3. В появившейся табличной части найдите строку «Контактная информация». Система автоматически распознает логическую связь объектов благодаря настроенным критериям отбора.
  4. Добавьте ограничения: поле Тип должно быть «Равно» значению «E-Mail», а поле Представление должно содержать символ «@» (или маску поиска, в зависимости от настроек системы).
  5. Сохраните данную настройку поиска под понятным именем (например, «Имеет E-Mail»). Она станет доступна в общем списке видов поиска прямо из панели формы списка.

Решение для управляемых форм (1С:ERP, КА 2, УТ 11, БП 3.0)

Переход на управляемый интерфейс и использование платформы 1С:Предприятие 8.3 существенно упрощает работу со списками. Здесь источником данных является объект ДинамическийСписок, который позволяет разработчику использовать произвольные SQL-подобные запросы для вывода информации.

Посмотрим на пример настройки динамического списка:

  1. Откройте форму списка контрагентов в конфигураторе, перейдите к свойствам основного реквизита списка и установите флаг «Произвольный запрос».
  2. В конструкторе запроса соедините таблицу справочника Справочник.Контрагенты с таблицей РегистрСведений.КонтактнаяИнформация.
  3. Выведите в схему компоновки виртуальное поле, например, Email (непосредственно строку адреса) или булево поле ЕстьEmail.

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


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

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

Важное примечание для конфигураций на БСП: Если ваша база построена на Библиотеке Стандартных Подсистем (БСП), то ручное изменение запроса динамического списка может не потребоваться. Подсистема «Контактная информация» автоматически подключает доступные виды КИ к динамическим спискам в качестве дополнительных реквизитов. Пользователю достаточно зайти в меню Еще — Настроить список — Отбор, найти в списке полей «Контактная информация.Email» и перетащить его в область быстрых отборов.

← На главную