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