Почему пропадают данные в отчете 1С при использовании ИТОГИ ПО ОБЩИЕ и как это исправить

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

При разработке отчетов в 1С программисты часто сталкиваются с ситуацией: в консоли запросов данные отображаются корректно, но при выводе в макет через программный код данные внезапно «исчезают». Особенно часто это происходит, когда в секцию ИТОГИ добавляется ключевое слово ОБЩИЕ. В этой статье мы подробно разберем, почему так происходит, как меняется структура выборки и как правильно изменить алгоритм обхода результата запроса, чтобы все цифры вернулись на свои места.

Разбираем причину проблемы: иерархия выборки

Когда мы пишем запрос без использования ИТОГИ ПО ОБЩИЕ, метод Выбрать() возвращает нам плоский список или сразу первый уровень указанных группировок. Однако добавление ОБЩИЕ в корень меняет архитектуру результата. Рассмотрим ситуацию: нам нужно посчитать итоги по каждому счету отдельно, а в самом конце вывести общую сумму по всем счетам.

Важный нюанс: как только вы добавляете ОБЩИЕ, в результате запроса появляется «нулевой» уровень — одна единственная строка, содержащая суммарные данные по всему отчету. Теперь все ваши счета и детальные записи находятся «внутри» этой строки. Если ваш старый код просто перебирал выборку в одном цикле Пока Выборка.Следующий(), то теперь он считывает только эту первую итоговую строку и завершает работу, так и не дойдя до самих счетов. Именно это создает иллюзию «исчезновения» данных.

Решение 1: Правильный программный обход иерархии

Для того чтобы вывести данные в макет, когда в запросе есть и общие итоги, и итоги по группировкам, нам необходимо использовать вложенные циклы. Разберем по шагам, как должен выглядеть код обработки результата запроса.

Сначала мы получаем общую выборку. Поскольку мы указали ИТОГИ ПО ОБЩИЕ, первой строкой пойдет общий итог. Чтобы «провалиться» глубже к счетам, нам нужно вызвать метод Выбрать повторно от текущей выборки.


// 1. Получаем результат запроса
РезультатЗапроса = Запрос.Выполнить();

// 2. Выборка самого верхнего уровня (Общие итоги)
ВыборкаОбщийИтог = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаОбщийИтог.Следующий() Цикл
    // Здесь выводим строку с общими итогами в макет, если нужно
    ОбластьИтог.Параметры.Заполнить(ВыборкаОбщийИтог);
    ТабДок.Вывести(ОбластьИтог);
    
    // 3. Переходим на уровень ниже — к группировке "Счет"
    ВыборкаСчет = ВыборкаОбщийИтог.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Счет");
    
    Пока ВыборкаСчет.Следующий() Цикл
        // Выводим итоги по конкретному счету
        ОбластьСчет.Параметры.Заполнить(ВыборкаСчет);
        ТабДок.Вывести(ОбластьСчет);
        
        // 4. Если нужны детальные записи (статьи ДДС), спускаемся еще глубже
        ВыборкаДетали = ВыборкаСчет.Выбрать();
        
        Пока ВыборкаДетали.Следующий() Цикл
            ОбластьСтрока.Параметры.Заполнить(ВыборкаДетали);
            ТабДок.Вывести(ОбластьСтрока);
        КонецЦикла;
    КонецЦикла;
КонецЦикла;

Обратите внимание на использование параметра ОбходРезультатаЗапроса.ПоГруппировкам. Именно он заставляет систему соблюдать вложенность, которую мы описали в тексте запроса в секции ИТОГИ.

Решение 2: Оптимизация текста запроса

Для корректной работы итогов и высокой производительности, особенно в бухгалтерских отчетах, проанализируем сам текст запроса. Использование условий через ИЛИ (как в примере Счет = &Счет1 ИЛИ Счет = &Счет2) внутри виртуальных таблиц может замедлять работу базы данных.

Рекомендуем передавать список счетов массивом. Это позволяет СУБД строить более эффективный план запроса. Также важно использовать АВТОУПОРЯДОЧИВАНИЕ, чтобы система правильно выстроила иерархию при обходе.

Рассмотрим улучшенный вариант запроса:


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

СГРУППИРОВАТЬ ПО
    Счет,
    ВЫБОР
        КОГДА ХозрасчетныйОстаткиИОбороты.Счет = &Счет5001 ТОГДА ХозрасчетныйОстаткиИОбороты.Субконто1
        ИНАЧЕ ХозрасчетныйОстаткиИОбороты.Субконто2
    КОНЕЦ

УПОРЯДОЧИТЬ ПО
    Счет
ИТОГИ
    СУММА(ОстатокНаНачало),
    СУММА(СуммаОборотДт),
    СУММА(СуммаОборотКт),
    СУММА(СуммаКонечныйОстаток)
ПО
    ОБЩИЕ,
    Счет
АВТОУПОРЯДОЧИВАНИЕ

Особенности работы с остатками в итогах

Проанализируем важный технический момент: суммирование ресурсов типа «Остаток». В обычных запросах 1С при использовании СУММА() в итогах остатки могут суммироваться некорректно, если данные задублированы по разным аналитикам (субконто). Система просто сложит все цифры, что приведет к завышению итогового остатка.

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

Почему СКД — лучшее решение?

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

  1. Автоматически строит дерево группировок любой вложенности.
  2. Корректно обрабатывает NULL в значениях субконто.
  3. Позволяет пользователю самому настраивать состав итогов (нужен ли общий итог или только по счетам).
  4. Решает проблему вывода данных, которая в обычном макете требует сложной программной обработки.

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

← На главную