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

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет Промышленность, строительство и АПК
← На главную

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

Разбор ситуации: Причины «размножения» строк

Проанализируем классическую ситуацию. У нас есть основной набор данных (источник), который получает количественные показатели (например, из регистра накопления ПланыПотребленияМатериалов), и вспомогательный набор (приемник), который должен подтянуть дополнительную информацию (например, текстовое примечание из РесурсныеСпецификации.МатериалыИУслуги).

Когда мы указываем связь по полям Номенклатура, Характеристика и Спецификация, система выполняет операцию, аналогичную ЛЕВОМУ СОЕДИНЕНИЮ. Если в наборе-приемнике для одной комбинации «Номенклатура + Характеристика + Спецификация» найдется две или более строки, то строка из основного набора будет продублирована столько же раз. В справочнике ресурсных спецификаций один и тот же материал может встречаться в разных строках табличной части (например, для разных этапов производства или с разными свойствами применения), что и приводит к «квадрату» строк в итоговом отчете.

Решение №1: Агрегация данных в наборе-приемнике

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

  1. Используем агрегатную функцию МАКСИМУМ для всех полей, которые не входят в ключ связи.
  2. Добавляем обязательную группировку по ключевым полям.

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


ВЫБРАТЬ
    ИзСпецификаций.Ссылка КАК Спецификация,
    ИзСпецификаций.Номенклатура КАК Номенклатура,
    ИзСпецификаций.Характеристика КАК Характеристика,
    МАКСИМУМ(ИзСпецификаций.ПрименениеМатериала) КАК Строка
ИЗ
    Справочник.РесурсныеСпецификации.МатериалыИУслуги КАК ИзСпецификаций
СГРУППИРОВАТЬ ПО
    ИзСпецификаций.Ссылка,
    ИзСпецификаций.Номенклатура,
    ИзСпецификаций.Характеристика

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

Проблема пустых значений и нескольких источников

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

Рассмотрим подробнее вкладку «Связи наборов данных». Для корректной работы необходимо:

Решение №2: Использование единого пакетного запроса

Часто программисты пытаются использовать временные таблицы (ВТ) в разных наборах данных, но сталкиваются с ошибкой Поле не найдено. Проанализируем ситуацию: в 1С СКД каждый «Набор данных - запрос» выполняется в своем собственном сеансе или контексте. Временная таблица, созданная в Наборе №1, физически не существует в Наборе №2.

Самым надежным и производительным способом решения проблемы «соединения наборов» является отказ от использования вкладок «Наборы данных» и «Связи наборов» в пользу одного набора данных с пакетным запросом. Посмотрим на алгоритм:

  1. В первом запросе пакета собираем данные по «Цилиндрам» во временную таблицу.
  2. Во втором запросе пакета собираем данные по «Кожухам» во временную таблицу.
  3. В третьем запросе объединяем их через ОБЪЕДИНИТЬ ВСЕ.
  4. В основном (последнем) запросе левым соединением подключаем справочные данные (спецификации), сразу применяя СГРУППИРОВАТЬ ПО.

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

Когда все же стоит использовать связи наборов данных?

Несмотря на вышеописанные сложности, механизм связей необходим в следующих случаях:

Подведем итог: если вы видите, что данные в отчете двоятся или пропадают при добавлении колонки из связанного набора, первым делом проверьте уникальность записей в наборе-приемнике с помощью МАКСИМУМ и СГРУППИРОВАТЬ ПО. Если структура отчета позволяет, всегда отдавайте предпочтение объединению данных внутри одного запроса — это значительно упростит отладку и повысит скорость формирования отчета.

← На главную