Методика оптимизированного полного разворачивания и сворачивания динамических списков форм иерархических справочников отображаемых в виде дерева (управляемый интерфейс)

11.10.12

Разработка - Механизмы платформы 1С

Не секрет, что в большинстве случаев пользователю намного удобнее использовать отображение списка иерархического справочника в виде дерева. Все бы ничего, да на полное разворачивание объемного справочника стандартными средствами 1С может уйти до нескольких минут. Моя методика позволит разворачивать и сворачивать подобные справочники в десятки раз быстрее.

Скачать файлы

Наименование Файл Версия Размер
Методика (корректировка). Код и описание методики в модуле объекта обработки.
.epf 5,29Kb
106
.epf 5,29Kb 106 Скачать

Эффективность методики зависит от структуры справочника и количества записей в нем. Понятное дело - что если справочник мал, и при установке в палитре свойств таблицы формы свойства НачальноеОтображениеДерева в РаскрыватьВсеУровни он открывается за секунду, то тут эффект не будет заметен. Однако все изменяется с ростом количества элементов. Ниже приведены результаты тестирования. Помимо полного разворачивания разработана и процедура для полного сворачивания.

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

Легенда:

1 колонка - наименование справочника

2 колонка - количество элементов

3 колонка - количество групп / родителей

4 колонка - время на раскрытие методом установки в палитре свойств таблицы формы свойства НачальноеОтображениеДерева в РаскрыватьВсеУровни

5 колонка - время на раскрытие с помощью моей методики

Для клиент-серверной версии:

Справочник Элементов Групп/родителей Стандартно С оптимиз.
Контрагенты 7809 6 27 с 0,6 с
Банки 17465 78 52 с  5 с
Статьи движения ДС 124 32 3 с 2,1 с
Подразделения организаций 73 17 4 с 1,5 с

 

Повторные разворачивания всего дерева в течение сеанса работы происходит за доли секунды (если вы не закрывали окно справочника).

 

Суть оптимизации состоит в нахождении КЛЮЧЕВЫХ узлов, раскрытия которых абсолютно достаточно для полного раскрытия всего дерева. А исходя из того, что стандартным механизмом 1С раскрываются полностью все узлы, в т.ч. и подчиненные элементы, то выигрыш в количестве обращений к серверу, а соответсвенно и во времени разворачивания дерева очень существенный (особенно заметно на больших справочниках).

См. также

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

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

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    4527    dsdred    53    

72

Как готовить и есть массивы

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

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    5294    YA_418728146    25    

63

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

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

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

11.12.2023    6409    dsdred    36    

112

1С-ная магия

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

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

06.10.2023    18473    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

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

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    12088    human_new    27    

74

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

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

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

28.08.2023    8822    YA_418728146    6    

141

Внешние компоненты Native API на языке Rust - Просто!

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

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6279    sebekerga    54    

94

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

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

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

27.06.2023    15986    SeiOkami    31    

