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