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