Как вывести список контрагентов в динамическом списке справочника партнеров в 1С?

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

В типовых конфигурациях 1С (ERP, КА, УТ) сущности партнеров (управленческий учет) и контрагентов (регламентированный учет) разделены. Часто у одного партнера может быть зарегистрировано несколько юридических лиц (контрагентов). При попытке соединить эти таблицы в запросе динамического списка разработчики сталкиваются с тем, что строки партнера не дублируются под каждого контрагента, либо список начинает работать некорректно.

Разберем причины такого поведения платформы 1С:Предприятие и рассмотрим проверенные способы реализации требуемого интерфейса и поиска.

Почему динамический список сворачивает строки?

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

Если в тексте запроса используется соединение ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты, возвращающее несколько строк на одну ссылку партнера, платформа при отрисовке интерфейса сворачивает дубли по первичному ключу. В итоге отображается только одна из записей либо связанные поля не отображаются вовсе.

Если очистить свойство Основная таблица, строки с дублирующимися ссылками отобразятся, однако это повлечет критические последствия:

  1. Отключается механизм динамического считывания порций данных (список начинает работать медленнее на больших объемах).
  2. Перестает работать иерархический просмотр справочника.
  3. Теряется стандартное контекстное меню, пиктограммы состояния, а также типовые механизмы добавления и редактирования объектов.
  4. Ломаются стандартный глобальный поиск платформы и встроенные панели отборов конфигурации.

Рассмотрим альтернативные варианты решения задачи без отключения основной таблицы.

Способ 1. Заполнение колонки контрагентов в событии «ПриПолученииДанныхНаСервере»

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

Разберем по шагам порядок действий:

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

Посмотрим на пример программного кода:


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

Ограничение метода: по колонкам, сформированным динамически в оформлении строк, не работает стандартная строковая фильтрация платформы.

Способ 2. Денормализация данных (хранение строки контрагентов в объекте)

Если пользователям необходим быстрый типовой поиск и сортировка по наименованиям контрагентов прямо в списке партнеров, оптимальным решением является денормализация.

Реализуем данный подход следующим образом:

  1. Добавляем в справочник Партнеры реквизит КонтрагентыСтрокой (строка неограниченной длины или фиксированной длины с включенным индексированием).
  2. Создаем подписки на события ПриЗаписи и ПередУдалением для справочника Контрагенты.
  3. При изменении контрагентов программно формируем и записываем актуальную строку связанных юрлиц (с наименованиями и ИНН) в реквизит партнера.
  4. Выводим реквизит КонтрагентыСтрокой в динамический список. По нему будут работать полнотекстовый поиск, стандартный поиск платформы и отборы.

Способ 3. Поиск по контрагентам через параметры динамического списка

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

Добавим в текст запроса динамического списка условие отбора:


ГДЕ
    &СтрокаПоиска = ""
    ИЛИ Партнеры.Ссылка В (
        ВЫБРАТЬ
            Контрагенты.Партнер
        ИЗ
            Справочник.Контрагенты КАК Контрагенты
        ГДЕ
            Контрагенты.Наименование ПОДОБНО &СтрокаПоискаШаблон
            ИЛИ Контрагенты.ИНН ПОДОБНО &СтрокаПоискаШаблон
    )

На форме списка размещаем пользовательское поле ввода для поиска и при его изменении передаем значения в параметры динамического списка:


&НаКлиенте
Процедура ПолеПоискаПриИзменении(Элемент)
    Список.Параметры.УстановитьЗначениеПараметра("СтрокаПоиска", ПолеПоиска);
    Список.Параметры.УстановитьЗначениеПараметра("СтрокаПоискаШаблон", "%" + ПолеПоиска + "%");
КонецПроцедуры

Способ 4. Организация интерфейса «Master-Detail»

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

  1. Размещаем на форме вторую таблицу, связанную с новым динамическим списком для таблицы Справочник.Контрагенты.
  2. В запросе подчиненного списка указываем отбор: ГДЕ Контрагенты.Партнер = &ТекущийПартнер.
  3. В событии СписокПриАктивизацииСтроки основного списка партнеров обновляем параметр ТекущийПартнер подчиненного списка.

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

← На главную