Как реализовать свой поиск по ИНН в форме списка партнеров в 1С:Управление торговлей 11?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Рассмотрим ситуацию, когда при установке отбора по ИНН в динамическом списке найденные элементы выводятся корректно, только если у партнера не заполнен реквизит Родитель. Если же найденный партнер является подчиненным элементом, динамический список в иерархическом режиме оказывается пустым.

Причина проблемы: особенности иерархических динамических списков

Проанализируем поведение платформы 1С:Предприятие при работе с динамическими списками в режимах просмотра «Иерархический список» или «Дерево»:

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

Решение 1. Программное добавление цепочки родителей в список отбора

Разберем первый способ решения задачи. Чтобы подчиненный партнер отобразился в иерархическом динамическом списке, необходимо поместить в список отбора не только самого найденного партнера, но и всех его вышестоящих родителей до самого верхнего уровня.

Рассмотрим исходный вариант функции поиска партнеров по ИНН контрагента:


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

После получения полного списка партнеров вместе с родителями устанавливаем отбор в обработчике события элемента формы:


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

Решение 2. Динамическая смена режима отображения таблицы

Еще один распространенный и эффективный подход — программное переключение режима отображения таблицы динамического списка с иерархического на простой список во время поиска.

Посмотрим, как это реализовать:

  1. При вводе текста в поле поиска переключаем режим отображения таблицы динамического списка на простой список: Элементы.Список.Отображение = РежимОтображенияТаблицы.Список;.
  2. В режиме простого списка платформа выводит все найденные элементы списком без построения дерева, поэтому подчиненные элементы не скрываются.
  3. При очистке поля поиска возвращаем исходный режим: Элементы.Список.Отображение = РежимОтображенияТаблицы.ИерархическийСписок;.

Решение 3. Использование регистра «ИерархияПартнеров»

В типовой конфигурации «1С:Управление торговлей 11» для работы с иерархией партнеров предусмотрен специальный служебный РегистрСведений.ИерархияПартнеров. Обход родителей через точки в цикле (ТекПартнер.Родитель) создает дополнительные обращения к базе данных. Чтобы ускорить выполнение запроса, выемку родительских связей лучше выполнять напрямую через данный регистр.

Пример оптимизированного запроса для получения всей цепочки иерархии:


ВЫБРАТЬ РАЗЛИЧНЫЕ
	Иерархия.Родитель КАК Ссылка
ИЗ
	Справочник.Контрагенты КАК Контрагенты
	ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ИерархияПартнеров КАК Иерархия
		ПО Контрагенты.Партнер = Иерархия.Элемент
ГДЕ
	Контрагенты.ИНН ПОДОБНО &ИНН

Такой подход позволяет за один быстрый запрос к СУБД получить как самих найденных партнеров, так и все родительские узлы, необходимые для корректной отрисовки иерархического динамического списка.

← На главную