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