103
Вознаграждение за ответ
Показать полностью
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. evgefremov 44 08.10.12 21:47 Сейчас в теме
плюсую конечно, а так хотелось бы текст методики видеть в самой статье а не скачивать отдельный файл..
2. alexandr1972_1 08.10.12 21:52 Сейчас в теме
Не охота скачивать файл. Хотя бы начало в статье выложите.
3. iRounder 99 09.10.12 09:13 Сейчас в теме
Коллеги - поймите - я не из жадности хочу, чтобы скачивали файл. Эту $m потом девать в общем-то и некуда. Но это дает толчок к развитию как инфостарта - так и его пользователей. Например, с чего все началось у меня? Мне очень понадобилась конкретная обработка с инфостарта. В итоге пришлось кое-какие свои наработки достать из закромов и оформить публикации, чтобы их скачали, а у меня появились $m на то, чтобы скачать целевую публикацию. В итоге оформил уже 3 публикации - и думаю хорошо ими помог нескольким десяткам пользователей инфостарта.
6. ander_ 10.10.12 08:48 Сейчас в теме
(3)
Полное отсутствие информации о методах решения задачи дает обратный эффект. Не заинтересовывает.
Хотя бы в общих чертах и сжато но описание подхода нужно.
Иначе давайте все статьи будем назвать "Кто-то сделал что-то" и прикреплять файлы. Пусть инфостарт развивается!
alenakrr; Andreyyy; linkov; automax24; vital1c; Petr0v1ch; gaglo; +7 Ответить
7. iRounder 99 10.10.12 09:15 Сейчас в теме
(6) Даже не знаю что и ответить. Подождем для начала комментариев от тех, кто воспользовался методикой. О достигнутом эффекте.
8. gaglo 10.10.12 09:30 Сейчас в теме
Присоединяюсь к (6). В таком виде публикация выглядит как реклама от перхоти. Поделитесь хотя бы оценкой трудоемкости прививки данной методики к готовым конфигурациям. Ну что-то вроде "добавить три процедуры в общий модуль и внести их вызовы в 2315 мест в формах справочников". Суть самой методики, так и быть, не раскрывайте.
4. iRounder 99 09.10.12 09:15 Сейчас в теме
Ну, и еще просьба. Если кто скачал и использовал методику - то было бы очень хорошо, если бы в комментах написали какой выигрыш во времени раскрытия дерева получили (или не получили). Возможно большая выборка результатов даст повод попробовать еще больше оптимизировать процесс. Хотя на первый взгляд дальше уже некуда.
5. DoctorRoza 09.10.12 17:12 Сейчас в теме
9. mxm2 1263 10.10.12 10:03 Сейчас в теме
... рискну выразится несколько резко... однако даже после скачивания файла - не совсем понятен принцип действия, тем более, что чтобы опробовать методику требуется некая доработка Вашей обработки. Если уж Вы не предоставили описание методики, выложите хотя-бы готовую обработку, которую можно было бы запустить в конфигурации без её изменения (выпустите некий "окончательный продукт", не требующий "допиливания"), понимаю, что на это потребуется чуть больше времени, но все же попробуйте, и, возможно повысите свой статус, до уровня "когда $m уже не важны" ))). Неплохо бы в общих словах и описать принцип действия.
Моська; +1 Ответить
10. iRounder 99 10.10.12 10:24 Сейчас в теме
(9) Принимаю любую критику - так что не проблема
Для начала поясню - это не обработка, а процедуры и функции + пояснения по их внедрению в вашу конфигурацию. Просто для удобства и скажем так ради "боевой раскраски" они упакованы не в текстовый файл, а в общий модуль обработки.
И невозможно сделать готовую обработку (дело не во времени). В любом случае придется вносить изменения в конфигурацию. Хотя бы создать кнопки Свернуть и Развернуть...

Ну а это выдержка из текста модуля обработки:

//Создаем в любом общем модуле с установленным свойством Клиент(Управляемое приложение)
//(остальные свойства в Ложь) либо создаем свой общий модуль с описанными выше свойствами.
//В моем случае это общий модуль РазворачиваниеСворачиваниеДереваКлиент.
//В нем создаем экспортную процедуру:

Далее текст самой процедуры

//Создаем в любом общем модуле с установленным свойством Сервер
//(остальные свойства в Ложь) либо создаем свой общий модуль с описанными выше свойствами.
//В моем случае это общий модуль РазворачиваниеСворачиваниеДереваСервер.
//В нем создаем экспортную функцию:

Далее текст самой функции

//Далее в модуле управляемой формы списка целевого справочника создаем 2 процедуры и 2 функции:

Далее тексты процедур и функций

//Готово. Теперь в палитре свойств списка справочника устанавливаем Отображение = Дерево,
//НачальноеОтображениеДерева = НеРаскрывать.
//А далее по желанию либо в каком-нибудь событии формы вызывать РазвернутьВсе() или СвернутьВсе()
//либо (как это реализовано у меня) создать две соответствующие команды, разместить их
//в командной панели формы, а в их обработчиках вызывать соответствующие процедуры (РазвернутьВсе() или СвернутьВсе()).

Вот интересно - что здесь непонятно?
Ну, и заодно очевидна и "трудоемкость прививки к готовым конфигурациям" для (8).

А $m мне действительно не важны, сколько их уже есть - мне столько обработок не понадобится - факт.
Количество скачиваний файла мне пусть и субъективно но показывает количество человек кому необходима такая методика. А возможно, с некоторой скидкой, и кому в итоге помогла. Т.е. если я вижу ее не бесполезность, то тогда есть желание дальше работать в этом направлении - в том смысле, что разрабатывать нечто, что может быть полезным другим.
11. mxm2 1263 10.10.12 11:08 Сейчас в теме
(10) Видимо я совсем не в теме... "Невозможно создать обработку" отображения списка справочника? в которой Ваши экспортные процедуры внесены в модуль объекта. Про количество заитересованных можно судить по количеству просмотров, про успешность темы по +/-
12. iRounder 99 10.10.12 11:15 Сейчас в теме
(11) Каким образом для пользователя подмените стандартную форму списка на свою обработку не внося правки в конфигурацию?

