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