Как программно заполнить дерево значений на обычной форме 1С?

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

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

Анализ проблемы: почему вложенные элементы не отображаются?

Когда мы заполняем дерево значений программно, используя результат запроса с обходом ПоГруппировкамСИерархией, основная сложность заключается в правильной передаче коллекций строк в рекурсивную функцию. Если передавать в процедуру само дерево вместо его коллекции строк или пытаться подменить объект Значение у табличного поля, связь с колонками, настроенными в дизайнере, может нарушиться.

Выясним основные причины отсутствия вложенных уровней:

Правильная реализация рекурсивного заполнения

Для корректного заполнения дерева из результата запроса лучше всего использовать рекурсивную процедуру, которая принимает на вход коллекцию строк-источников (из результата запроса) и коллекцию строк-приемников (строки дерева на форме). Рассмотрим этот метод подробнее.

Сначала подготовим данные в процедуре ПриОткрытии или в обработчике нажатия кнопки:


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

РезультатЗапроса = Запрос.Выполнить();

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

// Очищаем текущее дерево на форме (реквизит ТабличноеПоле1)
ТабличноеПоле1.Строки.Очистить();

// Запускаем рекурсивное заполнение
ЗаполнитьДеревоРекурсивно(ДЗИсточник.Строки, ТабличноеПоле1.Строки);

Теперь разберем саму рекурсивную процедуру ЗаполнитьДеревоРекурсивно. Основная задача здесь — создать новую строку в приемнике, скопировать в нее данные из источника и, если у источника есть вложенные строки, вызвать эту же процедуру для них.


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

Важные настройки интерфейса

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

  1. Свойство «Отображать иерархию»: Откройте свойства колонки, которая должна содержать дерево развертывания (обычно это первая колонка). Убедитесь, что флаг «Отображать иерархию» установлен. В обычных формах иерархия жестко привязана к первой видимой колонке.
  2. Связь с данными: Проверьте, что в свойствах каждой колонки табличного поля в поле «Данные» указано имя колонки из дерева значений. Если вы программно добавляете колонки в объект ДеревоЗначений через Колонки.Добавить(), убедитесь, что их имена в точности совпадают с настройками на форме.
  3. Метод СоздатьКолонки(): Старайтесь избегать использования метода ЭлементыФормы.ТабличноеПоле1.СоздатьКолонки() после заполнения данных. Этот метод сбрасывает все визуальные настройки (ширину, заголовки, привязки), сделанные в конфигураторе. Правильнее заранее настроить структуру дерева, чтобы она соответствовала результату запроса.

Как автоматически развернуть дерево?

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


// Пример развертывания первого уровня
Для Каждого СтрокаУровня1 Из ТабличноеПоле1.Строки Цикл
    ЭлементыФормы.ТабличноеПоле1.Развернуть(СтрокаУровня1, Ложь);
КонецЦикла;

Если требуется развернуть все уровни, необходимо реализовать аналогичный рекурсивный обход, вызывая ЭлементыФормы.ТабличноеПоле1.Развернуть(ТекущаяСтрока, Истина) для каждого родительского узла.

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

← На главную