Но суть даже не в этом - я нигде и не писал, что это готовая обработка. Я обозначал, что это методика. И в (10) я объяснил причину ее "упаковки" в обработку. Методика готовая к использованию. Все функции и процедуры написаны, их нужно только внедрить в свою конфигурацию.
13. mxm2 1263 10.10.12 11:30 Сейчас в теме
(12) если "въеду" в Вашу методику, напишу такую обработку. Методика работает только в "стандартной форме списка"? По крайней мере в пределах обычных форм на форму внешней обработки можно "положить" Форму списка любого справочника.
14. iRounder 99 10.10.12 12:43 Сейчас в теме
(13) Методика работает в любой форме с динамическим списком отображаемым в виде дерева. В пределах обычных форм (если Вы под обычными имеете в виду не управляемые) смысла в этой методике нет абсолютно.
И понятное дело, что в управляемых формах можно в форму обработки "положить" список любого справочника. Только как Вы будете подменять стандартную форму справочника на Вашу из обработки не влезая в конфигуратор (если у Вас конфигурация на полной поддержке)?
16. mxm2 1263 10.10.12 13:15 Сейчас в теме
(14) в большинстве случаев интересно применение ускорения именно в нестандартных формах справочников, как-то например, подбор номенклатуры в УТ11 (Управляемые формы). В УТ11 "подбор в документ продажи" реализован обработкой. Я имел ввиду, что для иллюстрации выигрыша можно сделать внешнюю обработку, скажем по одному и тому-же справочнику, стандартным способом, и Вашим, возможно в одной форме по типу "Norton Commander"
17. iRounder 99 10.10.12 13:23 Сейчас в теме
15. iRounder 99 10.10.12 12:49 Сейчас в теме
Неверно выразился в прошлом сообщении - смысла в этой методике нет в режиме обычного приложения, она исключительно для работы в режиме управляемого приложения.
39. gaglo 11.10.12 11:19 Сейчас в теме
С интересом прочитал обсуждение.
Видно, что в публикации изначально не хватало:
- указания из (15), что "смысла в этой методике нет в режиме обычного приложения"
- картинки, которая бы сразу показала вид развернутого дерева.
Теперь (наконец) стало ясно, необходима ли мне такая методика.
41. iRounder 99 11.10.12 12:13 Сейчас в теме
(39) Да бросьте - изначально в заголовке публикации было указано "управляемый интерфейс" :)

(38) Теперь я понял о каких двух вариантах шла речь. И теперь утверждать то, что реализовал оба варианта конечно же не буду. Изначально в описании публикации я говорил о конкретном варианте - одном списке в виде дерева.
Ваша функция с запросом и с последующей обработкой отрабатывает быстрее моей, пусть даже и та и другая выполняется за доли секунды - но отрицать факт неоптимальности моей реализации нет смысла.
Также возьму на заметку организацию запроса и обработки для двух списков. Спасибо.

Еще раз отмечу - что публиковалась методика, т.е. идея. А ее реализовывать можно по разному. Моя реализация - не оптимальна. И рад, что тема вызвала такое обсуждение, пусть и лишь с участием нескольких человек.

Ну и попрошу одного пояснения - у Вас все, что было Вами написано в этом обсуждении уже было реализовано до появления этой публикации или нет?
Т.е. мне интересно идея КЛЮЧЕВЫХ узлов была для Вас нова, или нет? (просто помню обсуждение подобной темы на мисте, где Вы говорили, что иерархический справочник из 5 000 строк открывался более 3 минут)
42. ChAlex 11.10.12 14:51 Сейчас в теме
(41) - Изначально я закинул решение этой задачи для конкретно большого справочника и просто по-умолчанию поставил режим отображения в виде иерархического дерева. + до сегодняшнего моемента все как-то не доходили руки до добавления сервиса в виде сворачивания и разворачивания деревьев в иных формах. Вообщем-то отчасти из-за того, что как то отложилось что нужно передавать иденитификатор строки (Тип Произвольный в документации для параметра никак не ассоциировался с ссылкой и к тому же в обычном дереве точно давал ошибку и требовался идентификатор строки) , а для динамического списка он отсутствует, вот и забил на это дело. Второй момент, который подсознательно давил, так это ну просто ТУПАЯ реализация стандартного поведения данного объекта в 1С. 5 минут разворачивается стандартными внутренними средствами 1С справочник в моей базе при развороте. Поэтому демонстрация того что срабатывает ссылка - решило проблемы с тем чтобы пробовать. Второй момент - честно как-то не думал раньше разворачивать не первый уровень, а последний. Почему-то тоже отложилось должно быть одно и тоже, а скорее всего просто производительность не тормозила, что бы как-то оптимизировать. Разворачивать верхний уровень с подчиненными програмно намного проще. Ко всему в обычных формах это нормально работало. Хотя стоит попробовать и там разворачивать последний уровень. Возможно поведение однотипное. В результате тестов на производительность можно однозначно сказать - оптимизации работы динамического списка нет абсолютно (как минимум в режиме дерева), поэтому если и использовать режим дерева, то разворачивать следует действительно самый нижний требуемый уровень. Разворот вниз от самого верхнего узла 1С делает аналогично тупо, как и работа с деревом. И этот вариант только может привести хоть к каким-то приемлимым цифрам по быстродействию. Хоть в целом и не фонтан, ну что тут зделаешь
alexware; +1 Ответить
44. iRounder 99 11.10.12 15:09 Сейчас в теме
(42) Опять же не могу понять к чему именно относится Ваша фраза "оптимизации работы динамического списка нет абсолютно" (как минимум в режиме дерева)? Если это относится к этой публикации, то не соглашусь, т.к. она как раз и была предназначена для того, чтобы продвинуть идею разворачивания не всех, а лишь ключевых узлов, а это и есть оптимизация (и существенный выигрыш по времени, хотя как Вы выразились на выходе все равно не фонтан - это уже зависит от справочника). А если фраза относится не к публикации - тогда прошу пояснить к чему именно.
45. ChAlex 11.10.12 17:06 Сейчас в теме
(44) - это относится к объекту 1С - "Динамический список"
46. iRounder 99 11.10.12 17:14 Сейчас в теме
(45) Спасибо за конструктивное обсуждение.
51. alexware 06.11.12 22:56 Сейчас в теме
(42) ChAlex,
А меня ещё больше, чем возможность использования ссылки в качестве параметра, удивил сам результат применения метода "Раскрыть" к глубоко вложенным ветвям дерева. Никогда бы не подумал, что при этом раскроются все родительские узлы. Я считал, что в этом случае просто запомнится состояние данного узла во внутренних переменных.
И вот что в связи с этим я для себя при этом обнаружил. Если на форме размещается дерево (полученное, например, запросом), то в нём запоминается состояние "раскрыт" для дочерних узлов. Т.е. если закрыть и заново открыть родительский узел, то его дочерние узлы будут раскрыты или закрыты в зависимости от того, какими мы их оставили. А в динамическом списке в виде дерева этого нет. Хотя, если задуматься, то понятно почему.
49. gaglo 12.10.12 11:29 Сейчас в теме
(41) Признаю, был неправ, не дочитал конец заголовка, а чуть ниже - многочисленные "не имеет значения" в рубрикаторе - ввели в меня заблуждение...
Но картинку все ж надо было приделать.
50. iRounder 99 12.10.12 12:37 Сейчас в теме
(49) К сожалению нету рубрикатора для указания типа интерфейса или приложения.
18. iRounder 99 10.10.12 13:24 Сейчас в теме
Если что-то нужно пояснить - я готов.
19. iRounder 99 10.10.12 13:26 Сейчас в теме
Ну и еще - стандартного метода раскрыть все дерева после того как форма создана и выведена на экран - нет. Во всяком случае я его не знаю. Поэтому только выставлять свойство списка НачальноеОтображение = РаскрыватьВсеУровни.
20. iRounder 99 10.10.12 13:26 Сейчас в теме
21. ChAlex 10.10.12 14:43 Сейчас в теме
Ну вот писал, писал - все куда-то ушло в корзину. Поэтому повторю. Если вдруг появится предыдущий труд - извиняйте.

Итак попробовал данный вариант. Сначала цифры: Справочник "Материалы" - количество записей 40 093 из них 379 папок. Время разворачивания списка: 1-е 50 сек., последующие 8 сек. Время сворачивания: 4 сек. Время разворачивания справочника при открытии в режиме "Разворачивать все уровни" 4 мин. 50 сек.

Теперь по методике: ничего нового или оптимизирующего в ней нет. Единственное что для себя открыл (до этого не пробовал писать не в соответствии с документаций) так это то, что в метод Развернуть(Строка,СПодчиненными) и Свернуть(Строка) можно передать в параметр "Строка" - ссылку а не идентификатор строки, как это написано в документации:
ТаблицаФормы (FormTable)
Развернуть (Expand)
Синтаксис:

Развернуть(<ИдентификаторСтроки>, <СПодчиненными>)
Параметры:

<ИдентификаторСтроки> (обязательный)

Тип: Произвольный.
Идентификатор строки таблицы.
<СПодчиненными> (необязательный)

Считаю это недоработкой документации.

Разжую для тех кто не сразу въезжает в тонкости данной темы:

