При разработке отчетов на Системе компоновки данных (СКД) программисты часто сталкиваются со следующей проблемой: в основном отчете (например, оборотно-сальдовой ведомости по счетам) остатки и обороты выводятся идеально. Но как только конечный пользователь делает расшифровку по регистраторам (документам движения), итоговые строки по начальным и конечным остаткам превращаются в бессмысленную сумму всех строк детальных записей. Вместо правильного сальдо на начало и конец периода платформа просто складывает все числа по вертикали.
В этой статье мы подробно разберем, почему так происходит, рассмотрим несколько эффективных способов решения этой проблемы, а также детально изучим сложные и редко документируемые бухгалтерские роли полей СКД, такие как «Счет», «Бух. тип» и «Поле счета».
Для того чтобы СКД могла рассчитать остатки правильно, ей необходимо понимать хронологическую последовательность записей. Остаток — это не просто число, которое можно суммировать (как оборот). Начальный остаток по группировке должен браться из первой временной точки этой группировки, а конечный остаток — из последней.
Когда мы выводим отчет в разрезе регистраторов без правильной настройки ролей периодов, СКД теряет информацию о временной оси. Для нее записи документов становятся рядовым набором строк, и она применяет к ним стандартную агрегатную функцию СУММА(), что приводит к математически неверным итогам.
Давайте разберем по шагам, как решить эту задачу различными путями в зависимости от ваших требований к отчету.
Если вам нужно получить полноценную расшифровку по регистраторам, где в строках документов отображаются корректные остатки и обороты, а в строке Итого выводится правильное сальдо на начало и конец всего периода, необходимо настроить иерархию периодов.
ПериодСекунда, Регистратор и при необходимости НомерСтроки.ПериодСекунда (или основного поля периода) укажите роль: Период, порядковый номер 3 (или 2, если нет номера строки).Регистратор укажите роль: Период, порядковый номер 2 (или 1).НомерСтроки (важно для документов, делающих несколько движений по одному счету в одну секунду), укажите роль: Период, порядковый номер 1.СуммаНачальныйОстаток и СуммаКонечныйОстаток) настройте роль «Остатки». В параметре «Имя» укажите одинаковое имя группы остатков (например, «Сумма»), а в параметре «Тип» укажите соответственно «НачальныйОстаток» и «КонечныйОстаток».Благодаря непрерывной нумерации периодов в ролях, СКД выстроит правильную временную шкалу и рассчитает итоги корректно, выбирая крайние точки для остатков.
Часто бизнес-требования звучат иначе: «В строках с регистраторами остатки вообще показывать не нужно (пусть там будут только обороты), но в итоговых строках по счетам остатки должны быть обязательно». Это самый лаконичный и простой способ, не требующий изменения запроса.
Для реализации этого сценария выполним следующие действия:
СуммаНачальныйОстаток).Счет, Субконто1, Организация.Регистратор.При таком подходе в детальных строках с документами колонки остатков автоматически останутся пустыми, не загромождая отчет лишней информацией, а на уровне счетов и общих итогов остатки будут рассчитаны абсолютно верно.
Рассмотрим метод, к которому пришел автор обсуждения на форуме. Этот способ гарантирует, что в детальных записях документов остатки будут равны NULL (пустыми), а обороты заполнятся штатно.
Суть метода заключается в объединении трех таблиц в одном запросе:
Регистратор для этих записей выбирается как NULL).Регистратор заполнено реальными документами).Регистратор снова выбирается как NULL).При объединении (оператор ОБЪЕДИНИТЬ ВСЕ) у нас появятся строки с пустым регистратором, содержащие только начальные и конечные остатки. Чтобы в расшифровке по регистраторам не выводилась паразитная пустая строка с общими остатками, настроим роль поля Регистратор:
В настройках поля Регистратор на вкладке «Наборы данных» в роли поля установите флаг «Игнорировать значения NULL». В этом случае СКД проигнорирует группировку по пустым значениям регистратора, и в детальные записи попадут только реальные документы с оборотами.
Если вам нужно быстро визуально скрыть остатки по строкам документов без изменения схемы компоновки данных, мы можем прибегнуть к условному оформлению отчета.
Текст и оставьте его значение пустым (или укажите пробел), либо установите свойство Видимость = Ложь.Регистратор Заполнено.Этот метод прост, но имеет минус — колонки остатков останутся в таблице, просто их ячейки напротив документов станут пустыми.
Если вам необходимо динамически управлять составом колонок при открытии расшифровки, мы можем перехватить процесс компоновки результата в модуле объекта отчета.
Проанализируем пример кода, который определяет выполнение расшифровки и программно отключает видимость полей остатков, оставляя только обороты:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// Проверим, выполняется ли формирование отчета в режиме расшифровки
Если ДанныеРасшифровки <> Неопределено Тогда
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// Определим, выводится ли группировка по регистратору
Если СодержитГруппировку(Настройки.Структура, "Регистратор") Тогда
// Пробегаем по выбранным полям и отключаем остатки
Для Каждого Поле Из Настройки.ВыбранныеПоля.Элементы Цикл
Если ТипЗнч(Поле) = Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
ПутьКПолю = Строка(Поле.Поле);
Если ПутьКПолю = "СуммаНачальныйОстаток" Или ПутьКПолю = "СуммаКонечныйОстаток" Тогда
Поле.Использование = Ложь;
КонецЕсли;
КонецЕсли;
КонецЦикла;
// Загружаем измененные настройки обратно в компоновщик
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция СодержитГруппировку(КоллекцияГруппировок, ИмяПоля) Экспорт
Для Каждого Элемент Из КоллекцияГруппировок Цикл
Если ТипЗнч(Элемент) = Тип("ГруппировкаКомпоновкиДанных") Тогда
Для Каждого ПолеГруппировки Из Элемент.ПоляГруппировки.Элементы Цикл
Если Строка(ПолеГруппировки.Поле) = ИмяПоля Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
// Рекурсивно проверяем вложенные группировки
Если СодержитГруппировку(Элемент.Структура, ИмяПоля) Тогда
Возврат Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
EndФункции
В завершение разберем тонкие настройки ролей полей СКД для бухгалтерского учета, о которых часто умалчивает официальная документация. Без понимания этих параметров невозможно построить сложную ОСВ по активно-пассивным счетам.
Когда вы заходите в конструктор роли числового поля-ресурса, вы видите дополнительные параметры в разделе «Остатки»:
Счет). Этот флаг дает понять системе компоновки, что данное поле определяет иерархическую структуру бухгалтерских счетов и влияет на поведение ресурсов. В параметре «Вид» указывается выражение (обычно имя реквизита счета), определяющее активность счета (Активный, Пассивный, Активно-Пассивный).
СуммаНачОстДт, СуммаНачОстКт, СуммаКонОстДт и СуммаКонОстКт укажите общее имя группы "Сумма". Это позволяет СКД автоматически сопоставлять дебетовые и кредитовые сальдо и правильно "сворачивать" их на разных уровнях иерархии группировок.
Дебет или Кредит. Помогает СКД определять знак операции при расчете конечного сальдо в зависимости от активности счета.
"Счет"). Это связывает конкретный ресурс остатка со счетом учета. Опираясь на эту связь, СКД понимает, к какому именно счету относится данный числовой показатель остатка, и динамически рассчитывает развернутое или свернутое сальдо.
Используя комбинацию правильной настройки ролей периодов, ограничения расчета ресурсов и параметров бухгалтерского учета, вы сможете создавать гибкие и профессиональные отчеты на платформе 1С, которые будут радовать пользователей корректными данными при любых вариантах расшифровки.