При разработке на платформе 1С:Предприятие 8 часто возникает ситуация, когда в табличной части (ТЧ) содержатся данные, имеющие логическую иерархию. Например, список контрагентов с их группами или перечень задач с подзадачами. Разработчики замечают в палитре свойств элемента формы Таблица свойство Отображение, где можно выбрать значение Дерево. Однако после установки этого свойства табличная часть все равно остается плоским списком. В этой статье мы подробно разберем, почему так происходит, как работает механизм отображения и какими способами можно добиться иерархического вида.
Для начала проанализируем устройство элементов управляемой формы. В 1С существует четкое разделение между данными (реквизитами формы) и элементами управления (визуальным представлением). Элемент ТаблицаФормы является универсальным «окном» для вывода данных разных типов. Мы можем связать одну и ту же таблицу на форме с:
ДинамическийСписок).ТабличнаяЧасть).ТаблицаЗначений).ДеревоЗначений).Свойство Отображение (со значениями Список, Иерархический список, Дерево) принадлежит именно элементу управления ТаблицаФормы. Платформа отображает это свойство в конфигураторе всегда, потому что она не знает заранее, какой тип данных вы программно можете подсунуть в эту таблицу в процессе работы. Однако режим дерева активируется только в том случае, если сам источник данных поддерживает иерархию.
Важный нюанс: Табличная часть и Таблица значений — это по определению плоские структуры данных. У них нет встроенного поля Родитель для строк, и они не поддерживают вложенность на уровне коллекции. Поэтому, даже если вы установите Отображение = Дерево, платформа не сможет построить связи, так как в ТабличнойЧасти каждая строка независима и имеет только порядковый номер.
Если вам необходимо полноценное интерактивное редактирование данных в виде иерархии, единственным штатным решением будет использование реквизита формы с типом ДеревоЗначений. Рассмотрим алгоритм действий, как связать данные вашей ТЧ с визуальным деревом.
Разберем ситуацию: у нас есть ТЧ СоставНоменклатуры, и мы хотим отображать ее как дерево. Поскольку ТЧ не может быть деревом, мы создаем на форме вспомогательный реквизит ДеревоДанных с типом ДеревоЗначений.
Проанализируем процесс переноса данных из плоской ТЧ в иерархическое дерево — реализовать это поможет инструментарий отладки и заполнения дерева значений в 1С. Нам потребуется рекурсивная функция. Посмотрим на пример кода:
&НаСервере
Процедура ЗаполнитьДеревоИзТабличнойЧасти()
// Конвертируем ТЧ в таблицу значений для удобства обработки
ТЗ = Объект.СоставНоменклатуры.Выгрузить();
// Очищаем дерево на форме
ДеревоОбъект = РеквизитФормыВЗначение("ДеревоДанных");
ДеревоОбъект.Строки.Очистить();
// Допустим, у нас в ТЗ есть колонки "Номенклатура" и "РодительНоменклатуры"
// Здесь мы должны программно выстроить иерархию, перебирая строки
// и добавляя их в соответствующие коллекции "Строки" дерева
Для Каждого СтрокаТЗ Из ТЗ Цикл
// Логика поиска родителя и добавления подчиненной строки
КонецЦикла;
ЗначениеВРеквизитФормы(ДеревоОбъект, "ДеревоДанных");
КонецПроцедуры
При использовании этого метода важно помнить, что при сохранении объекта вам придется выполнить обратную операцию: «свернуть» дерево обратно в плоскую табличную часть, чтобы данные записались в базу данных.
Если ваша задача — только отображать данные (например, для выбора или просмотра), и вам не нужно редактировать каждую ячейку ТЧ «на лету», лучше использовать ДинамическийСписок. Рассмотрим, почему это работает:
Контрагенты).Отображение = Дерево заработает автоматически «из коробки» без написания кода.Однако помните, что динамический список не предназначен для массового ввода новых строк прямо в таблице. Он удобен для выбора из уже существующих данных.
Иногда разработчики хотят избежать использования ДереваЗначений из-за сложности синхронизации данных. В этом случае можно прибегнуть к хитрости: оставить таблицу плоской, но визуально «показать» иерархию. Выясним, как это реализовать:
Мы можем программно изменять текст в основной колонке, добавляя отступы. Например, для элементов первого уровня отступов нет, для второго — два пробела, для третьего — четыре. Рассмотрим пример формирования строки для вывода:
&НаСервере
Функция ПолучитьПредставлениеСУчетомУровня(ЭлементСправочника)
Уровень = ЭлементСправочника.Уровень();
Отступ = "";
Для Сч = 1 По Уровень Цикл
Отступ = Отступ + " "; // Добавляем 4 пробела за каждый уровень
КонецЦикла;
Возврат Отступ + Строка(ЭлементСправочника);
КонецФункции
Такой подход создает иллюзию вложенности, но у него есть существенные минусы: нельзя сворачивать и разворачивать узлы (группы), так как для платформы это все еще плоский список строк. Для альтернативного решения задачи вывода иерархических данных подойдёт метод отображения через две связанные табличные части.
Проанализировав все возможности платформы 1С, мы можем сделать следующие выводы:
Дерево, источник данных должен поддерживать вложенность строк (как объект ДеревоЗначений).ДеревоЗначений. Да, это потребует написания кода для синхронизации с Табличной Частью, но это единственный стабильный способ обеспечить полноценный UI.ДинамическийСписок с указанием основной таблицы.ТабличнуюЧасть иерархической «одной галочкой» в свойствах — архитектура 1С предполагает, что ТЧ всегда плоская.Использование правильного типа данных (ДеревоЗначений) вместо попыток «взломать» поведение ТабличнойЧасти сэкономит время при поддержке кода и обеспечит пользователю привычный интерфейс с возможностью раскрытия и сворачивания групп.