По данной методики можно только организовать полное сворачивания и разворачивания веток дерева для динамического списка (в принципе можно модифицировать для разворачивания до определенного уровня). Все делается стандартными методами объекта "ТаблицаФормы": Развернуть() и Свернуть().
С вышесказанными замечаниями относительно параметров этих методов никаких сложностей с реализацией данных действий не возникает. Для динамических списков не возможно получить строку(и) из формы, которые нужно свернуть или развернуть, как например, для дерева( методом ДанныеФормыДерево.ПолучитьЭлементы()) - и потом уж получить по этим элементам идентификатор строки, который следовало бы передавать в качестве строки в метод Развернуть(). Оказывается вместо этого можно просто передать ссылки справочника. В этом и суть всех действий, предлагаемых автором. Все остальное стандартно. Ссылки получает запросом на сервере (кстати сам текст запроса какой-то геморный, не понял зачем так делать, но об этом позже), и потом обходя полученные ссылки разворачивается или сворачивается ветка ТаблицыФормы (списка справочника) из динамического списка методом Развернуть()/Свернуть(), где в качестве ссылки передается не идентификатор строки, а сама ссылка.

Теперь по поводу начального режима дерева: стоит устанавливать "Разворачивать только верхний уровень" - на моей базе разницы во времени с режимом "Не разворачивать" вообще никакой. Но хоть что-то отображается, вместо просто наименования справочника.

Теперь по поводу запроса: зачем там такой алгоритм - не понял. Переделал на простенький вариант:

Функция ПолучитьСписокЭлементовДерева2(ИмяСправочника, Развернуть) Экспорт
Запрос = Новый Запрос();
Запрос.Текст = "ВЫБРАТЬ
| " + ИмяСправочника + ".Ссылка
|ИЗ
| Справочник." + ИмяСправочника + " КАК " + ИмяСправочника + "
|ГДЕ
| " + ИмяСправочника + ".ЭтоГруппа"+?(Развернуть,""," И "+ИмяСправочника + ".Родитель = ЗНАЧЕНИЕ(Справочник." + ИмяСправочника + ".ПустаяСсылка)");
СписокЭлементов = Новый СписокЗначений;
СписокЭлементов.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"));
Возврат СписокЭлементов;
КонецФункции

Некоторое пояснение: для сворачивания нет необходимости получения всех групп, достаточно свернуть только группы на верхнем уровне.

Ну и теперь размышления по поводу производительности разворачивания(сворачивание всегда идет более менее быстро). В общем-то можно организовать 2-мя способами: разворачивать только верхний уровень с подчиненными, что делать не стоит (на моей базе в этом случае время разворачивания составляет 3 мин 50 сек - то, есть тоже самое, что режим при открытии разворачивать все уровни)! или разворачивать все ветки, следует использовать данный вариант. Разница во времени показывает качество оптимизации (вернее ее полное отсутствие) для дерева в 1С.
Andreyyy; mxm2; +2 Ответить
22. iRounder 99 10.10.12 14:59 Сейчас в теме
(21)Вся фишка именно в алгоритме обработки результата запроса. Какой максимальный уровень вложенности в справочнике "Материалы"?
Ну и очень интересна разница во времени разворачивания с моим "запросом и обработкой результата" и твоим.
27. ChAlex 10.10.12 16:44 Сейчас в теме
(22) - уровень вложенности не ограничен - данные введены с 5-ю уровнями вложенности (4 уровня групп, на 5-м только элементы). Естественно для разных групп вложенности разные, есть и с 1-м. Смысл переписывание запроса на в скорости, а в понятности и поддержке. На моей базе даже выигрыш в 1-2 сек для разворачивания и почти в 4 сек на сворачивание (сворачивание меньше секунды, вместо 4-х).
(23) - А что не соотносится? Все просто как грабли. Быстрее развернуть все ветки по одной самому, чем разворачивать только верхний уровень с подчиненными. Между этими двумя режимами и разница в эти 4 минуты, которые 1С тратит на то чтобы развернуть подчиненные элементы. Вот такая эффективность внутренних методов 1С.
(24) - вообще-то иерархия элементов с большим объемом и уровнями вложенности - нонсенс. Но даже и если это учитывать - не проблема - получить одним запросом и все. Совсем не догоняю зачем там в обработке какие-то поиски в списке, удаления и добавления родителей и т.п. Это лишне 100%
(25) - Не догнал совсем. Что значит "..КЛЮЧЕВЫЕ узлы дерева" и как "... развернуть лишь эти узлы (без подчиненных), чтобы увидеть полностью развернутое дерево." . Одно другому противоречит: если не развернуты все узлы, то и структура не вся видна. В чем соль и смысл?
23. iRounder 99 10.10.12 15:04 Сейчас в теме
В догонку - в первом абзаце (21) написано: "50 секунд против 4 минуты 50 секунд", в последнем абзаце: "Разница во времени показывает качество оптимизации (вернее ее полное отсутствие) для дерева в 1С."
Как-то не соотносится...
24. iRounder 99 10.10.12 15:17 Сейчас в теме
В запросе (21) не учтена возможность справочника с "Иерархия элементов"
25. iRounder 99 10.10.12 15:22 Сейчас в теме
В общем без дополнительных пояснений видимо действительно сложно разобраться в методике.
Вся соль там в обработке результата запроса.
Исходя из запроса в (21) всегда будет разворачиваться N узлов, где N - количество групп.
В результате моей обработки результата запроса получаем КЛЮЧЕВЫЕ узлы дерева. Т.е. достаточно развернуть лишь эти узлы (без подчиненных), чтобы увидеть полностью развернутое дерево. В зависимости от структуры справочника количество ключевых узлов может быть в десятки раз меньшим чем N, а соответственно уменьшается в столько же раз количество обращений к серверу, а вместе с ним и время разворачивания.
28. iRounder 99 10.10.12 16:57 Сейчас в теме
А смысл "ключевых узлов" прост: если проследить за поведением дерева (я это делал с помощью программной установки свойства ТекущаяСтрока при закрытом дереве) при открытии определенной ветви, то становится очевидным, что открыв например на 4 уровне определенный узел мне не нужно затем открывать его родителей вплоть до первого уровня (это если в двух словах). Исходя из запроса в (21) будут открываться все узлы дерева. По моему методу - только определенные.

