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