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