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

24.05.19

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

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

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

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

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

 

 

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

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

 

 

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

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

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

 

 

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

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

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

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


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

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

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

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

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

статья

См. также

Планы обмена VS История данных

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

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

11.12.2023    6440    dsdred    36    

112

1С-ная магия

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

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

06.10.2023    18508    SeiOkami    46    

118

Валидация JSON через XDTO (включая массивы)

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

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

28.08.2023    8850    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

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

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

2 стартмани

22.08.2023    2078    21    progmaster    7    

3

Расширение глобального поиска 1С, или Глобальный поиск "на максималках"

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

Мало кто знает, что поле "Глобального поиска" в 1С можно доработать. Добавить свои варианты поиска, кнопочки в результатах и даже целые пользовательские меню.

27.03.2023    6960    SeiOkami    10    

140

Версионирование объектов VS История данных

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

Давайте разберемся в механизме «История данных» и поэкспериментируем для наглядности. Сравним «Версионирование объектов» и «Историю данных».

06.03.2023    19001    dsdred    54    

193

Практическая шпаргалка по новым возможностям языка запросов 1С

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

В предлагаемой статье решил привести примеры применения новых возможностей языка запросов 1С, начиная с версии платформы 8.3.20.

21.11.2022    23458    quazare    36    

122

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

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

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16158    133    sapervodichka    112    

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

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

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

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


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