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