При формировании бухгалтерских отчетов, особенно по счету 51 «Расчетные счета», пользователи часто требуют отображать непрерывную календарную шкалу. Бухгалтеру важно видеть ежедневное состояние счета и динамику остатков даже за те дни, в которые движений денежных средств не происходило. Однако типовой отчет «Обороты счета» по умолчанию выводит только периоды, в которых есть реальные проводки, а пустые строки скрывает.
Разберем природу этой задачи, выясним причину стандартного поведения системы и подробно рассмотрим, как реализовать вывод всех дат периода с помощью встроенных возможностей СКД и встроенного языка 1С.
В типовых решениях (в частности, в конфигурации «Бухгалтерия предприятия») отчеты строятся на базе схемы компоновки данных (СКД). Поведение выборки обусловлено двумя факторами:
РегистрБухгалтерии.Хозрасчетный.Обороты. Если в определенный день проводок не было, физических записей в таблице нет, и этот день вовсе не попадает в выборку запроса.Попытка решить задачу путем прямого соединения таблицы оборотов с производственным календарем внутри запроса часто заводит в тупик: обороты соединить можно, но получить правильные входящие и исходящие сальдо на каждый пустой день через таблицу оборотов невозможно, так как она не хранит остатков.
Система компоновки данных имеет встроенный штатный функционал — дополнение периодов. Если в группировке указано поле с типом «Дата», СКД способна автоматически сгенерировать недостающие строки календаря. Но поскольку типовой отчет управляется общим модулем СтандартныеОтчеты, нам потребуется программно вмешаться в структуру настроек перед выводом.
Разберем по шагам, как модифицировать код в модуле объекта отчета. Наша цель — найти группировку по периоду, включить для нее тип дополнения и снять отбор на пустые строки.
Откроем модуль объекта отчета и проанализируем процедуру формирования. Встроим следующий блок кода непосредственно перед вызовом процедуры СтандартныеОтчеты.ВывестиОтчет:
Если ВыводитьПолностью Тогда
ДоработатьКомпоновщикПередВыводом(ВнешниеНаборыДанных);
КомпоновщикНастроек.Восстановить();
НастройкаКомпоновкиДанных = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
// Проверяем, установлена ли периодичность «День» (в типовых отчетах это значение 6)
Если Периодичность = 6 Тогда
// Рекурсивно или циклом находим последнюю группировку строк - это группировка по периоду
ТекСтруктура = НастройкаКомпоновкиДанных.Структура[0].Строки[0].Структура;
Пока ТекСтруктура.Количество() > 0 Цикл
ВложеннаяСтруктура = ТекСтруктура[0].Структура;
Если ВложеннаяСтруктура.Количество() > 0 Тогда
ТекСтруктура = ВложеннаяСтруктура;
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
// Настраиваем автодополнение периода для найденной группировки
ПолеГруппировки = ТекСтруктура[0].ПоляГруппировки.Элементы[0];
ПолеГруппировки.ТипДополнения = СтандартныеОтчеты.ПолучитьТипДополненияПоИнтервалу(Периодичность);
ПолеГруппировки.НачалоПериода = НачалоПериода;
ПолеГруппировки.КонецПериода = КонецПериода;
// Очищаем стандартный типовой отбор, отсекающий нулевые показатели
ТекСтруктура[0].Отбор.Элементы.Очистить();
КонецЕсли;
СтандартныеОтчеты.ВывестиОтчет(ЭтотОбъект, Результат, ДанныеРасшифровки, ВыводВФормуОтчета, ВнешниеНаборыДанных, Истина, НастройкаКомпоновкиДанных);
КонецЕсли;
Рассмотрим подробнее логику работы этого фрагмента:
Периодичность. Если пользователь выбрал группировку по дням, активируется наш алгоритм.Структура мы проходим до самого нижнего уровня вложенности группировок строк таблицы СКД, где как раз находится группировка по дате.ТипДополнения присваивается значение интервала (день), а свойствам НачалоПериода и КонецПериода передаются границы формируемого отчета. Благодаря этому СКД генерирует строки для всех дней диапазона.Отбор.Элементы у группировки предотвращает срабатывание штатного фильтра, который скрывает дни без движений.После внесения изменений в отчет разработчики часто сталкиваются с ситуацией, когда отчет продолжает открываться со старыми параметрами и пустые строки не выводятся. Выясним причину этой проблемы.
Типовая подсистема стандартных отчетов сохраняет пользовательские настройки во внутреннем хранилище и автоматически восстанавливает их при открытии формы по имени отчета. В результате схема инициализируется старыми системными настройками.
Чтобы избежать наложения сохраненных настроек, выполним простые действия:
.erf).ОборотыСчетаВсеДни).Если задача заключается не только в отображении пустых оборотов, но и в непрерывном показе остатка на каждый день (переходящего сальдо), доработка типового отчета «Обороты счета» может оказаться избыточно сложной из-за ограничений виртуальной таблицы оборотов.
В этом случае рассмотрим более надежный архитектурный подход — создание собственного внешнего отчета с нуля:
РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты с указанием периодичности День.Период указываем тип «Период, 1», а для числовых ресурсов входящего и исходящего сальдо задаем роли НачальныйОстаток и КонечныйОстаток соответственно. Это ключевое условие, позволяющее СКД корректно протягивать сальдо с предыдущего дня на следующий.Период на вкладке «Группируемые поля» устанавливаем тип дополнения «День», а также заполняем параметры начала и окончания периода.ЕстьNULL(СуммаОборотДт, 0).Использование правильной виртуальной таблицы и штатного автодополнения периодов СКД гарантирует получение точных данных без потери производительности базы данных.