При разработке бухгалтерских отчетов в 1С (например, отчетов по отклонениям остатков или оборотно-сальдовых ведомостей) часто возникает задача: пользователь выбирает в фильтре конкретные рабочие субсчета (например, 231, 281), а в результирующем отчете требуется отобразить не только выбранные счета, но и их родительские группы (счет 20) с корректным расчетом промежуточных итогов.
Разберем причины, по которым счета верхнего уровня не попадают в выборку автоматически, и рассмотрим по шагам правильные способы реализации иерархического вывода.
Проанализируем специфику работы с планами счетов и регистрами бухгалтерии в платформе 1С:
ЗапретитьИспользоватьВПроводках равен Ложь. Виртуальная таблица РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты физически не содержит записей по счетам-группам. Если передать родительский счет в условие Счет В (&Счет), запрос не вернет по нему данных.ИТОГИ ПО ... ИЕРАРХИЯ не может применяться в запросах, использующих оператор ПОМЕСТИТЬ.ТаблицаЗначений, поля родительских группировок будут пустыми до тех пор, пока они не будут явно настроены на вкладке Ресурсы схемы компоновки данных.Если отчет формируется на базе СКД с программной инициализацией внешнего набора данных (как в процедуре ПриКомпоновкеРезультата), самый простой и надежный путь — переложить построение дерева и расчет итогов на сам механизм компоновки данных.
Разберем по шагам настройку схемы компоновки данных (СКД):
КонечныйОстатокДтТекущий, КонечныйОстатокКтТекущий, ОтклонениеДт, ОтклонениеКт и другие. В поле «Выражение» укажем агрегатную функцию:
Сумма(ОтклонениеДт)
Счет нажмем правой кнопкой мыши, выберем свойства группировки и установим Тип группировки: Иерархия (вместо значения «Элементы»).При выводе отчета процессор компоновки данных автоматически определит родителей для всех выгруженных счетов, создаст вышестоящие узлы и рассчитает по ним суммы числовых ресурсов.
Если вывод строится без схемы компоновки данных напрямую в табличный документ через выборку результата запроса, необходимо сформировать иерархию на уровне языка запросов.
Посмотрим на пример построения секции итогов в финальной части запроса:
ВЫБРАТЬ
ВТ_Отклонение.Организация КАК Организация,
ВТ_Отклонение.Счет КАК Счет,
ВТ_Отклонение.СуммаКонечныйОстатокДт - ВТ_Отклонение1.СуммаКонечныйОстатокДт КАК ОтклонениеДт,
ВТ_Отклонение.СуммаКонечныйОстатокКт - ВТ_Отклонение1.СуммаКонечныйОстатокКт КАК ОтклонениеКт
ИЗ
ВТ_Отклонение КАК ВТ_Отклонение
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Отклонение КАК ВТ_Отклонение1
ПО ВТ_Отклонение.Счет = ВТ_Отклонение1.Счет
ИТОГИ
СУММА(ОтклонениеДт),
СУММА(ОтклонениеКт)
ПО
Счет ИЕРАРХИЯ
Для программного обхода такого результата запроса в коде модуля применяется специальный тип обхода с рекурсией:
РезультатЗапроса = Запрос.Выполнить();
ВыборкаВерхнийУровень = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
Пока ВыборкаВерхнийУровень.Следующий() Цикл
// Вывод родительского счета или детальной записи
ТабДок.Вывести(ОбластьСчет);
ВыборкаДетали = ВыборкаВерхнийУровень.Выбрать();
Пока ВыборкаДетали.Следующий() Цикл
// Вывод подчиненных субсчетов
ТабДок.Вывести(ОбластьСубсчет);
КонецЦикла;
КонецЦикла;
Если требуется передать в параметры запроса или в интерфейсные структуры полный перечень счетов вместе с вышестоящими родителями, выполним предварительный обход выбранного пользователем списка перед инициализацией запроса:
СпСчетовСРодителями = Новый Массив;
Для Каждого ТекСчет Из мСписокСчетов Цикл
СпСчетовСРодителями.Добавить(ТекСчет);
Родитель = ТекСчет.Родитель;
Пока ЗначениеЗаполнено(Родитель) Цикл
Если СпСчетовСРодителями.Найти(Родитель) = Неопределено Тогда
СпСчетовСРодителями.Добавить(Родитель);
КонецЕсли;
Родитель = Родитель.Родитель;
КонецЦикла;
КонецЦикла;
Важно: если добавить родительские счета в условие Счет В (&Счет), остатки из регистра по ним все равно не вернутся, так как проводки привязаны к субсчетам. Поэтому расчет суммовых показателей по добавленным родительским счетам необходимо производить в ресурсах СКД либо программно при обходе таблицы значений.