Как сложить суммы нескольких строк проводок в запросе 1С?

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

При разработке отчетов и обработок в 1С часто возникает задача получить общую сумму по нескольким проводкам одного документа. Например, когда в документе поступления присутствуют проводки по дебету счета 08.03 («Строительство объектов основных средств») и дебету счета 19.04 («НДС по приобретенным материально-производственным запасам») в корреспонденции со счетом 60.01 («Расчеты с поставщиками и подрядчиками»), и требуется получить их общую сумму по кредиту. Разберем по шагам, как правильно объединить такие строки в запросе, почему простая группировка или использование временных таблиц могут приводить к размножению строк, и как этого избежать.

Рассмотрим исходный запрос к виртуальной таблице регистра бухгалтерии, с которого начинается проблема:


ВЫБРАТЬ
    ХозрасчетныйДвиженияССубконто.Регистратор,
    ХозрасчетныйДвиженияССубконто.СчетКт,
    ХозрасчетныйДвиженияССубконто.СчетДт,
    ХозрасчетныйДвиженияССубконто.СубконтоДт1,
    ХозрасчетныйДвиженияССубконто.СубконтоДт2,
    ХозрасчетныйДвиженияССубконто.СубконтоДт3,
    ХозрасчетныйДвиженияССубконто.Сумма КАК Сумма
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(, , Регистратор = &Регистратор, , ) КАК ХозрасчетныйДвиженияССубконто

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

Выясним причину проблемы и почему строки не сворачиваются

Проанализируем ситуацию, возникающую при попытке сложения строк регистра бухгалтерии:

  1. Разные значения в группируемых полях. Механизм СГРУППИРОВАТЬ ПО в языке запросов 1С объединяет строки только при полном совпадении всех неагрегированных полей выборки. Проводка по счету 08.03 и проводка по счету 19.04 имеют разные значения в поле СчетДт. Кроме того, у счетов 08.03 и 19.04 принципиально различается состав субконто: для 08.03 это «Объекты строительства» и «Статьи затрат», а для 19.04 — «Контрагенты» и «Счета-фактуры полученные». Пока эти поля присутствуют в секции ВЫБРАТЬ без агрегации, строки никогда не схлопнутся в одну.
  2. Декартово произведение при соединении временных таблиц. Попытка выгрузить проводки по 08 счету в одну временную таблицу, проводки по 19 счету — в другую, а затем соединить их по полю Регистратор без предварительной группировки приводит к эффекту $M \times N$. Если в документе было несколько строк по счету 08 или по счету 19, строки взаимно перемножаются, в результате чего результирующая таблица разрастается.

Способ 1. Группировка с исключением различающихся полей аналитики

Если конечная цель заключается в том, чтобы получить общую сумму взаиморасчетов по кредиту счета 60.01 в рамках регистратора, нам необходимо исключить из списка выборки и секции группировки все поля, которые уникальны для каждой проводки (в частности, СчетДт и СубконтоДт1...3).

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


ВЫБРАТЬ
    Хозрасчетный.Регистратор КАК Регистратор,
    Хозрасчетный.СчетКт КАК СчетКт,
    Хозрасчетный.СубконтоКт1 КАК Контрагент,
    Хозрасчетный.СубконтоКт2 КАК Договор,
    СУММА(Хозрасчетный.Сумма) КАК ОбщаяСумма
ИЗ
    РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
    Хозрасчетный.Регистратор = &Регистратор
    И Хозрасчетный.СчетКт В ИЕРАРХИИ (&Счет60)
СГРУППИРОВАТЬ ПО
    Хозрасчетный.Регистратор,
    Хозрасчетный.СчетКт,
    Хозрасчетный.СубконтоКт1,
    Хозрасчетный.СубконтоКт2

В данном случае все строки документа, относящиеся к одному и тому же контрагенту и договору по кредиту, корректно просуммируются оператором СУММА в одну строку.

Способ 2. Условное суммирование через ВЫБОР КОГДА (разворот в колонки)

Рассмотрим случай, когда в одной результирующей строке документа требуется одновременно видеть и сумму затрат (08.03), и сумму НДС (19.04), и их общую сумму. Для этого применим конструкцию ВЫБОР КОГДА внутри агрегатной функции СУММА:


ВЫБРАТЬ
    Хозрасчетный.Регистратор КАК Регистратор,
    Хозрасчетный.СчетКт КАК СчетКт,
    СУММА(ВЫБОР
            КОГДА Хозрасчетный.СчетДт = &Счет0803
                ТОГДА Хозрасчетный.Сумма
            ИНАЧЕ 0
        КОНЕЦ) КАК СуммаКапВложений,
    СУММА(ВЫБОР
            КОГДА Хозрасчетный.СчетДт = &Счет1904
                ТОГДА Хозрасчетный.Сумма
            ИНАЧЕ 0
        КОНЕЦ) КАК СуммаНДС,
    СУММА(Хозрасчетный.Сумма) КАК СуммаВсего
ИЗ
    РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
    Хозрасчетный.Регистратор = &Регистратор
    И Хозрасчетный.СчетДт В (&СписокСчетовДт)
СГРУППИРОВАТЬ ПО
    Хозрасчетный.Регистратор,
    Хозрасчетный.СчетКт

Такой подход позволяет сохранить прозрачность расчетов: строки схлопываются до уровня документа и кредитового счета, а суммы по разным дебетовым счетам разносятся по соответствующим колонкам без дублирования.

Способ 3. Корректная работа с временными таблицами

Если логика требует использования временных таблиц (например, для сложной предварительной обработки), разберем, как избежать размножения записей:

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

ВЫБРАТЬ
    ВТ_Проводки.Регистратор КАК Регистратор,
    СУММА(ВТ_Проводки.Сумма) КАК ИтогоСумма
ИЗ
    (ВЫБРАТЬ
        Движения.Регистратор КАК Регистратор,
        Движения.Сумма КАК Сумма
    ИЗ
        РегистрБухгалтерии.Хозрасчетный КАК Движения
    ГДЕ
        Движения.Регистратор = &Регистратор
        И Движения.СчетДт = &Счет0803

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

    ВЫБРАТЬ
        Движения.Регистратор КАК Регистратор,
        Движения.Сумма КАК Сумма
    ИЗ
        РегистрБухгалтерии.Хозрасчетный КАК Движения
    ГДЕ
        Движения.Регистратор = &Регистратор
        И Движения.СчетДт = &Счет1904) КАК ВТ_Проводки
СГРУППИРОВАТЬ ПО
    ВТ_Проводки.Регистратор

Оптимизация производительности: выбор таблицы регистра

Обратим внимание на важную архитектурную деталь платформы 1С: виртуальная таблица ДвиженияССубконто выполняет ресурсоемкие соединения с таблицами значений субконто. Если для решения задачи аналитика дебета (СубконтоДт1...3) в итоговой выборке не нужна, обращаться к виртуальной таблице ДвиженияССубконто не рекомендуется. Для получения сумм проводок конкретного регистратора быстрее и эффективнее использовать реальную физическую таблицу РегистрБухгалтерии.Хозрасчетный с отбором по полю Регистратор.

← На главную