Как программно работать с итогами и событиями ДереваЗначений в 1С

Программист Управленческий учет IT и автоматизация бизнеса
← На главную

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

Обращение к строкам и итогам первого уровня

Разберем ситуацию, когда у нас есть дерево значений с номенклатурой, сгруппированной по категориям (например, «Шапки» и «Варежки»). Чтобы получить доступ к данным конкретной группы, необходимо понимать, что ДеревоЗначений состоит из коллекции Строки. Каждая строка этой коллекции, в свою очередь, может содержать свою коллекцию Строки.

Для обращения к итогам первого уровня (самым верхним узлам) мы используем индексацию коллекции строк. Рассмотрим пример кода:


// Допустим, ДЗ — это наше ДеревоЗначений
// Получаем первую корневую строку (например, "Шапки")
СтрокаШапки = ДЗ.Строки[0]; 
ИтогПоШапкам = СтрокаШапки.Количество;

// Получаем вторую корневую строку (например, "Варежки")
СтрокаВарежки = ДЗ.Строки[1];
ИтогПоВарежкам = СтрокаВарежки.Количество;

Если нам необходимо получить общую сумму по колонке только для строк верхнего уровня (игнорируя вложенные детали), платформа предоставляет стандартный метод Итог(). Проанализируем его использование:


// Суммирует значения колонки "Количество" только у строк 0-го уровня
ОбщийИтогВерхнегоУровня = ДЗ.Строки.Итог("Количество");

Доступ к родителю из подчиненной строки

Часто возникает обратная задача: при изменении данных в подчиненной строке (например, «шапка1») нужно обновить итог в родительской строке («Шапки»). У каждой строки дерева есть свойство Родитель. Выясним, как использовать это свойство для пересчета итогов.

Когда пользователь меняет значение в дочерней строке, мы можем программно «подняться» на уровень выше:


// ТекущаяСтрока — это строка, в которой изменили количество
РодительскаяСтрока = ТекущаяСтрока.Родитель;

Если РодительскаяСтрока <> Неопределено Тогда
    // Обнуляем старый итог и считаем заново по всем подчиненным строкам
    НовыйИтог = 0;
    Для Каждого ПодчиненнаяСтрока Из РодительскаяСтрока.Строки Цикл
        НовыйИтог = НовыйИтог + ПодчиненнаяСтрока.Количество;
    КонецЦикла;
    РодительскаяСтрока.Количество = НовыйИтог;
КонецЕсли;

Программное создание колонок и назначение событий

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

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

  1. Сначала вызываем СоздатьКолонки() у табличного поля.
  2. Затем находим нужную колонку в коллекции Колонки элемента формы.
  3. Обращаемся к свойству ЭлементУправления этой колонки.
  4. Используем метод УстановитьДействие, указывая имя события и имя процедуры-обработчика.

Посмотрим на пример реализации в процедуре ПриОткрытии:


Процедура ПриОткрытии()
    // Создаем колонки на основании структуры ДереваЗначений
    ЭлементыФормы.РезультатДерево.СоздатьКолонки();
    
    // Получаем колонку, для которой нужно событие изменения
    КолонкаКоличество = ЭлементыФормы.РезультатДерево.Колонки.Количество;
    
    // Назначаем обработчик "ПриИзменении" для элемента управления (ПолеВвода) в этой колонке
    ДействиеПриИзменении = Новый Действие("КоличествоПриИзменении");
    КолонкаКоличество.ЭлементУправления.УстановитьДействие("ПриИзменении", ДействиеПриИзменении);
КонецПроцедуры

// Процедура-обработчик должна быть объявлена с ключевым словом Экспорт
Процедура КоличествоПриИзменении(Элемент) Экспорт
    // Здесь пишем логику пересчета итогов родителя
    ТекущаяСтрока = ЭлементыФормы.РезультатДерево.ТекущаяСтрока;
    // ... логика пересчета ...
КонецПроцедуры

Выборочный обход строк дерева

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

Например, если нам нужно обработать только первые две «дочки» у определенного родителя, мы сделаем следующее:


НужныйРодитель = ДЗ.Строки[0]; // Выбираем первого родителя
КоличествоДочек = НужныйРодитель.Строки.Количество();

// Обходим только первые две строки, если их достаточно
Для Индекс = 0 По Мин(1, КоличествоДочек - 1) Цикл
    ТекущаяДочка = НужныйРодитель.Строки[Индекс];
    // Выполняем действия с ТекущаяДочка
КонецЦикла;

Важные нюансы и рекомендации

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

Таким образом, мы проанализировали основные механизмы работы с иерархией в 1С. Использование свойств Родитель, методов обхода коллекций и программное назначение действий через УстановитьДействие позволяет создавать гибкие и интерактивные интерфейсы для работы со сложными данными.

← На главную