Как программно реализовать переход из строки ТаблицыЗначений к строке в ДеревеЗначений

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

В процессе разработки сложных интерфейсов на платформе 1С:Предприятие 8 часто возникает задача связать несколько табличных частей или коллекций данных. Типичный сценарий: у нас есть вспомогательная ТаблицаЗначений (например, со списком ошибок или результатов поиска) и основное ДеревоЗначений. Рассмотрим подробнее, как сделать так, чтобы при клике на строку в таблице система автоматически «перебрасывала» пользователя на нужную строку в дереве, даже если она скрыта в иерархии.

Понятие идентификатора строки и фокуса

Для начала разберем ситуацию с точки зрения платформы. Когда мы работаем с управляемыми формами, важно разделять данные (само дерево) и элемент формы (то, что видит пользователь). Для реализации перехода нам понадобится «фокус». Проанализируем, что это такое. Фокус — это состояние, при котором конкретный элемент управления становится активным для ввода, а конкретная строка внутри него подсвечивается как текущая.

Основной механизм связи здесь — это числовой идентификатор строки. В 1С каждая строка таблицы или дерева на форме имеет уникальный внутренний номер. Выясним причину, по которой это важно: свойство ТекущаяСтрока у элемента формы принимает именно этот числовой идентификатор, а не саму строку как объект данных.

Способ 1. Использование динамических идентификаторов

Если ДеревоЗначений заполняется один раз и не перестраивается полностью в процессе работы, мы можем сохранить идентификаторы строк дерева прямо в нашей ТаблицеЗначений. Разберем по шагам, как это реализовать:

  1. В ТаблицеЗначений создадим скрытую колонку ИдентификаторСтрокиДерева (тип: Число).
  2. При заполнении дерева или во время его обхода получим идентификатор каждой строки.
  3. Запишем этот идентификатор в соответствующую строку таблицы.

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


// Обработчик события Выбор в ТаблицеЗначений
&НаКлиенте
Процедура ТаблицаОшибокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь; // Отменяем стандартное действие
    
    // Получаем текущие данные строки таблицы
    ТекущиеДанныеТаблицы = Элементы.ТаблицаОшибок.ТекущиеДанные;
    
    Если ТекущиеДанныеТаблицы <> Неопределено Тогда
        ИдентификаторЦели = ТекущиеДанныеТаблицы.ИдентификаторСтрокиДерева;
        
        // 1. Устанавливаем текущую строку в дереве
        Элементы.ОсновноеДерево.ТекущаяСтрока = ИдентификаторЦели;
        
        // 2. Активизируем само дерево, чтобы пользователь его увидел
        ЭтаФорма.ТекущийЭлемент = Элементы.ОсновноеДерево;
    КонецЕсли;
    
КонецПроцедуры

Способ 2. Связь через уникальные ключи (Естественные ключи)

Проанализируем ситуацию, когда дерево может обновляться, пересчитываться или сортироваться. В этом случае числовые идентификаторы могут измениться, и хранить их «впрок» небезопасно. Рассмотрим более надежный метод — использование ключей связи. В качестве ключа может выступать УникальныйИдентификатор ссылки, артикул или составной ключ из нескольких реквизитов.

В этом случае алгоритм будет следующим:

  1. При нажатии на строку в таблице мы берем значение ключа.
  2. Выполняем поиск в данных дерева по этому ключу.
  3. Получаем объект строки дерева и узнаем его текущий идентификатор.
  4. Выполняем позиционирование.

Рассмотрим пример реализации с поиском на сервере:


&НаКлиенте
Процедура ПерейтиКСтрокеДерева()
    
    КлючСвязи = Элементы.ТаблицаДанных.ТекущиеДанные.КлючСвязи;
    
    // Ищем идентификатор строки в данных дерева на сервере или клиенте
    ИдентификаторСтроки = НайтиИдентификаторПоКлючу(КлючСвязи);
    
    Если ИдентификаторСтроки <> Неопределено Тогда
        // Позиционируем элемент формы
        Элементы.ДеревоДанных.ТекущаяСтрока = ИдентификаторСтроки;
        ЭтаФорма.ТекущийЭлемент = Элементы.ДеревоДанных;
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: Работа с иерархией (Развертывание узлов)

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

Разберем, как правильно развернуть дерево до нужной строки:


// После установки ТекущейСтроки обязательно разворачиваем узел
ИдентификаторНазначения = ДанныеСтрокиДерева.ПолучитьИдентификатор();
Элементы.ДеревоДанных.ТекущаяСтрока = ИдентификаторНазначения;

// Параметр "Истина" означает, что нужно развернуть всю цепочку родителей
Элементы.ДеревоДанных.Развернуть(ИдентификаторНазначения, Истина);

События для инициации перехода

Для создания качественного UX (пользовательского опыта) важно выбрать правильный момент для перехода. Рассмотрим основные варианты:

Заключение

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

← На главную