Просто о дереве значений

24.05.19

Разработка - Универсальные функции

Кратко о работе с объектом типа ДеревоЗначений.

   Цель данной статьи - изложить свой взгляд на такой объект 1С, как дерево значений. На данную тему написано уже достаточно статей, в особенности на предмет программной работы с этим объектом. Поэтому Америку не открою, лишь попытаюсь предложить начинающим программистам способ лёгкого освоения методики работы с деревом значений с помощью всего 3х важных моментов.

    Для того, чтобы работать с этим объектом, нужно понимать, для чего он нужен. Он удобен, в первую очередь, для представления иерархических объектов – таких, как справочник Номенклатура. Мне встречалась также задача по представлению в виде дерева разнотипных подчинённых объектов, например ЗаказовПокупателя и Номенклатуры в Маршрутном Листе.

Дерево Значений = Таблица Значений + колонка Родитель

 

 

Иерархия или подчинённость отражается в 1С с помощью дополнительного реквизита – Родитель. Именно наличие такого реквизита отличает объект ДеревоЗначений от объекта ТаблицаЗначений.  Это первое, что нужно запомнить для работы с Деревом – ДеревоЗначений это ТаблицаЗначений с дополнительной колонкой Родитель.

Дерево Значений = работа с одним уровнем иерархии

 

 

Второй важный момент – при работе с деревом на Сервере, в отличие от ТаблицыЗначений, у которой можно получить произвольное количество строк методом НайтиСтроки(), получаемые строки ограничены текущим уровнем иерархии, то есть значением колонки Родитель.  Во время первого обращения к объекту метод Строки() возвращает коллекцию (не массив, как в ТЗ) строк корневого уровня – строк с пустым значением колонки Родитель. В зависимости от типа иерархии таких строк может быть как одна, так и несколько. Далее вся работа с Деревом сводится к перебору циклом «Для Каждого Из» колллекции, полученной методом Строки(). Для каждого элемента коллекции метод Строки() возвращает коллекцию подчинённых строк – тех, у которых значение колонки Родитель равно данному элементу. Таким образом организуется рекурсивный обход дерева – примеры функций также есть в других статьях. Остальные методы работы с деревом аналогичны методам работы с таблицей значений (см. синтакс-помощник). Иначе говоря, коллекция строк дерева с одинаковым значением колонки Родитель представляет собой таблицу значений.

ДеревоЗначений на Сервере = ДанныеФормыДерево на Клиенте

   Третий момент – передача данных Дерева между Клиентом и Сервером. На Клиенте объекту типа ДеревоЗначений соответствует объект ДанныеФормыДерево.

 

 

Для работы с Деревом Значений в клиент-серверном режиме необходимо использовать функции платформы – РеквизитФормыВЗначение (ДанныеФормыВЗначение) для передачи изменений с клиента на сервер и ЗначениеВРеквизитФормы (ЗначениеВДанныеФормы) для передачи с сервера на клиент. Эти функции облегчают жизнь разработчику, поскольку обрабатывают весь объект целиком, а не только один уровень иерархии, как это вынужден делать разработчик.

Напоследок, хотелось бы изложить свой взгляд на задачу позиционирования в Дереве, которая встречается достаточно часто. Раз у Дерева есть колонки, то для его отображения на клиенте используется объект ТаблицаФормы. Для решения задачи позиционирования в дереве используется свойство таблицы – ТекущаяСтрока. На просторах Интернета встречаются решения, когда для позиционирования происходит обращение к серверу. На мой взгляд, этого не требуется, поскольку объект ДанныеФормыДерево содержит все значения, при условии, что они переданы с помощью функций передачи (см. выше) и позиционирование заключается в поиске значения, получении идентификатора строки и установке свойства ТекущаяСтрока у элемента управляемой формы.

Пример клиентской функции поиска значения:

Функция Дерево_НайтиНаКлиенте(Что_то)
    
    НайденоЗначение = Ложь;
    КоллекцияДерева = Дерево.ПолучитьЭлементы();
    Для Каждого СтрокаДерева Из КоллекцияДерева Цикл
        Если СтрокаДерева.Поле = Что_то Тогда
            РезультатПоиска = СтрокаДерева;
        Иначе
            РезультатПоиска = НайтиВДереве(СтрокаДерева, Что_то);
        КонецЕсли;
        Если РезультатПоиска <> Неопределено Тогда
            ИндексДерева = РезультатПоиска.ПолучитьИдентификатор();
            ЭтаФорма.ТекущийЭлемент = Элементы.Дерево;
            ЭтаФорма.ТекущийЭлемент.ТекущаяСтрока = ИндексДерева;
            НайденоЗначение = Истина;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    Возврат НайденоЗначение;
    
КонецФункции


Комментарий: сначала получается коллекция элементов корневого уровня. Системная функция ПолучитьЭлементы() на клиенте соответствует функции Строки() на сервере. В цикле запускается перебор элементов коллекции, в котором присутствует рекурсивная функция НайтиВДереве(СтрокаДерева, Что_то), возвращающая найденную строку в случае успешного поиска, либо Неопределено, в противном случае. Если РезультатПоиска отличается от пустого значения Неопределено, то в ТаблицеФормы, отображающей Дерево, устанавливаются значения ТекущийЭлемент и ТекущаяСтрока по идентификатору строки дерева, получаемому системной функцией ПолучитьИдентификатор().

Это простой пример поиска по одному полю - Поле. Если имя поля передать в качестве второго параметра функции, то к нему можно будет обратиться следующим образом:

Если СтрокаДерева[Поле] = Что_то Тогда

и функция будет искать значения в любой колонке (по любому реквизиту) дерева.

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

статья

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7443    bayselonarrend    20    

154

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    20123    dimanich70    81    

144

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11222    dsdred    44    

130

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23757    SeiOkami    48    

135

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14730    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3580    56    progmaster    8    

4

Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    25523    SeiOkami    31    

113
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. VmvLer 24.05.19 11:19 Сейчас в теме
автор изложил свою картину миру в проекции дерева значений, причем, по моему, ни фига не просто, скорее коряво.

но он имеет право на свою картину мира и как и я на свою.

