Как установить отбор в списке справочника по значениям табличной части элементов в 1С?

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

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

В зависимости от используемого типа форм (обычные или управляемые) подход к решению этой задачи будет отличаться. Проанализируем способы реализации отбора для обоих вариантов интерфейса.

Решение для обычных форм (толстый клиент)

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

Разберем по шагам алгоритм выполнения отбора:

  1. Выполняем запрос к табличной части справочника с условием по искомому реквизиту.
  2. Получаем массив или список ссылок на найденные элементы справочника.
  3. Устанавливаем вид сравнения ВидСравнения.ВСписке для поля отбора Ссылка.

Посмотрим на пример кода, реализующий данный механизм:


Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ответственный", ПараметрыСеанса.ТекущийПользователь);
Запрос.Текст = 
"ВЫБРАТЬ РАЗЛИЧНЫЕ
|	ДокументСогласователи.Ссылка КАК Ссылка
|ИЗ
|	Справочник.Документ.Согласователи КАК ДокументСогласователи
|ГДЕ
|	ДокументСогласователи.Согласователь = &Ответственный";

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

ЭтаФорма.СправочникСписок.Отбор.Ссылка.Использование = Истина;
ЭтаФорма.СправочникСписок.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
ЭтаФорма.СправочникСписок.Отбор.Ссылка.Значение.ЗагрузитьЗначения(МассивСсылок);

Оптимизация кода: Для передачи найденных ссылок в отбор списка не обязательно обходить выборку в цикле Пока Выборка.Следующий() Цикл. Результат запроса можно сразу выгрузить в таблицу значений и получить массив ссылок методом ВыгрузитьКолонку("Ссылка"). Передача массива или его загрузка в список значений выполняется существенно быстрее обхода в цикле.

Решение для управляемых форм (динамический список)

В управляемом интерфейсе задача решается встроенными возможностями динамического списка. В свойствах списка можно включить произвольный запрос и прописать логику фильтрации напрямую.

Выясним нюансы настройки динамического списка:

  1. В запросе динамического списка обязательно должно быть заполнено свойство ОсновнаяТаблица. Без этого платформа отключает динамическое считывание данных очередными порциями, а также блокирует стандартные команды контекстного меню (создание, копирование, пометка на удаление).
  2. Чтобы избежать дублирования строк справочника в интерфейсе, отбор строится не через соединение с табличной частью, а с использованием подзапроса или группировки.

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


ВЫБРАТЬ
	СправочникДокумент.Ссылка КАК Ссылка,
	СправочникДокумент.Наименование КАК Наименование
ИЗ
	Справочник.Документ КАК СправочникДокумент
ГДЕ
	СправочникДокумент.Ссылка В
		(ВЫБРАТЬ
			ТЧ.Ссылка
		ИЗ
			Справочник.Документ.Согласователи КАК ТЧ
		ГДЕ
			ТЧ.Согласователь = &Ответственный)

Альтернативные архитектурные решения и производительность

Проанализируем технические ограничения и альтернативные пути решения задачи при работе с большими объемами данных:

Критерии отбора: В платформе 1С предусмотрен объект метаданных КритерийОтбора. Если отбор по реквизиту табличной части используется часто в различных формах системы, можно создать критерий отбора в конфигураторе, указав в его составе реквизит табличной части справочника.

Ограничения отбора по списку ссылок: При использовании метода с выгрузкой массива ссылок в отбор списка (операция ВидСравнения.ВСписке) платформа транслирует условие в конструкцию SQL IN (...). Если искомых объектов несколько тысяч, это приводит к существенному падению производительности запросов, а в файловом режиме или MS SQL Server может вызывать ошибки превышения допустимого количества элементов в операторе отбора.

Индексирование реквизитов: Для реквизита табличной части, по которому предполагается регулярная фильтрация или поиск, в конфигураторе необходимо установить свойство Индексировать (или "Индексировать с доп. упорядочиванием"). Без этого СУБД выполняет полное сканирование таблицы информационной базы при каждом запросе.

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

← На главную