Как правильно объединить данные из двух запросов в 1С, чтобы избежать задвоения итогов?

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

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

Понимание проблемы «размножения» строк

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

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

Самый надежный способ решить эту задачу — привести все данные к единому уровню детализации до того, как они будут объединены в итоговой выборке. Для этого мы используем МенеджерВременныхТаблиц.

  1. Создадим временную таблицу ВТ_Факт, в которой сгруппируем данные по сотруднику и подразделению.
  2. Создадим временную таблицу ВТ_План, в которой оставим только уникальные записи по сотруднику на каждый месяц.
  3. Выполним соединение этих двух таблиц.

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


ВЫБРАТЬ
    Регистр.Сотрудник,
    Регистр.Подразделение,
    СУММА(Регистр.Факт) КАК Факт
ПОМЕСТИТЬ ВТ_Факт
ИЗ РегистрСПодразделениями КАК Регистр
СГРУППИРОВАТЬ ПО Регистр.Сотрудник, Регистр.Подразделение;

ВЫБРАТЬ
    Планы.Сотрудник,
    СУММА(Планы.План) КАК План
ПОМЕСТИТЬ ВТ_План
ИЗ Документ.Планы КАК Планы
СГРУППИРОВАТЬ ПО Планы.Сотрудник;

ВЫБРАТЬ
    ВТ_Факт.Подразделение,
    ВТ_Факт.Сотрудник,
    ВТ_Факт.Факт,
    ЕСТЬNULL(ВТ_План.План, 0) КАК План
ИЗ ВТ_Факт КАК ВТ_Факт
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_План КАК ВТ_План
ПО ВТ_Факт.Сотрудник = ВТ_План.Сотрудник;

Решение 2: Использование возможностей СКД

Если вы работаете с СистемойКомпоновкиДанных, не всегда нужно писать сложные запросы. Вы можете использовать механизм Наборы данных - Объединение.

Разделите логику на два набора данных:

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

Решение 3: Группировка после объединения

Если вы все же предпочитаете использовать ОБЪЕДИНИТЬ ВСЕ, важно помнить о правилах группировки. Чтобы итоги считались верно, результат объединения стоит поместить во временную таблицу, а уже из неё делать итоговую выборку с использованием СУММА().

Важное замечание: При проектировании запроса всегда анализируйте, является ли поле числовым. Если вы используете СУММА для полей, которые должны быть уникальными (например, План), убедитесь, что группировка в СКД настроена иерархично. Если необходимо выводить среднее значение, учитывайте, что оно может исказить данные на верхних уровнях иерархии (Департамент, Подразделение), поэтому для итоговых уровней лучше использовать формулы ВычислитьВыражение, чтобы зафиксировать значение на уровне сотрудника.

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

← На главную