Это легко проверить - поставь мой запрос с обработкой результата и по точке останова посмотри сколько элементов эта функция возвращает, и тоже самое сделай со своим запросом. И сравни.
А затем сравни деревья в обоих случаях - они будут одинаково полностью раскрыты.
30. ChAlex 10.10.12 20:54 Сейчас в теме
(28) Ну тогда следует разделить требования на 2 пункта: 1 - есть потребность разворачивания всей иерархии вместе с элементами, и 2 - разворачивать только структуру подчиненности (т.е. только дерево). Вы реализовывали 2-й вариант. Мне нужнее 1-й.

Ну и по поводу все-таки запроса: Я переделал (опять же с учетом подчиненности групп, при желании можно перенести на подчиненность элементов) на более эффективный

Функция ПолучитьСписокЭлементовДерева(ИмяСправочника, Развернуть, ДляДерева=Ложь) Экспорт
Запрос = Новый Запрос();
Если Развернуть Тогда
СписокЭлементов = Новый Массив;
Если ДляДерева Тогда
Запрос.Текст="ВЫБРАТЬ РАЗЛИЧНЫЕ
| Номенклатура.Ссылка.Родитель КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ЭтоГруппа
| И Номенклатура.Ссылка.Родитель <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
|ИТОГИ ПО
| Ссылка ИЕРАРХИЯ
|АВТОУПОРЯДОЧИВАНИЕ";
Иначе
Запрос.Текст="ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ЭтоГруппа
|ИТОГИ ПО
| Ссылка ИЕРАРХИЯ
|АВТОУПОРЯДОЧИВАНИЕ";
КонецЕсли;
Рез=Запрос.Выполнить();
Рекурсивно(Рез,СписокЭлементов);
Возврат СписокЭлементов;
Иначе
Запрос.Текст="ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ЭтоГруппа
| И Номенклатура.Ссылка.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
|АВТОУПОРЯДОЧИВАНИЕ";
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецЕсли;
КонецФункции

Процедура Рекурсивно(Выб,М)
Выборка = Выб.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией,"Ссылка");
Пока Выборка.Следующий() Цикл
Если Выборка.ТипЗаписи()=ТипЗаписиЗапроса.ИтогПоГруппировке И (ТипЗнч(Выб)=Тип("РезультатЗапроса") ИЛИ Выборка.Ссылка<>Выб.Ссылка) Тогда
М.Добавить(Выборка.Ссылка);
Иначе
Рекурсивно(Выборка,М);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
32. iRounder 99 10.10.12 21:00 Сейчас в теме
(30) Не согласен.
Мой алгоритм реализует обе задачи.
Либо я не понял, что Вы имеете в виду под "1 - есть потребность разворачивания всей иерархии вместе с элементами, и 2 - разворачивать только структуру подчиненности (т.е. только дерево)"
Прошу пояснить что значит только дерево?
В моем варианте все элементы дерева и вся иерархия - видны.
34. ChAlex 10.10.12 21:16 Сейчас в теме
(32) - ну тогда я не понял совсем смысла телодвижений в вашей процедуре с удалением каких то строк и поиском и добавлением чего-то. Можно развернуть иерархию дерево (элементы последнего уровня не разворачивать, ибо в них могут находится только элементы). Такое свойственно например если на форме вывести отдельно дерево справочника и отдельно список (как часто делалось в обычном интерфейсе). В таком случае нужно разворачивать не последний уровень иерархии а предпоследний. А можно разворачивать весь список, включая элементы на самом нижнем уровне. В таком случае нужно разворачивать уже самый последний уровень иерархии. Вот и все, что я имел ввиду. А по поводу производительности - да с уменьшением количества разворачиваемых элементов, время уменьшается.

