Создание дерева с указанием количества вложенных для каждой ветки

1. AnryMc 849 03.09.20 12:04 Сейчас в теме
Есть:
Иерархический справочник ("МойСправочник"). Иерархия элементов.
Создается форма выбора с динамическим списком ("Список"), отображение списка "Дерево". Источник: Произвольный запрос.

Вопрос:
Как в запросе сформировать количество ВСЕХ вложенных ветвей в каждой ветке (колонка "Колво")

Например:
Корень
- Ветка 1 (колво - 2)
- Ветка 11 (колво - 0)
- Ветка 12 (колво - 0)
- Ветка 2 (колво - 5)
- Ветка 21 (колво - 2)
- Ветка 211 (колво - 0)
- Ветка 212 (колво - 0)
- Ветка 22 (колво - 0)
- Ветка 23 (колво - 0)
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. BackinSoda 03.09.20 12:09 Сейчас в теме
(1) тут или тут, ну и комментах много интересного
malikov_pro; AnryMc; +2 Ответить
4. AnryMc 849 03.09.20 12:20 Сейчас в теме
(2) Спасибо.

Но хотелось бы ОДНИМ "произвольным запросом" для "динамического списка".

Т.е. без внешних параметров. Просто ОДИН запрос.
5. oleg-x 23 03.09.20 13:13 Сейчас в теме
(4) Если получится, то обязательно напишите свое решение :-)
6. maxmax83 03.09.20 17:28 Сейчас в теме
(4) Запрос и будет один, если максимально возможная глубина вложенности будет известна.
7. AnryMc 849 03.09.20 17:55 Сейчас в теме
(6)
если максимально возможная глубина вложенности будет известна

КАК???
8. maxmax83 03.09.20 18:13 Сейчас в теме
(7) как-как - в конфигураторе ограничить уровень иерархии. Если это не вариант, то перед открытием формы сначала определить максимальный уровень, сконструировать запрос и установить его как текст запроса динамического списка.
10. SlavaKron 04.09.20 13:15 Сейчас в теме +1 $m
Если решать "в лоб", то при "Количество уровней иерархии" = 6 достаточно такого запроса:
ВЫБРАТЬ
	Т1.Ссылка КАК Ссылка,
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т2.Ссылка) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т3.Ссылка) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т4.Ссылка) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т5.Ссылка) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т6.Ссылка) КАК КоличествоПодчиненных

ИЗ
	Справочник.Номенклатура КАК Т1
		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т2
			ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т3
				ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т4
					ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т5
						ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т6
						ПО (Т5.Ссылка = Т6.Родитель)
					ПО (Т4.Ссылка = Т5.Родитель)
				ПО (Т3.Ссылка = Т4.Родитель)
			ПО (Т2.Ссылка = Т3.Родитель)
		ПО (Т1.Ссылка = Т2.Родитель)

СГРУППИРОВАТЬ ПО Т1.Ссылка
Показать
11. AnryMc 849 04.09.20 14:49 Сейчас в теме
(10)
РАЗЛИЧНЫЕ
+

Но это кол-во только для 1-го уровня
14. SlavaKron 21.09.20 09:09 Сейчас в теме
(11) Запрос считает количество для всех ссылок, для всех уровней.
3. M_A_D 196 03.09.20 12:17 Сейчас в теме
(1)
Писал запрос под свои потребности, доделал в нем подсчет элементов в группировке)
ВЫБРАТЬ
	ГруппыДоступаПользователи.Ссылка КАК Ссылка,
	ГруппыДоступаПользователи.Пользователь КАК Пользователь
ИЗ
	Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
ГДЕ
	ГруппыДоступаПользователи.Ссылка В ИЕРАРХИИ(&Ссылка)

СГРУППИРОВАТЬ ПО
	ГруппыДоступаПользователи.Ссылка,
	ГруппыДоступаПользователи.Пользователь
ИТОГИ
	КОЛИЧЕСТВО(Пользователь)
ПО
	Ссылка ИЕРАРХИЯ
Показать
9. ixijixi 1992 03.09.20 23:09 Сейчас в теме
Можно попробовать транзитивное замыкание запросом, но тест запроса придется собирать при создании формы
13. slasher777 21.09.20 08:40 Сейчас в теме
Если получится, то обязательно напишите свое решение
15. VZyryanov 21.09.20 09:23 Сейчас в теме
В "МойСправочник" можно и реквизит добавить "КоличествоВложенных" (или короче "Состав"). И заполнять этот реквизит в модуле объекта справочника в процедурах "ПриЗаписи", "ПередУдалением".
16. AnryMc 849 21.09.20 09:32 Сейчас в теме
(15)
В "МойСправочник" можно и реквизит добавить "КоличествоВложенных" (или короче "Состав"). И заполнять этот реквизит в модуле объекта справочника в процедурах "ПриЗаписи", "ПередУдалением".


То же вариант. (Но не хочется "плодить сущности")...
19. FatPanzer 21.09.20 09:57 Сейчас в теме
(15) Мы понимаем, что придется пересчитывать и перезаписывать все вышестоящие элементы? А при смене владельца - придется пересчитывать две ветки - все вышестоящие элементы новой ветки и все вышестоящие элементы старой ветки.
17. AnryMc 849 21.09.20 09:33 Сейчас в теме
Меня, если честно, всегда раздражает, что в дереве нужно начать "плюсик" чтобы понять, что "под ним" ничего нет...
18. VZyryanov 21.09.20 09:45 Сейчас в теме
Пример (проверял в БП 3.0):
ВЫБРАТЬ
	Номенклатура.Ссылка КАК Ссылка,
	ISNULL(Состав.Колво,0) КАК КоличествоВложенных
ИЗ
	Справочник.Номенклатура КАК Номенклатура
		ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
			Номенклатура1.Родитель КАК Родитель,
			КОЛИЧЕСТВО(Номенклатура1.Ссылка) КАК Колво
		ИЗ
			Справочник.Номенклатура КАК Номенклатура1
		
		СГРУППИРОВАТЬ ПО
			Номенклатура1.Родитель) КАК Состав
		ПО (Состав.Родитель = Номенклатура.Ссылка)
ГДЕ
	Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)
Показать
20. FatPanzer 21.09.20 10:00 Сейчас в теме
Не вижу реального прикладного смысла в том, чтобы выводить количество всех подчиненных объектов по иерархии - эта информация никакой ценности не несет. Вполне достаточно выводить подчиненные одного следующего уровня - можно будет хотя бы визуально отделить "пустые" ветки от заполненных.
А для этого и одного запроса хватит с одной связью по владельцу.
21. herfis 515 21.09.20 10:40 Сейчас в теме
Еще вариант:
- количество вложенных отображать через ПриПолученииДанныхНаСервере()
- получать через метод общего модуля с повторным использованием возвращаемых значений (сразу для всех веток дерева по "методу Ильдаровича")
- пересчет (при необходимости) - по кнопке на форме (управлять необходимостью пересчета кэша через доп-параметр)
Плюсы:
- минимум накладных расходов (основной приоритет метода).
Минусы:
- ручная актуализация в течение сеанса
- рост размера сеансовых данных при частых пересчетах в течение сеанса
ЗЫ. Другими словами, основной сценарий использования ориентирован на то, что инфа в этом справочнике условно-постоянная.
22. herfis 515 21.09.20 11:05 Сейчас в теме
(21) + Можно модифицировать метод, чтобы уйти от "кнопки" и обновлять кэш автоматически при изменении данных справочника
- регистрировать модификацию справочника в служебном плане обмена
- при получении данных из кэша на сервере сравнивать время генерации данных в кэше со временем последнего изменения данных справочника и если данные менялись - обновлять данные в кэше
Плюсы:
- своевременная актуализация
Минусы:
- таблицу регистрации плана придется чистить регламентом каким-нить (скажем, все записи "старше" недели)
- метод опять-таки не рассчитан на активное изменение справочника (так как и список подтормаживать будет в эти моменты и сеансовые данные будут бухнуть)
ЗЫ. Актуализацию кэша в этом случае проще всего реализовать, передавая параметром время последнего изменения справочника. Если справочник не менялся - будут использованы старые данные кэша. Как только данные были изменены - будет сгенерирован кэш по новым данным.
23. FatPanzer 21.09.20 11:12 Сейчас в теме
(22) Не уверен в необходимости такого количества телодвижений и новых объектов метаданных для такой задачи. Если рассматривать задачу как теоретическую - то вариантов масса. Если как практическую - то золотая задача получится, цель не оправдывает средства.
24. herfis 515 21.09.20 11:21 Сейчас в теме
(23) Я тоже не уверен. Это имеет смысл только в случае, если количество вложенных элементов является важной информацией для принятия решений. Причем для принятия решений различными сотрудниками в различных ситуациях. В противном случае проблема решается созданием специализированных инструментов.
25. FatPanzer 21.09.20 11:22 Сейчас в теме
(24) Да, конечно. Но даже для принятия решений нет необходимости использовать динамические списки. Для этого есть отчеты ;-) Списки - они для другого. Это же не центр управления полетами, где решения надо принимать за пару секунд глядя в монитор...
26. herfis 515 21.09.20 11:28 Сейчас в теме
(25) Я бы не проводил тут настолько строгих водоразделов. Вообще - да, но иногда - нет. Жизнь - она такая :)
И 1С не всегда используется как бэк-офис, да и в бэк-офисе заказчик часто бывает готов платить за повышение удобства.
27. FatPanzer 21.09.20 11:35 Сейчас в теме
(26) Ну уж если очень надо - то я бы просто перерисовал форму списка на использование дерева, заполняемого при открытии и обновляемого по обработчику ожидания. Безо всяких новых метаданых для БД.
Но это уже вопрос религии, конечно.
28. herfis 515 21.09.20 11:44 Сейчас в теме
(27) Это вопрос не религии, а количества данных и плюшек динамического списка. Если статический список вывозит по юзабилити - то ради бога. А я просто увидел пост и мне стало интересно - а как бы я решал, если бы в самом деле приперло с динамическим списком. Ну и придумалось вот такое :)
29. SlavaKron 21.09.20 12:17 Сейчас в теме
(22)
регистрировать модификацию справочника в служебном плане обмена

