Как вывести контактную информацию контрагентов в одну строку в отчете СКД?

Программист 1С v8.3 (Управляемые формы)
← На главную

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

Причина возникновения дублей в отчете

Разберем ситуацию: у контрагента есть «Телефон» и «Электронная почта». В базе данных это две разные записи в подчиненной таблице. Когда мы пишем запрос и просто выбираем данные из справочника Контрагенты и его табличной части КонтактнаяИнформация, СУБД выполняет соединение, результатом которого становится количество строк, равное количеству контактов. Чтобы этого избежать, нам нужно «развернуть» строки в колонки.

Решение 1: Использование множественных левых соединений в запросе

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

Проанализируем пример запроса, который позволяет получить телефон и почту в отдельные колонки одной строки:


ВЫБРАТЬ
    Контрагенты.Наименование КАК Наименование,
    Контрагенты.ИНН КАК ИНН,
    КонтрагентыПочта.АдресЭП КАК АдресЭП,
    КонтрагентыТелефон.НомерТелефона КАК НомерТелефона
ИЗ
    Справочник.Контрагенты КАК Контрагенты
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыТелефон
        ПО Контрагенты.Ссылка = КонтрагентыТелефон.Ссылка
            И (КонтрагентыТелефон.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ТелефонКонтрагента))
            
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыПочта
        ПО Контрагенты.Ссылка = КонтрагентыПочта.Ссылка
            И (КонтрагентыПочта.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.EmailКонтрагенты))

В данном примере мы используем ЛЕВОЕ СОЕДИНЕНИЕ. Это критически важно, так как если у контрагента не будет заполнена почта, но будет телефон, при использовании внутреннего соединения (INNER JOIN) такой контрагент вообще не попадет в отчет. Условие ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации...) позволяет нам обращаться к предопределенным элементам видов контактов напрямую в коде запроса.

Решение 2: Получение данных контактных лиц

Часто требуется вывести не только контакты самой компании, но и данные её основного контактного лица. Посмотрим на алгоритм реализации такой задачи. Нам необходимо сначала соединиться со справочником КонтактныеЛица, а затем от него по той же логике получить контактную информацию.

Выясним причину, почему это сложнее: контактное лицо — это самостоятельный объект со своим набором контактов. Запрос будет выглядеть следующим образом:


ВЫБРАТЬ
    Контрагенты.Ссылка КАК Контрагент,
    Контрагенты.КонтактноеЛицо КАК КонтактноеЛицо,
    КИ_Контрагента.НомерТелефона КАК ТелефонКомпании,
    КИ_КонтактногоЛица.НомерТелефона КАК ТелефонМенеджера
ИЗ
    Справочник.Контрагенты КАК Контрагенты
    
    // Получаем телефон самого контрагента
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты.КонтактнаяИнформация КАК КИ_Контрагента
    ПО Контрагенты.Ссылка = КИ_Контрагента.Ссылка
    И КИ_Контрагента.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ТелефонКонтрагента)
    
    // Получаем телефон контактного лица
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.КонтактныеЛица.КонтактнаяИнформация КАК КИ_КонтактногоЛица
    ПО Контрагенты.КонтактноеЛицо = КИ_КонтактногоЛица.Ссылка
    И КИ_КонтактногоЛица.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ТелефонКонтактногоЛица)

Решение 3: Агрегатная функция СоединитьСтроки в СКД

Если у одного контрагента может быть записано несколько телефонов (например, два рабочих номера), использование соединений в запросе может привести к дублированию строк, если мы не выберем только один «основной». В СКД есть мощный инструмент для решения этой проблемы без усложнения запроса — функция СоединитьСтроки.

Рассмотрим по шагам, как это настроить:

  1. В запросе выберите все записи контактной информации детально (без соединений по видам).
  2. На вкладке Ресурсы выберите поле НомерТелефона.
  3. В колонке Выражение напишите: СоединитьСтроки(ТаблицаЗначений(НомерТелефона), ", ").
  4. В колонке Рассчитывать по... укажите только поле Ссылка (или Контрагент).

Этот метод позволит вывести все телефоны контрагента в одну ячейку через запятую, при этом основной отчет останется линейным и понятным. Для ознакомления со схожим примером группировки пригодится способ объединения значений строк в СКД.

Решение 4: Работа с регистром сведений (БСП)

В современных конфигурациях (УТ 11, ERP, БП 3.0), построенных на Библиотеке стандартных подсистем (БСП), контактная информация хранится в одноименном регистре сведений КонтактнаяИнформация. Работа с ним через запрос предпочтительнее с точки зрения производительности.

Обратите внимание на поле Объект в регистре — оно имеет составной тип. Поэтому при соединении важно соблюдать типизацию. Также в БСП часто используется поле Представление, которое уже содержит отформатированную строку контакта. Проанализируем пример связи с регистром:


ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КИ
ПО Контрагенты.Ссылка = КИ.Объект
    И КИ.Вид = &ПараметрВидКИ
    И КИ.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Телефон)

Важный совет: Если вы работаете в типовой конфигурации, посмотрите на функции общего модуля УправлениеКонтактнойИнформацией. Там существуют готовые инструменты для парсинга адресов и телефонов из формата JSON/XML, в котором они хранятся в поле ЗначенияПолей. Для СКД это можно реализовать через Вычисляемые поля, вызывая функции модуля прямо в выражении поля.

Рекомендации по оптимизации

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

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

← На главную