я бы не рекомендовал эту статью первокурснику по ит.
адуырщдв; Daruma; eden_gmail; rpgshnik; ltfriend; +5 Ответить
2. Infector 201 24.05.19 11:24 Сейчас в теме
Субъективно, но все-таки - не люблю, когда слишком увлекаются деревом значений. За пределами интерфейсных задач это вообще бессмысленно, а в интерфейсных зачастую встречаю перегруженность уровнями, когда ради того чтобы добраться до конечных строк нужно долго и упорно эти уровни разворачивать. Т.е. как временно-случайному пользователю такого интерфейса, где попросили что-то подправить, мне это не нравится еще больше, чем как разработчику. По сей причине предпочитаю таблицы значений с отборами, удобнее со всех сторон.
adhocprog; kungfufox; Revachol; eden_gmail; rpgshnik; w.r.; +6 Ответить
3. w.r. 650 24.05.19 12:03 Сейчас в теме
(2) аналогично считаю. Если список большой, то работа с деревом будет сильно тормозить 1с. Лучше всего использовать динамические списки с динамическим считыванием данных
5. dkoder 6 30.05.19 08:16 Сейчас в теме
(3)а что, в динамическом списке уже можно напрямую ячейки редактировать?
DELOVOYDOM; 1CEnterprise; +2 Ответить
17. DELOVOYDOM 10.02.24 03:48 Сейчас в теме
(5) он просто обслуживает какую то конкретную фирму и не знает, зачем вообще еще 1с нужна кроме отборов статистических данных. Поймем человека, он просто удивлен что мир несколько больше
14. 1CEnterprise 01.04.21 09:57 Сейчас в теме
(3) А если наоборот список небольшой? В этом случае использование динамического списка (в общем случае) будет отрабатывать медленнее. Так же при небольшом списке данных - использование динамического списка "неправильно" по сути.
4. dkoder 6 30.05.19 08:15 Сейчас в теме
(2) за пределами интерфейсных задачь, есть как минимум одна задача - разузлование изделий, и это реальная боль.
Согласен, что увлекаться глубокими уровнями вложенности не стоит, но интерфесно распределение чего либо: занятость станков, оплаты по реализации, и т.п. очень даж удобно.
7. Infector 201 30.05.19 08:46 Сейчас в теме
(4) я в свое время эксперементировал и с деревом, и в вложенными таблицами. На данный момент при разработке с чистого листа в том числе для разузлования не стал бы пользоваться деревом. Таблица значений с дополнительными полями, идентифицирующим строки и связи между ними в использовании оказывается много удобнее.
16. DELOVOYDOM 10.02.24 03:46 Сейчас в теме
(2) в схеме бизнес процесса без дерева работать невозможно, пользователь просто не поймет как строить диаграмму процесса. я удивлен, что вы понятия не имеете зачем нужны иерархии в управлении качеством и оптимизации логистических цепочек. Можете рисовать в визио потоки создания ценностей, как лет 30 назад. Одними таблицами бизнес не ограничивается, есть еще кад системы, там вообще без иерархии никуда, запутаетесь.
18. Infector 201 10.02.24 12:09 Сейчас в теме
(16)Для любой иерархии дерево значений как объект платформы не является обязательным. Просто идем в любой иерархический справочник, смотрим как он хранит данные, обнаруживаем там колонку "родитель" а далее воспроизводим в виде таблицы. Это как альтернативное решение, уместность того или иного это уже по контексту задачи и необходимых операциях по обработке этих данных. Иногда стоит отходить от привычных шаблонов, за их пределами можно найти то, что окажется более удобным / уместным.
6. dkoder 6 30.05.19 08:26 Сейчас в теме
дам пару советов:
- на больших данных не используйте рекурсивный вызов процедур, используйте искуственную рекурсию внутри одной процедуры, для этого нужно два массива, это работает если не на порядок, то в разы быстрее. Кстати в erp2 для разузлования используется рекурсия через две процедуры - это боль.
- для формирования дерева одним запросом используйте СКД с иерархией детальных записей, через связи наборов данных, где делаете связь набора к самому себе
8. user925427 126 30.05.19 10:40 Сейчас в теме
(6) Приветствую. Спасибо за комментарии, с которыми я лично согласен. Они дают больше знаний о дереве и сопутствующих задачах. Статья-то для начинающих, тех, кто знакомится с деревом. Кому-то, мой взгляд на него может оказаться полезным. (1) показался корявым, но я и не претендую на академичность.
15. Serg2000mr 670 30.04.23 16:59 Сейчас в теме
(6) Подскажите, как реализуется искусственная рекурсия на двух массивах
9. sm.artem 16 03.06.19 06:31 Сейчас в теме
На мой взгляд немного некорректно показалось описание метода НайтиСтроки() для коллекции строк:

в отличие от ТаблицыЗначений, у которой можно получить произвольное количество строк методом НайтиСтроки(), получаемые строки ограничены текущим уровнем иерархии, то есть значением колонки Родитель.


А как же второй параметр в этом методе, который как-раз таки и определяет возможность поиска с учетом подчиненных коллекций или без них?
user756416; +1 Ответить
10. user925427 126 03.06.19 12:12 Сейчас в теме
В целом, согласен. Есть второй параметр у метода НайтиСтроки(), который позволяет получить и подчинённые строки тоже. Почему о нём не написал? Потому что не было цели скопировать содержимое СП. Я предложил начинающим подход к работе с деревом - получать текущий уровень и работать с ним. Иначе, при использовании второго параметра, придётся разбирать массив строк на текущий и подчинённые уровни. Это тоже вариант, но немного более сложный для понимания. В 1С, вообще, почти всегда есть несколько путей решения задач. Но статья называется "Просто о дереве значений", поэтому я и выбрал более простой, в моём понимании, путь.
11. Daruma 03.06.19 14:18 Сейчас в теме
И сильно "рекурсивная" НайтиВДереве отличается от "корневой" Дерево_НайтиНаКлиенте? :)
12. user925427 126 03.06.19 14:28 Сейчас в теме
(11) Только начальными условиями, стартом с верхнего уровня. Тут простор для творчества широкий, кому как нравится. Эффективность не страдает, читабельность кода, на мой взгляд, повыше.
13. Daruma 03.06.19 14:32 Сейчас в теме
(12) Я понял. Вопрос был чисто риторический. На мой взгляд, одна функция (может быть даже чуть более развернутая) лучше двух, практически дублирующих друг друга.
Оставьте свое сообщение