Как получить и использовать идентификатор строки дерева значений в 1С

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

При работе с деревьями значений в управляемых формах 1С часто возникает необходимость «запомнить» конкретную строку, чтобы вернуться к ней позже. Например, если при обработке данных возникла ошибка, мы хотим сохранить ссылку на проблемную строку и при нажатии на уведомление сфокусировать на ней внимание пользователя. В этой статье мы подробно разберем, как работают идентификаторы строк, чем они отличаются от самих данных и как правильно организовать поиск в иерархической структуре дерева.

Различие между данными формы и объектом дерева

Прежде всего, проанализируем важный технический нюанс. В 1С существует два принципиально разных состояния дерева значений. Первое — это объект ДеревоЗначений, который живет на сервере в оперативной памяти. У такого объекта нет встроенных числовых идентификаторов строк. Второе — это ДанныеФормыДерево, реквизит управляемой формы, который визуализируется в интерфейсе. Именно у этого типа данных появляются уникальные числовые идентификаторы строк, с которыми мы и будем работать.

Как получить идентификатор текущей строки

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


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

Если ИдентификаторСтроки <> Неопределено Тогда
    Сообщить("Вы выбрали строку с номером: " + ИдентификаторСтроки);
КонецЕсли;

Важно помнить, что ТекущаяСтрока в данном контексте — это не сама строка (не объект с данными), а именно целое число. Это число является уникальным ключом строки в рамках текущего сеанса работы формы.

Использование метода ПолучитьИдентификатор()

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


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

Метод ПолучитьИдентификатор() принимает объект строки (тип ДанныеФормыЭлементДерева) и возвращает его числовой ID. Это крайне удобно, так как идентификатор легко передавать между клиентом и сервером в качестве параметра.

Как найти строку по сохраненному идентификатору

Выясним, как выполнить обратную операцию. Допустим, у нас есть сохраненное число (ID), и мы хотим получить доступ к данным строки (например, прочитать значение в колонке Сумма или Статус). Для этого используется метод НайтиПоИдентификатору(). Проанализируем пример кода:


// Предположим, СохраненныйID был получен ранее
Идентификатор = Число(СохраненныйID);

// Ищем строку в реквизите формы
СтрокаОбъект = РеквизитДерево.НайтиПоИдентификатору(Идентификатор);

Если СтрокаОбъект <> Неопределено Тогда
    // Мы нашли строку, теперь можем менять её данные
    СтрокаОбъект.Статус = "Обработано";
Иначе
    Сообщить("Строка больше не существует в дереве!");
КонецЕсли;

Обратите внимание: если дерево значений было полностью обновлено (например, методом ЗначениеВРеквизитФормы), старые идентификаторы перестают существовать. Метод НайтиПоИдентификатору() в таком случае вернет Неопределено.

Работа с иерархией: поиск родителя и навигация

Одним из преимуществ использования идентификаторов в дереве является то, что НайтиПоИдентификатору() работает «сквозь» всю иерархию. Вам не нужно знать, на каком уровне вложенности находится строка. Однако, найдя строку, вам может потребоваться узнать, кто является её родителем. Посмотрим, как это сделать:


// Находим строку
ЦелеваяСтрока = РеквизитДерево.НайтиПоИдентификатору(НужныйИд);

Если ЦелеваяСтрока <> Неопределено Тогда
    Родитель = ЦелеваяСтрока.ПолучитьРодителя();
    
    Если Родитель <> Неопределено Тогда
        Сообщить("Родитель найден: " + Родитель.НаименованиеГруппы);
    Иначе
        Сообщить("Это строка верхнего уровня");
    КонецЕсли;
КонецЕсли;

Практические советы и ограничения

Рассмотрим несколько важных моментов, которые помогут избежать ошибок при разработке:

  1. Срок жизни ID: Идентификатор строки гарантированно уникален только до тех пор, пока дерево на форме не будет перестроено или очищено. Если ваша логика подразумевает долгое хранение ссылки (например, между разными днями работы пользователя), идентификаторы форм использовать нельзя. В этом случае добавьте в дерево скрытую колонку УникальныйИдентификатор и генерируйте Новый УникальныйИдентификатор() при создании каждой строки.
  2. Передача на сервер: Числовой идентификатор — это примитивный тип данных. Вы можете смело передавать его в процедуры &НаСервере, выполнять там поиск по дереву, менять данные и результат сразу отобразится у пользователя.
  3. Фокусировка в интерфейсе: Чтобы не просто найти строку в коде, но и показать её пользователю (выделить цветом или курсором), используйте установку свойства ТекущаяСтрока у элемента формы:

// Программная установка фокуса на строку
Элементы.ДеревоДанных.ТекущаяСтрока = СохраненныйИдентификатор;

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

← На главную