Работа с деревом значений в 1С

 

В последнее время аномально часто мне в работе попадалось дерево значений, поэтому решил написать на эту тему статью.

Попробую рассмотреть способы решения основных задач связанных с деревом значений, при этом постараюсь писать «без воды».

Дерево значений

Из названия объекта понятно, что дерево значений служит для хранения/отображения какой-либо иерархической информации. Каждая строка дерева значений может иметь какое-то количество подчиненных строк, при этом такие операции как поиск, сортировка, подсчет итогов можно проводит с учетом уровня иерархии и подчиненных строк.

Кроме этого, каждая строка дерева значений имеет свойства «Родитель» и «Строки».

Дерево значений на форме

Визуальное представление дерева значений обеспечивает элемент «Табличное поле».

Дерево значений на обычной форме
Дерево значений на обычной форме
Дерево значений на управляемой форме
Дерево значений на управляемой форме

Заполнение дерева значений

При заполнении дерева значений нужно помнить, что сам объект «ДеревоЗначений» и все его строки имеют свойство «Строки»и добавление новых строк на любом уровне дерева осуществляется через это свойство.

Сам же объект «ДеревоЗначений» имеет еще и свойство «Колонки», которое ничем не отличается от аналогичного свойства у таблицы значений.

Небольшой пример программного заполнения таблицы значений для управляемых форм:

Обход дерева значений

Обход всех строк дерева значений делается при помощи рекурсии, вот так будет выглядеть код для обхода дерева созданного в примере выше:

Как свернуть и развернуть дерево значений

Сворачивается и разворачивается дерево значений очень просто.

Свернуть:

Привел три примера: для сворачивания текущей строки, для сворачивания строк верхнего уровня, для сворачивания вообще всех строк (рекурсия).

Развернуть:

Два примера: для разворачивания текущей строки и для разворачивания всех строк. У метода «Развернуть» есть дополнительный параметр, который позволяет указать нужно ли разворачивать подчиненные строки.

 

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

Тут опять же все просто, нужно помнить, что при удалении/очистке строки, все подчиненные строки удаляются.

Очистить дерево значений:

Точно также можно очистить от подчиненных элементов другую другую строку.

Удалить строку дерева значений не сложнее — нужно только знать ее индекс:

Запрос и дерево значений

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

Если на форме имеется реквизит «ДеревоЗначений» и связанный с ним визуальный элемент, то можно сделать примерно так:

Причем полного совпадения колонок и типов не требуется — лишние колонки будут просто отброшены, а колонки с различными типами будут заполнены пустыми значениями.

Дерево значений в таблицу значений и обратно

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

Отбор в дереве значений

Стандартного отбора в дереве значений не предусмотрено. Так получилось потому, что непонятно как разрешать ситуацию, когда родительский элемент не удовлетворяет условию отбора, а подчиненные ему элементы удовлетворяют.

Таким образом, если Вам нужно реализовать отбор в дереве  значений, то начать нужно с решения именно этой проблемы. А уже после этого можно придумать несколько способов реализовать задуманное.

Первый способ — накладывать отбор до вывода дерева значений (в запросе например). Это не классический отбор, но в тех случаях когда этот способ применим, то следует применять именно его, так как это почти всегда быстрее и правильнее чем что-либо другое.

Второй способ — перебор всех строк дерева значений. Описывать здесь особенно нечего, нужно просто взять обход дерева значений, проверять каждую строку на соответствие условию отбора и удалять лишние строки.

Еще один способ заключается в том, чтобы преобразовать дерево значений в таблицу значений, сделать отбор в таблице значений, проконтролировать результат (почистить «хвосты» — строки, родитель которых не удовлетворил условию отбора) и выполнить обратное преобразование в дерево значений.

На этом все, рассказал все, что знал, надеюсь мне удалось сэкономить Вам немного времени.

Если Вы нашли ошибку или неточность, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Оценка статьи:
УжасноПлохоНеплохоХорошоОтлично (оценок: 43, средняя оценка: 4,23 из 5)
Загрузка...

Понравилась статья? Поделиться с друзьями:
Комментарии: 17
  1. Юрий

    Спасибо за хорошую статью.

  2. Жизель

    Спасибо, помогло!

  3. Глеб

    спасибо за объяснение

  4. Юрий

    Огромное спасибо!!! Очень помогла статья!!!

  5. Игорь

    Добрый день!
    Как можно поменять родителя в дереве значения, для того чтобы элемент дерева с одной группы перешел в другую группу дерева?

  6. egolege

    Отличный сайт!

  7. Vitonya

    Ошибка!
    Откуда эта процедура взялась?

    Свернутьв(тСтрЭлементы);

    1. Петр

      Я сначала задавал себе такой же вопрос. Потом разобрался.
      Выкладываю решение для тех у кого будут аналогичные проблемы:

      // Процедура которая реализует команду формы (кнопка на форме)
      // Данная команда сворачивает дерево значений (реквизит формы)
      // которое выведено в элемент формы типа «Таблица формы»
      &НаКлиенте
      Процедура СвернутьДерево(Команда)
      ЭлементыДерева = ДеревоВидовНоменклатуры.ПолучитьЭлементы();
      СвернутьРекурсия(ЭлементыДерева, «ДеревоВидовНоменклатуры»);
      КонецПроцедуры

      // Рекурсивная процедура, которая сворачивает элементы дерева на форме
      // ЭлементыДерева — элементы дерева значений (реквизит формы)
      // ИмяЭлементаФормы — имя элементы формы, в который выведено дерево (таблица формы)
      &НаКлиенте
      Процедура СвернутьРекурсия(ЭлементыДерева, ИмяЭлементаФормы)
      Для Каждого Стр Из ЭлементыДерева Цикл
      СтрЭлементы = Стр.ПолучитьЭлементы();
      СвернутьРекурсия(СтрЭлементы, ИмяЭлементаФормы);

      Элементы[ИмяЭлементаФормы].Свернуть(Стр.ПолучитьИдентификатор());
      КонецЦикла;
      КонецПроцедуры

  8. Евгений

    Искал вариант организации выбора строки из дерева. Здесь не нашел.

  9. Филипп

    Прекрасная статья, благодарю.

  10. Сергей

    Отбор в дереве можно организовать через условное оформление, поле «Видимость», по условию добавленного служебного поля

  11. Fedor

    Толково. Спасибо!

  12. Евгений

    них не понятно. откуда что взялось. всё названо одним и тем словом дерево и сиди разбирайся что где отчего взялось.
    очередная статься написанная для себя любимого ,а не для люедй

    1. Петр

      Евгений, а вы хотели чтобы вам тут все разжевали, разложили по полкам, предложили решение каждого уникального случая и предложили решение на все случаи жизни?
      Такого не будет ни где, потому что тема достаточно сложная.
      Программист на то такая профессия и есть чтобы искать решение в безвыходных ситуациях.
      Автор предложил достаточно универсальные способы подходящие под большинство случаев в практике.
      Эти способы необходимо преобразовать под ваш конкретный случай.

    2. Владимир

      Евгений, ты имбицил :cool:

    3. Илья

      Ты прав, во первых такого нет на управляемых формах. А не управляемые никто уже не использует. Не пойму что тут толкового? Сложно было написать что табличное поле не существует в природе на УФ?

  13. Петр

    Большое спасибо за эту статью!
    Она помогла мне со сворачиванием и разворачиванием Дерева формы на управляемой форме. :smile:

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: