Как в дерево значений добавить строку, подчиненную родителю верхнего уровня?

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

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

Разбираем базовый принцип добавления строк

Для начала проанализируем структуру объекта ДеревоЗначений. В отличие от обычной таблицы значений, где все строки находятся в одном плоском списке, дерево представляет собой вложенную структуру. У самого объекта есть коллекция Строки, которая содержит элементы верхнего уровня. Однако у каждой конкретной строки дерева также есть своя собственная коллекция Строки.

Если мы выполним стандартную команду Дерево.Строки.Добавить(), система создаст новую строку на самом верхнем уровне иерархии (корень). Чтобы создать подчиненную строку, нам нужно вызвать метод Добавить() не у всего дерева, а у конкретной строки-родителя.

Рассмотрим пример кода для программного объекта на сервере или в обычном приложении:


// 1. Добавляем родительскую строку верхнего уровня
НовыйРодитель = ДеревоОбъект.Строки.Добавить();
НовыйРодитель.Наименование = "Группа товаров";

// 2. Добавляем подчиненную строку именно к этому родителю
НоваяПодчиненная = НовыйРодитель.Строки.Добавить();
НоваяПодчиненная.Наименование = "Товар внутри группы";

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

Особенности работы на управляемых формах (УФ)

Разберем ситуацию, которая часто вызывает затруднения у начинающих разработчиков. На управляемых формах реквизит с типом «Дерево значений» превращается в объект типа ДанныеФормыДерево. У этого объекта и у его строк отсутствует прямое свойство Строки.

Вместо него в управляемом интерфейсе используется метод ПолучитьЭлементы(). Проанализируем, как будет выглядеть аналогичный код для управляемой формы:


// Допустим, "ДеревоНаФорме" — это имя реквизита формы
// Добавляем корень
РодительскаяСтрока = ДеревоНаФорме.ПолучитьЭлементы().Добавить();
РодительскаяСтрока.Название = "Верхний уровень";

// Добавляем подчиненную строку
ПодчиненнаяСтрока = РодительскаяСтрока.ПолучитьЭлементы().Добавить();
ПодчиненнаяСтрока.Название = "Вложенный уровень";

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

Как найти нужного родителя для вставки строки

Рассмотрим ситуацию, когда нам нужно добавить строку не в «только что созданную» ветку, а найти существующего родителя по определенному критерию (например, по артикулу или уникальному идентификатору). Для этого удобно использовать метод НайтиСтроки(), но помните, что он ищет по всему дереву сразу.

Посмотрим на пример реализации поиска и добавления:


ПараметрыОтбора = Новый Структура("ID", "001");
НайденныеСтроки = Дерево.Строки.НайтиСтроки(ПараметрыОтбора, Истина); // Истина — поиск по всем уровням

Если НайденныеСтроки.Количество() > 0 Тогда
    // Берем первого найденного родителя
    ЦелевойРодитель = НайденныеСтроки[0];
    // Добавляем в него подчиненную строку
    НоваяСтрока = ЦелевойРодитель.Строки.Добавить();
    НоваяСтрока.Значение = "Данные";
КонецЕсли;

Метод «Вставить» для управления позицией

Иногда требуется, чтобы новая подчиненная строка появилась не в самом конце списка детей, а в начале или в определенной позиции. Для этого проанализируем метод Вставить(). Он принимает индекс, указывающий на позицию нового элемента (индексация начинается с нуля).

Пример вставки строки в самое начало списка подчиненных элементов:


// Сделаем новую строку первой в списке подчиненных
ИндексПозиции = 0;
НоваяСтрока = РодительскаяСтрока.Строки.Вставить(ИндексПозиции);

Визуальное отображение: разворачивание узла

Выясним важный нюанс пользовательского интерфейса. Если вы программно добавили подчиненную строку в дерево на форме, пользователь может ее не увидеть, так как родительский узел по умолчанию будет свернут (рядом с ним просто появится «плюсик»).

Чтобы программно раскрыть ветку и показать добавленный элемент, выполните следующий код (только для управляемых форм на клиенте):

  1. Получите идентификатор родительской строки через РодительскаяСтрока.ПолучитьИдентификатор().
  2. Используйте метод элемента формы «Таблица» — Развернуть().

// На клиенте
ИдентификаторРодителя = ДобавленнаяСтрока.ПолучитьРодителя().ПолучитьИдентификатор();
Элементы.ГруппаДерево.Развернуть(ИдентификаторРодителя, Ложь); // Ложь — развернуть только этот уровень

Копирование данных между строками

Рассмотрим случай, когда подчиненную строку нужно создать на основе данных другой строки. Чтобы не переносить значения каждой колонки вручную, мы рекомендуем использовать метод ЗаполнитьЗначенияСвойств(). Это значительно сокращает код и уменьшает вероятность ошибок при добавлении новых колонок в дерево.


НоваяСтрока = Родитель.Строки.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник);

Резюмируем: для работы с подчиненными строками всегда нужно обращаться к коллекции дочерних элементов конкретного узла. В обычном приложении это свойство Строки, в управляемом — метод ПолучитьЭлементы(). Не забывайте про возможность поиска существующих узлов и необходимость визуального раскрытия веток для удобства пользователя.

← На главную