(33) - пробовал я вашим запросом делать. Результат тот же (по скорости тот же порядок - однозначно не замерить, ситуация все время меняется - сервер то работает и нагрузка меняется). Я вообще-то не говорю что он не устраивает. Я говорил - что понять смысл вторичной обработки после запроса - не догоняю.
35. iRounder 99 10.10.12 21:24 Сейчас в теме
(34) Да - можно сказать, что у меня разворачивается предпоследний уровень иерархии, т.е. последний, на котором могут быть родители элемента. Но... Но ведь развернув родителя на предпоследнем уровне иерархии автоматически становятся видны все его подчиненные элементы - это ли не есть развернуть ветвь дерева, когда я вижу все его элементы, вплоть до самого "глубокого"?

А вторичную обработку я сейчас поясню (не исключаю, что ее можно сделать и посредством запроса - например, вложенного). Но опять же повторюсь - делал универсальный запрос для всех типов иерархии. Возможно это и не совсем правильно.
38. ChAlex 11.10.12 11:14 Сейчас в теме
(35) Вот так чаще всего (желаниям нет предела, что людей то столько правд) пользователь хочет видеть разворот справочника в варианте отображения списка в виде одного единственного дерева. В данном случае ему ВАЖНО видеть все элементы (и разворачивать дерево в данном случае нужно по узлу последнего уровня иерархии), это позволяет легче прокручивать ненужные группы и при этом быстрее ориентироваться в нахождении нужной позиции. И не убеждайте как 1С что отбор в этом случае лучше - далеко не всегда и можно об этом поспорить отдельно.

http://itmages.ru/image/view/710102/15c6ad9c

А вот так чаще всего отображается справочник с двумя списками: дерево для иерархии и список с отбором позиций по текущей строке дерева. В данном случае дерево нужно разворачивать по узлам предпоследней иерархии.

http://itmages.ru/image/view/710101/2fc58faa

Так что ваша функция с запросом оба варианта не реализовывает, как бы вы не утверждали. Я вам предложил идею простой процедуры получения предпоследнего, последнего и первого уровня иерархии запросом и рекурсивным обходом выборки, что правильнее, прозрачней, быстрей и лучше поддерживается. Чуть измените запрос и уберите отбор по группе получите универсально для иерархии элементов. А еще можно проверять вид иерархии справочника и делать разные запросы. Как душе угодно. И одним параметром можно получить сразу разный вариант разворота - хотите до кровня последних элементов (вариант 1), хотите до уровня только иерархии (вариант 2)
26. iRounder 99 10.10.12 15:45 Сейчас в теме
Ну, и если еще кто-нибудь один из скачавших скажет, что не понял методики. Тогда нигде не денусь - буду давать пояснения.
29. klel 10.10.12 20:44 Сейчас в теме
Большое спасибо за статью так и не понял как это работает :(
31. ChAlex 10.10.12 20:56 Сейчас в теме
Не сразу заметил, что можно оформить тегом :)
Функция ПолучитьСписокЭлементовДерева(ИмяСправочника, Развернуть, ДляДерева=Ложь) Экспорт 
	Запрос = Новый Запрос(); 
Если Развернуть Тогда 
	СписокЭлементов = Новый Массив; 
Если ДляДерева Тогда 
	Запрос.Текст="ВЫБРАТЬ РАЗЛИЧНЫЕ 
| Номенклатура.Ссылка.Родитель КАК Ссылка 
|ИЗ 
| Справочник.Номенклатура КАК Номенклатура 
|ГДЕ 
| Номенклатура.ЭтоГруппа 
| И Номенклатура.Ссылка.Родитель <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) 
	|ИТОГИ ПО 
| Ссылка ИЕРАРХИЯ 
|АВТОУПОРЯДОЧИВАНИЕ"; 
Иначе 
	Запрос.Текст="ВЫБРАТЬ 
