Как сгруппировать договоры по контрагенту в обработке 1С без использования агрегатных функций?

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

При разработке отчетов или обработок в 1С часто возникает задача визуального представления данных в виде иерархического списка. Например, у нас есть список договоров, и мы хотим, чтобы пользователь видел контрагента как «родительский» элемент, а при раскрытии списка — все его договоры. Часто начинающие разработчики пытаются решить эту задачу средствами языка запросов, используя конструкции ИТОГИ ПО, однако есть более гибкий и профессиональный подход, позволяющий добиться желаемого поведения интерфейса без усложнения кода запроса.

Почему не стоит перегружать запрос агрегатными функциями?

Когда мы пытаемся получить иерархию прямо из запроса, мы ограничиваем гибкость отображения данных. Запрос должен заниматься исключительно выборкой необходимых данных из базы, а их визуальное представление — задача уровня формы и объекта ДеревоЗначений. Если вы используете ИТОГИ ПО в запросе, вы получаете «плоский» результат с итоговыми записями, что не всегда удобно при программной обработке данных в модуле формы. Вместо этого рассмотрим использование структуры, специально предназначенной для иерархии.

Решение с помощью объекта ДеревоЗначений

Наиболее правильным и удобным способом решения задачи «Контрагент -> Список его договоров» является использование элемента управления ДеревоЗначений. Давайте разберем по шагам, как это реализовать на практике.

  1. Создание реквизита: В вашей обработке на вкладке «Реквизиты» добавьте новый реквизит (например, с именем РезультатДерево) и установите ему тип ДеревоЗначений.
  2. Настройка колонок: Для этого дерева необходимо создать колонки, которые будут соответствовать вашим данным. Добавьте колонки «Наименование» (для контрагента и договора), «СсылкаНаДоговор» и другие необходимые поля.
  3. Вывод на форму: Перетащите реквизит РезультатДерево из списка реквизитов на форму обработки. Платформа 1С автоматически создаст элемент управления «Таблица», который поддерживает иерархическое отображение данных.

Программное заполнение дерева

После того как структура готова, необходимо программно заполнить дерево данными, полученными из запроса. Рассмотрим пример, как это сделать максимально эффективно:


// Предположим, запрос уже выполнен и результат находится в переменной РезультатЗапроса
ВыборкаДетальныхЗаписей = РезультатЗапроса.Выбрать();

// Очищаем дерево перед заполнением
РезультатДерево.Строки.Очистить();

Пока ВыборкаДетальныхЗаписей.Следующий() Цикл
    // Ищем строку контрагента (владельца)
    СтрокаКонтрагента = РезультатДерево.Строки.Найти(ВыборкаДетальныхЗаписей.Владелец, "Наименование", Истина);
    
    Если СтрокаКонтрагента = Неопределено Тогда
        // Создаем новую строку контрагента, если её еще нет
        СтрокаКонтрагента = РезультатДерево.Строки.Добавить();
        СтрокаКонтрагента.Наименование = ВыборкаДетальныхЗаписей.Владелец;
    КонецЕсли;
    
    // Добавляем договор в подчиненные строки контрагента
    СтрокаДоговора = СтрокаКонтрагента.Строки.Добавить();
    СтрокаДоговора.Наименование = ВыборкаДетальныхЗаписей.Ссылка;
КонецЦикла;

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

Альтернативные подходы: СКД

Если задача становится более масштабной и требует дополнительных настроек (отборы, сортировки, вывод дополнительных реквизитов), рекомендуем рассмотреть Систему Компоновки Данных (СКД). Это стандарт де-факто в 1С для работы с отчетами. В СКД вам достаточно добавить поле «Владелец» в раздел «Группировки» настроек отчета. Система сама сгенерирует иерархический отчет с итоговыми записями, группировками и возможностью расшифровки, не требуя от вас ручного написания цикла по обходу запроса.

Подведем итоги

Для реализации группировки договоров по владельцу в обработке придерживайтесь следующих рекомендаций:

Такой подход делает ваше решение легко масштабируемым и понятным для других разработчиков, которые будут поддерживать ваш код в будущем.

← На главную