Почему в отчете СКД дублируются строки при соединении нескольких регистров и как это исправить?

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

При разработке сложных отчетов в Системе компоновки данных (СКД) часто возникает задача вывести информацию из двух и более регистров накопления одновременно. Однако при попытке объединить данные с помощью ПОЛНОГО СОЕДИНЕНИЯ (Full Join) или ЛЕВОГО СОЕДИНЕНИЯ начинающие разработчики сталкиваются с проблемой: строки отчета начинают необоснованно дублироваться. Это происходит из-за возникновения так называемого «декартова произведения», когда система сопоставляет каждую запись первой таблицы с каждой записью второй таблицы, если ключи соединения не являются строго уникальными.

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

Причина возникновения проблемы

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

Решение 1: Использование объединения запросов (UNION)

Если вам нужно получить список всех событий (приходов и расходов) из разных регистров, не объединяя их в одну «широкую» строку, самым надежным способом будет использование оператора ОБЪЕДИНИТЬ (Union). Этот метод позволяет собрать данные в один плоский список, где для каждого регистра будут заполнены только «свои» колонки, а в «чужих» будут стоять нули.

Посмотрим на пример реализации такого подхода:


ВЫБРАТЬ
    ВложЗапрос.Номенклатура КАК Номенклатура,
    ВложЗапрос.Склад КАК Склад,
    ВложЗапрос.ВНаличииКонечныйОстаток КАК ВНаличииКонечныйОстаток,
    ВложЗапрос.ДокументСклад КАК ДокументСклад,
    ВложЗапрос.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток,
    ВложЗапрос.ДокументОрганизация КАК ДокументОрганизация
ИЗ (
    ВЫБРАТЬ 
        ТоварыНаСкладах.Номенклатура КАК Номенклатура,
        ТоварыНаСкладах.Склад КАК Склад,
        ТоварыНаСкладах.ВНаличииКонечныйОстаток КАК ВНаличииКонечныйОстаток,
        ТоварыНаСкладах.Регистратор КАК ДокументСклад,
        0 КАК КоличествоКонечныйОстаток,
        0 КАК ДокументОрганизация
    ИЗ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(,, Авто,,) КАК ТоварыНаСкладах
    ГДЕ НЕ ТоварыНаСкладах.ВНаличииОборот = 0

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ 
        ТоварыОрганизаций.АналитикаУчетаНоменклатуры.Номенклатура,
        ТоварыОрганизаций.АналитикаУчетаНоменклатуры.Склад,
        0,
        0,
        ТоварыОрганизаций.КоличествоКонечныйОстаток,
        ТоварыОрганизаций.Регистратор
    ИЗ РегистрНакопления.ТоварыОрганизаций.ОстаткиИОбороты(,, Авто,,) КАК ТоварыОрганизаций
    ГДЕ НЕ ТоварыОрганизаций.КоличествоОборот = 0
) КАК ВложЗапрос

Используя ОБЪЕДИНИТЬ ВСЕ, мы гарантируем, что каждая строка из регистра попадет в результат ровно один раз, что исключает дублирование.

Решение 2: Использование нескольких наборов данных в СКД

Если вы хотите сохранить гибкость СКД, рассмотрите вариант разделения запросов на два независимых набора данных:

  1. Создайте Набор данных - запрос 1: данные из ТоварыНаСкладах.
  2. Создайте Набор данных - запрос 2: данные из ТоварыОрганизаций.
  3. Перейдите на вкладку Связи наборов данных.
  4. Установите связь между этими наборами по полям Номенклатура, Склад и Период.

В этом случае система компоновки сама возьмет на себя задачу сопоставления записей, что гораздо безопаснее ручного написания ПОЛНОГО СОЕДИНЕНИЯ в тексте запроса.

Решение 3: Создание таблицы-связки (Временная таблица)

Если данные в регистрах сильно различаются и связь по ключевым полям работает некорректно, можно применить классический метод «связки»:

  1. Сначала сформируйте запрос, который выбирает РАЗЛИЧНЫЕ сочетания Номенклатура, Склад и Период из обоих регистров.
  2. Поместите результат во временную таблицу.
  3. Используйте эту временную таблицу как главную («левую») таблицу, к которой через ЛЕВОЕ СОЕДИНЕНИЕ подтягиваются данные из обоих регистров.

Такой подход позволяет полностью исключить появление декартова произведения, так как основой для отчета становится уникальный список аналитик, к которому просто «приклеиваются» нужные показатели.

Итоговые рекомендации

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

← На главную