| Номенклатура.Ссылка КАК Ссылка 
|ИЗ 
| Справочник.Номенклатура КАК Номенклатура 
|ГДЕ 
| Номенклатура.ЭтоГруппа 
|ИТОГИ ПО 
| Ссылка ИЕРАРХИЯ 
|АВТОУПОРЯДОЧИВАНИЕ"; 
КонецЕсли; 
Рез=Запрос.Выполнить(); 
Рекурсивно(Рез,СписокЭлементов); 
Возврат СписокЭлементов; 
Иначе 
	Запрос.Текст="ВЫБРАТЬ 
| Номенклатура.Ссылка КАК Ссылка 
|ИЗ 
| Справочник.Номенклатура КАК Номенклатура 
|ГДЕ 
| Номенклатура.ЭтоГруппа 
| И Номенклатура.Ссылка.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) 
	|АВТОУПОРЯДОЧИВАНИЕ"; 
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"); 
КонецЕсли; 
КонецФункции 

Процедура Рекурсивно(Выб,М) 
Выборка = Выб.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией,"Ссылка"); 
Пока Выборка.Следующий() Цикл 
	Если Выборка.ТипЗаписи()=ТипЗаписиЗапроса.ИтогПоГруппировке И (ТипЗнч(Выб)=Тип("РезультатЗапроса") ИЛИ Выборка.Ссылка<>Выб.Ссылка) Тогда 
	М.Добавить(Выборка.Ссылка); 
Иначе 
	Рекурсивно(Выборка,М); 
КонецЕсли; 
КонецЦикла; 
КонецПроцедуры 
Показать
33. iRounder 99 10.10.12 21:03 Сейчас в теме
(31) Вы пробовали без доработок открыть дерево моим алгоритмом? Если да - то что именно не развернулось в дереве.
По поводу оптимизации запроса - там возможно и есть над чем подумать (будет время гляну). Не знаю почему - но хотелось сделать универсальный запрос: и для "Иерархия групп и элементов" и для "Иерархия элементов".
36. iRounder 99 10.10.12 21:48 Сейчас в теме
Для начала приношу извинения. В функции ПолучитьСписокЭлементовДерева(ИмяСправочника, Развернуть) в публикацию попала строка, которой там быть не должно (из старой версии). Ее нужно удалить. Хотя она и не влияла на производительность или корректность разворачивания. Именно из-за нее сворачивание происходило дольше.
Вот эта строка:
СписокЭлементов.ЗагрузитьЗначения(СписокРодители.ВыгрузитьКолонку("Родитель"));
она находится перед: Если Развернуть Тогда
10-я по счету в указанной функции.
37. iRounder 99 10.10.12 21:56 Сейчас в теме
Ну и суть методики.

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

А далее в обработке результатов запроса - это и есть суть оптимизации - я:
для сворачивания выбираю лишь родителей без родителей, т.е. фактически родителей с верхнего уровня группировки, формирую список узлов и отдаю в процедуру разворачивания/сворачивания;
для разворачивания формируется список из родителей, у которых нет в подчинении родителей (это то, что я ранее назвал КЛЮЧЕВЫМИ узлами, разворачивания которых абсолютно достаточно для отображения дерева в полностью развернутом виде), т.е. только тех родителей, у которых в подчинении только элементы, т.е. предпоследний уровень иерархии на ветви дерева, формирую список узлов и отдаю в процедуру разворачивания/сворачивания;
40. zipik 11.10.12 11:23 Сейчас в теме
когда уже УФ доведут до ума
43. ChAlex 11.10.12 15:01 Сейчас в теме
Собственно ваше решение подтолкнуло вернуться к этой проблеме. :)
47. kilokilo 18 11.10.12 17:37 Сейчас в теме
Я вот не пойму - а зачем использовать динамический список, если нужно все дерево разворачивать??
48. ChAlex 11.10.12 17:57 Сейчас в теме
(47) - тогда подскажите каким образом можно вывести список справочника в управляемой форме кроме динамического списка. Я думаю даже 1С узнает что-то новое про свой продукт :)
52. blockcode 40 20.03.13 09:06 Сейчас в теме
Приходилось работать с отрисовкой деревьев. Принцип построения динамического дерева прост:
1) На первом этапе формируем дерево только из корневых узлов и их подчиненных, т.е. нулевой и первый уровень. Оставляем их свернутыми.
2) При разворачивании каждого узла для его дочерних улов удаляем и дорисовываем внуков при их наличии. Если внуков не удалять, то при повторном открытии они будут множиться )))
Экономия во времени получается за счет не раскрытых узлов, что для деревьев с большим количеством узлов актуально.
53. Rain_man 07.02.23 09:53 Сейчас в теме
УФ, динамический список, в нём иерархический справочник, наложен отбор (все родители отфильтрованного видны).

Развернёт?
Оставьте свое сообщение