Как в отчете СКД вывести обороты и остатки по всем дням, включая даты без движений

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

При формировании бухгалтерских отчетов, особенно по счету 51 «Расчетные счета», пользователи часто требуют отображать непрерывную календарную шкалу. Бухгалтеру важно видеть ежедневное состояние счета и динамику остатков даже за те дни, в которые движений денежных средств не происходило. Однако типовой отчет «Обороты счета» по умолчанию выводит только периоды, в которых есть реальные проводки, а пустые строки скрывает.

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

Почему в отчете пропадают пустые даты

В типовых решениях (в частности, в конфигурации «Бухгалтерия предприятия») отчеты строятся на базе схемы компоновки данных (СКД). Поведение выборки обусловлено двумя факторами:

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

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

Решение через модуль объекта отчета: программное дополнение периодов

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

Разберем по шагам, как модифицировать код в модуле объекта отчета. Наша цель — найти группировку по периоду, включить для нее тип дополнения и снять отбор на пустые строки.

Откроем модуль объекта отчета и проанализируем процедуру формирования. Встроим следующий блок кода непосредственно перед вызовом процедуры СтандартныеОтчеты.ВывестиОтчет:


Если ВыводитьПолностью Тогда
    ДоработатьКомпоновщикПередВыводом(ВнешниеНаборыДанных);
    КомпоновщикНастроек.Восстановить();
    НастройкаКомпоновкиДанных = КомпоновщикНастроек.ПолучитьНастройки();
    КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);

    // Проверяем, установлена ли периодичность «День» (в типовых отчетах это значение 6)
    Если Периодичность = 6 Тогда
        // Рекурсивно или циклом находим последнюю группировку строк - это группировка по периоду
        ТекСтруктура = НастройкаКомпоновкиДанных.Структура[0].Строки[0].Структура;
        Пока ТекСтруктура.Количество() > 0 Цикл
            ВложеннаяСтруктура = ТекСтруктура[0].Структура;
            Если ВложеннаяСтруктура.Количество() > 0 Тогда
                ТекСтруктура = ВложеннаяСтруктура;
            Иначе
                Прервать;
            КонецЕсли;
        КонецЦикла;

        // Настраиваем автодополнение периода для найденной группировки
        ПолеГруппировки = ТекСтруктура[0].ПоляГруппировки.Элементы[0];
        ПолеГруппировки.ТипДополнения = СтандартныеОтчеты.ПолучитьТипДополненияПоИнтервалу(Периодичность);
        ПолеГруппировки.НачалоПериода = НачалоПериода;
        ПолеГруппировки.КонецПериода = КонецПериода;

        // Очищаем стандартный типовой отбор, отсекающий нулевые показатели
        ТекСтруктура[0].Отбор.Элементы.Очистить();
    КонецЕсли;

    СтандартныеОтчеты.ВывестиОтчет(ЭтотОбъект, Результат, ДанныеРасшифровки, ВыводВФормуОтчета, ВнешниеНаборыДанных, Истина, НастройкаКомпоновкиДанных);
КонецЕсли;

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

  1. Мы анализируем переменную Периодичность. Если пользователь выбрал группировку по дням, активируется наш алгоритм.
  2. Через коллекцию Структура мы проходим до самого нижнего уровня вложенности группировок строк таблицы СКД, где как раз находится группировка по дате.
  3. Свойству ТипДополнения присваивается значение интервала (день), а свойствам НачалоПериода и КонецПериода передаются границы формируемого отчета. Благодаря этому СКД генерирует строки для всех дней диапазона.
  4. Очистка коллекции Отбор.Элементы у группировки предотвращает срабатывание штатного фильтра, который скрывает дни без движений.

Проблема кэширования настроек типового отчета

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

Типовая подсистема стандартных отчетов сохраняет пользовательские настройки во внутреннем хранилище и автоматически восстанавливает их при открытии формы по имени отчета. В результате схема инициализируется старыми системными настройками.

Чтобы избежать наложения сохраненных настроек, выполним простые действия:

  1. Сохраним отчет как внешний (файл с расширением .erf).
  2. В свойствах отчета изменим его Имя и Синоним (например, зададим ОборотыСчетаВсеДни).
  3. Откроем отчет заново через меню Файл — Открыть. Система распознает его как новый объект и применит заложенные в коде модификации настроек.

Альтернативное решение: создание отчета на базе остатков и оборотов

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

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

  1. Выбор таблицы: В качестве источника данных используем виртуальную таблицу РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты с указанием периодичности День.
  2. Настройка ролей полей: На вкладке «Наборы данных» обязательно настраиваем роли: для поля Период указываем тип «Период, 1», а для числовых ресурсов входящего и исходящего сальдо задаем роли НачальныйОстаток и КонечныйОстаток соответственно. Это ключевое условие, позволяющее СКД корректно протягивать сальдо с предыдущего дня на следующий.
  3. Включение дополнения в настройках: В настройках группировки по полю Период на вкладке «Группируемые поля» устанавливаем тип дополнения «День», а также заполняем параметры начала и окончания периода.
  4. Обработка пустых значений: Чтобы вместо пустых ячеек в днях без движений выводились нули, в выражениях ресурсов на вкладке «Ресурсы» используем функцию ЕстьNULL(СуммаОборотДт, 0).

Использование правильной виртуальной таблицы и штатного автодополнения периодов СКД гарантирует получение точных данных без потери производительности базы данных.

← На главную