(7) как-как - в конфигураторе ограничить уровень иерархии. Если это не вариант, то перед открытием формы сначала определить максимальный уровень, сконструировать запрос и установить его как текст запроса динамического списка.
Если решать "в лоб", то при "Количество уровней иерархии" = 6 достаточно такого запроса:
ВЫБРАТЬ
Т1.Ссылка КАК Ссылка,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т2.Ссылка) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т3.Ссылка) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т4.Ссылка) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т5.Ссылка) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т6.Ссылка) КАК КоличествоПодчиненных
ИЗ
Справочник.Номенклатура КАК Т1
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т2
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т3
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т4
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т5
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Т6
ПО (Т5.Ссылка = Т6.Родитель)
ПО (Т4.Ссылка = Т5.Родитель)
ПО (Т3.Ссылка = Т4.Родитель)
ПО (Т2.Ссылка = Т3.Родитель)
ПО (Т1.Ссылка = Т2.Родитель)
СГРУППИРОВАТЬ ПО Т1.Ссылка
(1)
Писал запрос под свои потребности, доделал в нем подсчет элементов в группировке)
ВЫБРАТЬ
ГруппыДоступаПользователи.Ссылка КАК Ссылка,
ГруппыДоступаПользователи.Пользователь КАК Пользователь
ИЗ
Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
ГДЕ
ГруппыДоступаПользователи.Ссылка В ИЕРАРХИИ(&Ссылка)
СГРУППИРОВАТЬ ПО
ГруппыДоступаПользователи.Ссылка,
ГруппыДоступаПользователи.Пользователь
ИТОГИ
КОЛИЧЕСТВО(Пользователь)
ПО
Ссылка ИЕРАРХИЯ
В "МойСправочник" можно и реквизит добавить "КоличествоВложенных" (или короче "Состав"). И заполнять этот реквизит в модуле объекта справочника в процедурах "ПриЗаписи", "ПередУдалением".
В "МойСправочник" можно и реквизит добавить "КоличествоВложенных" (или короче "Состав"). И заполнять этот реквизит в модуле объекта справочника в процедурах "ПриЗаписи", "ПередУдалением".
То же вариант. (Но не хочется "плодить сущности")...
(15) Мы понимаем, что придется пересчитывать и перезаписывать все вышестоящие элементы? А при смене владельца - придется пересчитывать две ветки - все вышестоящие элементы новой ветки и все вышестоящие элементы старой ветки.
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
ISNULL(Состав.Колво,0) КАК КоличествоВложенных
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
Номенклатура1.Родитель КАК Родитель,
КОЛИЧЕСТВО(Номенклатура1.Ссылка) КАК Колво
ИЗ
Справочник.Номенклатура КАК Номенклатура1
СГРУППИРОВАТЬ ПО
Номенклатура1.Родитель) КАК Состав
ПО (Состав.Родитель = Номенклатура.Ссылка)
ГДЕ
Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)
Не вижу реального прикладного смысла в том, чтобы выводить количество всех подчиненных объектов по иерархии - эта информация никакой ценности не несет. Вполне достаточно выводить подчиненные одного следующего уровня - можно будет хотя бы визуально отделить "пустые" ветки от заполненных.
А для этого и одного запроса хватит с одной связью по владельцу.
Еще вариант:
- количество вложенных отображать через ПриПолученииДанныхНаСервере()
- получать через метод общего модуля с повторным использованием возвращаемых значений (сразу для всех веток дерева по "методу Ильдаровича")
- пересчет (при необходимости) - по кнопке на форме (управлять необходимостью пересчета кэша через доп-параметр)
Плюсы:
- минимум накладных расходов (основной приоритет метода).
Минусы:
- ручная актуализация в течение сеанса
- рост размера сеансовых данных при частых пересчетах в течение сеанса
ЗЫ. Другими словами, основной сценарий использования ориентирован на то, что инфа в этом справочнике условно-постоянная.
(21) + Можно модифицировать метод, чтобы уйти от "кнопки" и обновлять кэш автоматически при изменении данных справочника
- регистрировать модификацию справочника в служебном плане обмена
- при получении данных из кэша на сервере сравнивать время генерации данных в кэше со временем последнего изменения данных справочника и если данные менялись - обновлять данные в кэше
Плюсы:
- своевременная актуализация
Минусы:
- таблицу регистрации плана придется чистить регламентом каким-нить (скажем, все записи "старше" недели)
- метод опять-таки не рассчитан на активное изменение справочника (так как и список подтормаживать будет в эти моменты и сеансовые данные будут бухнуть)
ЗЫ. Актуализацию кэша в этом случае проще всего реализовать, передавая параметром время последнего изменения справочника. Если справочник не менялся - будут использованы старые данные кэша. Как только данные были изменены - будет сгенерирован кэш по новым данным.
(22) Не уверен в необходимости такого количества телодвижений и новых объектов метаданных для такой задачи. Если рассматривать задачу как теоретическую - то вариантов масса. Если как практическую - то золотая задача получится, цель не оправдывает средства.
(23) Я тоже не уверен. Это имеет смысл только в случае, если количество вложенных элементов является важной информацией для принятия решений. Причем для принятия решений различными сотрудниками в различных ситуациях. В противном случае проблема решается созданием специализированных инструментов.
(24) Да, конечно. Но даже для принятия решений нет необходимости использовать динамические списки. Для этого есть отчеты ;-) Списки - они для другого. Это же не центр управления полетами, где решения надо принимать за пару секунд глядя в монитор...
(25) Я бы не проводил тут настолько строгих водоразделов. Вообще - да, но иногда - нет. Жизнь - она такая :)
И 1С не всегда используется как бэк-офис, да и в бэк-офисе заказчик часто бывает готов платить за повышение удобства.
(26) Ну уж если очень надо - то я бы просто перерисовал форму списка на использование дерева, заполняемого при открытии и обновляемого по обработчику ожидания. Безо всяких новых метаданых для БД.
Но это уже вопрос религии, конечно.
(27) Это вопрос не религии, а количества данных и плюшек динамического списка. Если статический список вывозит по юзабилити - то ради бога. А я просто увидел пост и мне стало интересно - а как бы я решал, если бы в самом деле приперло с динамическим списком. Ну и придумалось вот такое :)
регистрировать модификацию справочника в служебном плане обмена
По-моему, достаточно просто подписаться на запись справочника и в ХранилищеОбщихНастроек писать текущую дату в какое-нибудь "ДатаПоследнейМодификации". Но вариант с кнопкой мне нравится больше.
Как вариант. Смущает только запись/чтение транзакционных данных в непредназначенное для этого хранилище. Сразу возникает масса интересных вопросов по типу "что произойдет, если два сеанса будут туда писать одновременно". Если просто гонка - то ладно. Для этого кейса некритично. Хуже, если что-то более экзотическое. Ведь в общем случае платформа не рассчитывает на то, что одна и та же настройка одного пользователя пишется и читается конкурентно.
ЗЫ. Но сама идея понятна - уйти от "из пушки по воробьям", и хранить только дату последнего изменения. Это логично. Можно и явно в БД писать, но тогда сразу попадаем на блокировки. Короче, как всегда - выбор подходящего компромисса. Хотя в рамках стратегии "изменяется редко" и константа/справочник вполне сойдут.
Щадящий вариант через ПриПолученииДанныхНаСервере и кнопку. Думаю, обработка данных во встроенном языке через Соответствие будет быстрее "метода Ильдаровича" – обрабатываются только позиции, имеющие подчиненные элементы.
А запрос с итогами разве не выдаст в Общих итогах количество всех подчинённых вне зависимости от количества вложений?
Вот запрос по справочнику БизнесРегионы, иерархия элементов:
ВЫБРАТЬ
БизнесРегионы.Наименование КАК Наименование
ИЗ
Справочник.БизнесРегионы КАК БизнесРегионы
ИТОГИ
КОЛИЧЕСТВО(Наименование)
ПО
ОБЩИЕ
Значение в самой первой строке - это общее количество и есть.