Как получить родителя верхнего уровня в СКД?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке отчетов на базе СистемаКомпоновкиДанных часто возникает задача сгруппировать данные по «корневому» подразделению или номенклатуре. Однако попытки реализовать эту логику через простые функции в Вычисляемые поля часто приводят к ошибке Значение не является значением объектного типа. Разберем, почему так происходит и как правильно решить эту задачу.

Почему возникают ошибки при использовании функций

Основная причина кроется в архитектуре СКД. При выполнении отчета в Вычисляемые поля попадают не полноценные объекты СправочникСсылка, а их представления или упрощенные типы данных. Обращение через точку (например, Ссылка.Родитель) в таких условиях вызывает исключение. Кроме того, вызов функций для каждой строки отчета крайне негативно сказывается на производительности.

Способ 1: Использование конструкции ВЫБОР КОГДА в запросе

Если глубина вложенности справочника фиксирована и невелика, самым быстрым и надежным способом будет использование логики ВЫБОР КОГДА непосредственно в тексте запроса. Это позволяет выполнить вычисления на стороне сервера СУБД.

Рассмотрим пример реализации:


ВЫБОР 
    КОГДА НЕ Ссылка.Родитель.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Подразделения.ПустаяСсылка) ТОГДА Ссылка.Родитель.Родитель.Родитель
    КОГДА НЕ Ссылка.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Подразделения.ПустаяСсылка) ТОГДА Ссылка.Родитель.Родитель
    КОГДА НЕ Ссылка.Родитель = ЗНАЧЕНИЕ(Справочник.Подразделения.ПустаяСсылка) ТОГДА Ссылка.Родитель
    ИНАЧЕ Ссылка 
КОНЕЦ КАК ВерхнийРодитель

Этот метод работает максимально быстро, так как не требует обращения к объектной модели платформы в процессе вывода данных.

Способ 2: Использование запроса с иерархией

Если уровни вложенности динамические, лучше всего воспользоваться возможностями языка запросов 1С, а именно ключевым словом ИТОГИ ПО с использованием опции ТОЛЬКО ИЕРАРХИЯ. Это позволяет получить структуру родительских элементов наиболее «чистым» способом.

Разберем, как получить родителя через запрос:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ 
    |	Номенклатура.Ссылка КАК Ссылка 
    |ИЗ 
    |	Справочник.Номенклатура КАК Номенклатура 
    |ГДЕ 
    |	Номенклатура.Ссылка = &Ссылка 
    |ИТОГИ ПО 
    |	Ссылка ТОЛЬКО ИЕРАРХИЯ";

Запрос.УстановитьПараметр("Ссылка", Ссылка);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

После выполнения запроса вы можете выгрузить результат в массив или таблицу, где первым элементом и будет искомый «корневой» родитель. Такой подход является наиболее профессиональным при работе с СКД, так как минимизирует риски ошибок доступа к свойствам объектов.

Рекомендации по реализации

  1. Избегайте рекурсии: Рекурсивные вызовы функций в выражениях СКД — это главная причина тормозов отчетов. Старайтесь выносить логику в основной набор данных.
  2. Используйте связи наборов данных: Если необходимо получить дополнительные данные о родителе, настройте Связи наборов данных. Это позволит СКД самостоятельно подтянуть нужные сведения без написания сложного кода.
  3. Проверяйте типы: Если вы всё же используете функции, убедитесь, что передаете в них именно Ссылка, а не строковое представление, используя при отладке точку останова.

Применяя данные методы, вы сможете добиться корректного отображения и группировки данных в отчетах любой сложности, сохраняя при этом высокую скорость работы системы.

← На главную