Как исправить вывод неправильных данных в отчёте СКД при связке документов и справочников?

Программист Управленческий учет Торговля и дистрибуция
← На главную

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

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

Анализ проблемы: почему данные выводятся неправильно?

Разберем типичную ситуацию. У нас есть цепочка бизнес-процесса:

  1. Создается элемент справочника Запросы.
  2. На его основании создается документ ТелефонныйЗвонок.
  3. На основании звонка создается справочник СделкиСКлиентами.

Основная ошибка, которую совершают многие разработчики при написании запроса, — это попытка связать объекты по косвенным признакам, таким как Источник, Менеджер или Контрагент. Рассмотрим пример ошибочного соединения:


ИЗ Справочник.СделкиСКлиентами КАК СделкиСКлиентами
ПОЛНОЕ СОЕДИНЕНИЕ Документ.ТелефонныйЗвонок КАК ТелефонныйЗвонок
ПОЛНОЕ СОЕДИНЕНИЕ Справочник.Запросы КАК Запросы
ПО ТелефонныйЗвонок.ВзаимодействиеОснование = Запросы.Ссылка
ПО (СделкиСКлиентами.Источник = Запросы.Источник)

Проанализируем этот код. Проблема здесь в строке ПО (СделкиСКлиентами.Источник = Запросы.Источник). Если у вас есть 10 сделок с источником «Реклама» и 10 запросов с тем же источником, система сопоставит каждую сделку с каждым запросом. В итоге вы получите 100 строк в отчете вместо 10. Это называется картезианским произведением. Чтобы данные выводились корректно, связь должна идти строго по уникальным ссылкам (идентификаторам) объектов.

Решение 1: Добавление реквизита связи в метаданные

Самый надежный способ связать справочник СделкиСКлиентами с документом ТелефонныйЗвонок — это создать в справочнике специальный реквизит, который будет хранить ссылку на документ-основание. Выясним, как это реализовать:

  1. В конфигураторе откройте справочник СделкиСКлиентами.
  2. Добавьте новый реквизит, например, с именем ДокументОснование.
  3. Установите тип данных этого реквизита как ДокументСсылка.ТелефонныйЗвонок (или используйте составной тип, если оснований может быть несколько).

Теперь необходимо обеспечить заполнение этого реквизита при создании сделки на основании звонка. Для этого используем модуль объекта справочника СделкиСКлиентами и процедуру ОбработкаЗаполнения.

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


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ТелефонныйЗвонок") Тогда
        // Записываем ссылку на звонок в наш новый реквизит
        ЭтотОбъект.ДокументОснование = ДанныеЗаполнения;
        
        // Также можно заполнить другие реквизиты из документа-основания
        ЭтотОбъект.Партнер = ДанныеЗаполнения.Абонент;
        ЭтотОбъект.Ответственный = ДанныеЗаполнения.Ответственный;
    КонецЕсли;
    
КонецПроцедуры

После внесения этих изменений каждая новая сделка будет «знать», какой именно звонок стал её причиной. Это позволит нам построить идеальную связь в отчете.

Решение 2: Корректное соединение в запросе СКД

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

Рассмотрим структуру правильного запроса:


ВЫБРАТЬ
    Запросы.Ссылка КАК Запрос,
    ТелефонныйЗвонок.Ссылка КАК Звонок,
    СделкиСКлиентами.Ссылка КАК Сделка
ИЗ
    Справочник.Запросы КАК Запросы
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.ТелефонныйЗвонок КАК ТелефонныйЗвонок
        ПО ТелефонныйЗвонок.ВзаимодействиеОснование = Запросы.Ссылка
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.СделкиСКлиентами КАК СделкиСКлиентами
        ПО СделкиСКлиентами.ДокументОснование = ТелефонныйЗвонок.Ссылка

В данном случае условие ПО СделкиСКлиентами.ДокументОснование = ТелефонныйЗвонок.Ссылка гарантирует, что к конкретному звонку подтянется только та сделка, которая была создана на его основании.

Решение 3: Использование типовых механизмов (Предмет и Критерии отбора)

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

У документа ТелефонныйЗвонок часто есть реквизит Предмет. При создании сделки на основании звонка, система может автоматически записывать ссылку на сделку в этот реквизит звонка. В таком случае связь в запросе будет выглядеть наоборот:


ЛЕВОЕ СОЕДИНЕНИЕ Справочник.СделкиСКлиентами КАК СделкиСКлиентами
    ПО ТелефонныйЗвонок.Предмет = СделкиСКлиентами.Ссылка

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

Работа с пустыми значениями через ЕСТЬNULL

При использовании ЛЕВОГО СОЕДИНЕНИЯ для документов, по которым еще не созданы подчиненные объекты, в полях сделки будет значение NULL. В СКД это может привести к визуальному отсутствию данных или ошибкам в ресурсах. Проанализируем, как этого избежать.

Всегда оборачивайте выбираемые поля в функцию ЕСТЬNULL. Это особенно важно для числовых показателей и ссылочных полей, если вы планируете использовать их в группировках:


ВЫБРАТЬ
    Запросы.Ссылка КАК Запрос,
    ЕСТЬNULL(ТелефонныйЗвонок.Ссылка, ЗНАЧЕНИЕ(Документ.ТелефонныйЗвонок.ПустаяСсылка)) КАК Звонок,
    ЕСТЬNULL(СделкиСКлиентами.Статус, "Нет сделки") КАК СтатусСделки
ИЗ
    Справочник.Запросы КАК Запросы
    ...

Настройка связей на уровне наборов данных СКД

Иногда эффективнее разделять запросы на разные наборы данных в СКД и связывать их на вкладке «Связи наборов данных». Это позволяет избежать дублей на уровне SQL-запроса, так как СКД будет выполнять соединения после получения результатов из каждой таблицы отдельно.

Разберем, как это сделать:

  1. Создайте НаборДанных1 с запросом по Запросам и Звонкам.
  2. Создайте НаборДанных2 с запросом по Сделкам.
  3. Перейдите на вкладку «Связи наборов данных».
  4. Укажите Источник связи (Набор1), Приемник (Набор2) и выберите поля связи (например, Звонок и ДокументОснование).

Этот метод часто спасает, когда один объект может иметь несколько подчиненных, и стандартное ЛЕВОЕ СОЕДИНЕНИЕ начинает бесконтрольно множить строки в отчете.

Подведение итогов

Для исправления неверного вывода данных в СКД необходимо:

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

← На главную