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