Как подсчитать разность итогов при объединении запросов в 1С

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

При разработке отчетов и сложных алгоритмов получения данных в 1С программисты часто сталкиваются с необходимостью объединить данные из разных источников (например, из разных регистров или документов) и получить итоговый результат в виде одной цифры. Типичная задача: вычислить общую сумму по первому запросу и вычесть из неё общую сумму по второму запросу, используя конструкцию ОБЪЕДИНИТЬ.

Рассмотрим детально, как реализовать этот механизм, разберем типичные ошибки и проанализируем различные подходы — от классического запроса до использования Системы компоновки данных (СКД).

Метод 1: Использование отрицательных значений в Конструкторе запросов

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

Разберем этот процесс по шагам:

  1. Создание первого запроса: В Конструкторе запросов выберите нужную таблицу и поле, например, СуммаОстаток. Назовите это поле ОбщийИтог.
  2. Добавление объединения: На вкладке "Объединения/Псевдонимы" добавьте второй запрос.
  3. Инверсия знака: Во втором запросе выберите поле суммы, но вместо прямого выбора поля пропишите выражение. Нажмите кнопку редактирования выражения и введите -ТвояТаблица.СуммаОстаток.
  4. Сопоставление полей: Это критически важный момент. На вкладке "Объединения/Псевдонимы" убедитесь, что поле из первого запроса и поле с минусом из второго запроса стоят в одной строке. В правой колонке (результат) они должны иметь общий псевдоним ОбщийИтог.

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


ВЫБРАТЬ
    Продажи.СуммаОборот КАК ОбщийИтог
ИЗ
    РегистрНакопления.Продажи КАК Продажи

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

ВЫБРАТЬ
    -Возвраты.СуммаОборот
ИЗ
    РегистрНакопления.Возвраты КАК Возвраты

Проанализируем ситуацию: если в продажах была сумма 100, а в возвратах 30, то итоговая таблица будет содержать две строки: 100 и -30. При подсчете итога по колонке ОбщийИтог система выдаст 70.

Метод 2: Применение временных таблиц для получения одной ячейки

Если ваша задача — вывести результат "одной ячейкой" без лишних строк, профессиональным подходом считается использование пакета запросов с временной таблицей. Это гарантирует чистоту данных и удобство последующей обработки.

Рассмотрим подробнее этот алгоритм:

Шаг 1. Подготовка данных. Мы объединяем данные так же, как в первом методе, но помещаем результат во временную таблицу ВТ_ДанныеДляРасчета.

Шаг 2. Агрегация. Во втором запросе пакета мы обращаемся к этой временной таблице и используем функцию СУММА().

Пример реализации в коде 1С:


ВЫБРАТЬ
    Таблица1.Сумма КАК Значение
ПОМЕСТИТЬ ВТ_СводныеДанные
ИЗ
    Документ.ПриходнаяНакладная КАК Таблица1

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

ВЫБРАТЬ
    -Таблица2.Сумма
ИЗ
    Документ.РасходнаяНакладная КАК Таблица2
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СУММА(ВТ_СводныеДанные.Значение) КАК КонечныйРезультат
ИЗ
    ВТ_СводныеДанные КАК ВТ_СводныеДанные

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

Метод 3: Работа через Систему компоновки данных (СКД)

Если вы разрабатываете отчет, то манипуляции внутри самого текста запроса могут быть излишними. В СКД задачу можно решить на уровне ресурсов. Посмотрим на пример настройки:

Во многих случаях удобнее оставить в запросе две разные колонки: СуммаПриход и СуммаРасход. В настройках схемы компоновки данных (вкладка "Ресурсы") вы можете создать пользовательское выражение.

В поле "Выражение" для нового ресурса укажите:

СУММА(СуммаПриход) - СУММА(СуммаРасход)

Преимущество этого метода: Вы сохраняете детальную информацию в отчете (пользователь может увидеть отдельно приходы и отдельно расходы), но в общих итогах будет выведена их разность.

Важные технические нюансы

При работе с объединениями и арифметическими операциями в 1С существуют "подводные камни", которые могут привести к неверному результату или пустым значениям.

1. Обработка значений NULL.

Выясним причину, почему данные могут пропадать. Если в одной из таблиц нет записей, запрос может вернуть NULL. Любая математическая операция с NULL (например, 100 + NULL) дает в результате NULL. Чтобы этого избежать, всегда используйте функцию ЕСТЬNULL().

Пример безопасного выражения:

ЕСТЬNULL(Сумма, 0)

2. Разница между ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ.

Проанализируем ситуацию: оператор ОБЪЕДИНИТЬ (без слова ВСЕ) выполняет проверку на дубликаты и удаляет одинаковые строки. Это не только замедляет запрос, но и фатально для подсчета итогов. Если у вас есть две продажи по 500 рублей, система может оставить только одну. Всегда используйте ОБЪЕДИНИТЬ ВСЕ для корректного суммирования данных.

3. Имена полей.

Помните, что структура результирующей таблицы (названия колонок) всегда определяется первым запросом в объединении. Как бы вы ни называли поля во втором или третьем запросе, они "влетят" в колонки первого запроса в соответствии с их порядковым номером в списке выбора.

Заключение

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

← На главную