По-моему, достаточно просто подписаться на запись справочника и в ХранилищеОбщихНастроек писать текущую дату в какое-нибудь "ДатаПоследнейМодификации". Но вариант с кнопкой мне нравится больше.
30. herfis 515 21.09.20 12:35 Сейчас в теме
(29)
в ХранилищеОбщихНастроек писать текущую дату

Как вариант. Смущает только запись/чтение транзакционных данных в непредназначенное для этого хранилище. Сразу возникает масса интересных вопросов по типу "что произойдет, если два сеанса будут туда писать одновременно". Если просто гонка - то ладно. Для этого кейса некритично. Хуже, если что-то более экзотическое. Ведь в общем случае платформа не рассчитывает на то, что одна и та же настройка одного пользователя пишется и читается конкурентно.
ЗЫ. Но сама идея понятна - уйти от "из пушки по воробьям", и хранить только дату последнего изменения. Это логично. Можно и явно в БД писать, но тогда сразу попадаем на блокировки. Короче, как всегда - выбор подходящего компромисса. Хотя в рамках стратегии "изменяется редко" и константа/справочник вполне сойдут.
31. SlavaKron 21.09.20 17:12 Сейчас в теме
Щадящий вариант через ПриПолученииДанныхНаСервере и кнопку. Думаю, обработка данных во встроенном языке через Соответствие будет быстрее "метода Ильдаровича" – обрабатываются только позиции, имеющие подчиненные элементы.
Прикрепленные файлы:
ВнешняяОбработка2.epf
32. herfis 515 21.09.20 18:04 Сейчас в теме
(31) Для получения "среза" количества подчиненных - однозначно оптимальное решение!
33. sergioevans 22.09.20 19:06 Сейчас в теме
А запрос с итогами разве не выдаст в Общих итогах количество всех подчинённых вне зависимости от количества вложений?
Вот запрос по справочнику БизнесРегионы, иерархия элементов:
ВЫБРАТЬ
	БизнесРегионы.Наименование КАК Наименование
ИЗ
	Справочник.БизнесРегионы КАК БизнесРегионы
ИТОГИ
	КОЛИЧЕСТВО(Наименование)
ПО
	ОБЩИЕ

Значение в самой первой строке - это общее количество и есть.
34. AnryMc 849 23.09.20 09:10 Сейчас в теме
(33)
А запрос с итогами разве не выдаст в Общих итогах количество всех подчинённых вне зависимости от количества вложений


см. рисунок...

Или я то то не так делаю?
Прикрепленные файлы:
35. sergioevans 23.09.20 09:33 Сейчас в теме
(34) Прошу простить. Не усёк, что вам для динамического списка нужно. В нём итоги не работают (
36. AnryMc 849 15.12.21 15:09 Сейчас в теме +1 $m
Тема умерла - вознаграждение забрал. :-(
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот