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