Как правильно рассчитать остатки и итоги по регистратору в отчете 1С?

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

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

Разберем первопричину проблемы: поле Регистратор формирует исключительно обороты за период. Остаток — это моментный показатель (состояние на определенную точку на оси времени), а не интервальный. Простое суммирование конечных остатков по строкам документов-регистраторов приводит к получению бессмысленного числа, так как складываются остатки на разные последовательные моменты времени. Корректный общий итог по остатку — это остаток на конец всего выбранного периода отчета, а в строке документа — это остаток строго после проведения данного конкретного регистратора.

Решение проблемы при использовании Системы компоновки данных (СКД)

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

  1. Корректировка текста запроса:

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

    Посмотрим на пример правильного запроса к регистру бухгалтерии:

    
    ВЫБРАТЬ
        ХозрасчетныйОстаткиИОбороты.ПериодСекунда КАК ПериодСекунда,
        ХозрасчетныйОстаткиИОбороты.Регистратор КАК Регистратор,
        ХозрасчетныйОстаткиИОбороты.НомерСтроки КАК НомерСтроки,
        ХозрасчетныйОстаткиИОбороты.Субконто1 КАК РасчетныйСчет,
        ХозрасчетныйОстаткиИОбороты.СуммаНачальныйОстаток КАК СуммаНачальныйОстаток,
        ХозрасчетныйОстаткиИОбороты.СуммаОборотДт КАК СуммаОборотДт,
        ХозрасчетныйОстаткиИОбороты.СуммаОборотКт КАК СуммаОборотКт,
        ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстаток КАК СуммаКонечныйОстаток
    ИЗ
        РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
            &НачалоПериода,
            &КонецПериода,
            Авто,
            ,
            Счет = &Счет,
            &МассивСубконто,
            {(Субконто1 = &РасчетныйСчет)}) КАК ХозрасчетныйОстаткиИОбороты
    
  2. Настройка ролей полей на вкладке «Наборы данных»:

    Перейдем на вкладку «Наборы данных» схемы компоновки данных и укажем роли для полей периодов и остатков:

    1. Для поля ПериодСекунда: флажок «Период», порядковый номер 1.
    2. Для поля Регистратор: флажок «Период», порядковый номер 2, дополнительное поле (при необходимости).
    3. Для поля НомерСтроки: флажок «Период», порядковый номер 3.
    4. Для поля СуммаНачальныйОстаток: роль «Остаток», тип остатка — НачальныйОстаток, имя группы остатков — Сумма.
    5. Для поля СуммаКонечныйОстаток: роль «Остаток», тип остатка — КонечныйОстаток, имя группы остатков — Сумма.
  3. Настройка ресурсов:

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

Решение в классическом запросе (без СКД)

Если отчет строится с помощью прямого выполнения запроса и вывода через ТабличныйДокумент без СКД, суммировать конечные остатки в секции ИТОГИ категорически нельзя. Рассмотрим, как правильно организовать расчет.

  1. Расчет итоговых остатков через формулу:

    В секции ИТОГИ агрегатная функция СУММА() применяется только к оборотам (СуммаОборотДт, СуммаОборотКт). Итоговый остаток вычисляется вручную по формуле: для активного счета — НачальныйОстаток + СуммаОборотДт - СуммаОборотКт, для пассивного счета — НачальныйОстаток + СуммаОборотКт - СуммаОборотДт.

  2. Вычисление остатка нарастающим итогом в коде:

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

    Посмотрим на пример алгоритма обхода выборки:

    
    ТекущийОстаток = ВыборкаСчет.СуммаНачальныйОстаток;
    
    Пока ВыборкаРегистратор.Следующий() Цикл
        // Для активного счета расчет остатка после проведения строки:
        ТекущийОстаток = ТекущийОстаток + ВыборкаРегистратор.СуммаОборотДт - ВыборкаРегистратор.СуммаОборотКт;
        
        ОбластьСтрока.Параметры.Заполнить(ВыборкаРегистратор);
        ОбластьСтрока.Параметры.ОстатокНаСчете = ТекущийОстаток;
        ТабличныйДокумент.Вывести(ОбластьСтрока);
    КонецЦикла;
    

Таким образом, для получения корректных итогов в разрезе регистратора всегда разделяйте оборотные и моментные показатели, обязательно включайте в выборку поля периодов (ПериодСекунда, НомерСтроки) и начальный остаток, а в СКД корректно заполняйте роли полей.

← На главную