1с развернуть дерево рекурсивно

Обход дерева значений на клиенте

Подскажите, пожалуйста, как обойти дерево значений на клиенте.

У меня в серверной процедуре обсчитываются итоги. После этого я используя метод ЗначениеВРеквизитФормы(Дерево, «ДеревоЗначений») заполняю дерево на форме. При этом оно становится свернутым.

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

ЭлементыДерева = Дерево.ПолучитьЭлементы(); Для Каждого ЭлементДерева Из ЭлементыДерева Цикл Элементы.Дерево.Развернуть(ЭлементДерева.ПолучитьИдентификатор(), Истина); КонецЦикла;

Спасибо, но это не то. У меня многоуровненовое дерево.

То есть .получитьэлементы() возвращает только корневую коллекцию строк. А в дочерние я попасть не могу.

ЭлементыДерева = Дерево.ПолучитьЭлементы(); Для Каждого ЭлементДерева Из ЭлементыДерева Цикл Элементы.Дерево.Развернуть(ЭлементДерева.ПолучитьИдентификатор(), Истина); ЭлементыУр2 = ЭлементДерева.ПолучитьЭлементы(); Для Каждого ЭлементУр2 Из ЭлементыУр2 Цикл Элементы.Дерево.Развернуть(ЭлементДерева.ПолучитьИдентификатор(), Истина); ЭлементыУр3 = ЭлементДерева.ПолучитьЭлементы(); . КонецЦикла; КонецЦикла;

Спасибо большое. Получилось, написал в итоге рекурсивные процедуры. Одна запоминает какие развернуты были узлы, потом на сервере процедура пересчитывает итоги, и третья раскрывает узлы, какие были раскрыты до пересчета. Может кому пригодится код:

&НаКлиенте Процедура ДеревоЗначенийСуммаПриИзменении(Элемент) соотвКолонок = Новый Соответствие; соотвКолонок.Вставить("Сумма"); РазвернутыеСтроки = Новый Соответствие(); КоличествоСтрок = 0; ПроверитьСвернутостьДерева(ДеревоЗначений, РазвернутыеСтроки, КоличествоСтрок); ПосчитатьНаСервере(соотвКолонок); УстановитьРазвернутостьДерева(ДеревоЗначений, РазвернутыеСтроки, КоличествоСтрок); КонецПроцедуры &НаКлиенте Процедура ПроверитьСвернутостьДерева(пДеревоЗначений, РазвернутыеСтроки, КоличествоСтрок) ЭлементыДерева = пДеревоЗначений.ПолучитьЭлементы(); КоличествоСтрок = КоличествоСтрок + 1; Если ЭлементыДерева.Количество() = 0 Тогда Возврат КонецЕсли; Для Каждого ЭлементДерева Из ЭлементыДерева Цикл Идентификатор = ЭлементДерева.ПолучитьИдентификатор(); РазвернутыеСтроки.Вставить(Идентификатор, Элементы.ДеревоЗначений.Развернут(Идентификатор)); ПроверитьСвернутостьДерева(ЭлементДерева, РазвернутыеСтроки, КоличествоСтрок); КонецЦикла; КонецПроцедуры &НаКлиенте Процедура УстановитьРазвернутостьДерева(пДеревоЗначений, РазвернутыеСтроки, КоличествоСтрок) ЭлементыДерева = пДеревоЗначений.ПолучитьЭлементы(); Если ЭлементыДерева.Количество() = 0 Тогда Возврат КонецЕсли; Для Каждого ЭлементДерева Из ЭлементыДерева Цикл Идентификатор = ЭлементДерева.ПолучитьИдентификатор(); Если РазвернутыеСтроки.Получить(Идентификатор - КоличествоСтрок + 1) = Истина Тогда Элементы.ДеревоЗначений.Развернуть(Идентификатор); КонецЕсли; УстановитьРазвернутостьДерева(ЭлементДерева, РазвернутыеСтроки, КоличествоСтрок); КонецЦикла; КонецПроцедуры

Однако если вы хотите, что бы состояние развернутости запоминалось до пересчета итогов, и восстанавливалось после, то это уже совсем другая задача, которую можно решить примерно так, как вы написали в (5). Но только не совсем так, потому что так как вы написали, будет работать не всегда. Например, если пользователь будет сначала интерактивно заполнять дерево в хаотичном порядке, т.е. добавлять элементы, то в одну группу то в другую, а потом запустится процедура пересчета итогов, то дерево у вас раскроется не правильно, т.е. не так как было до пересчета. Произойдет это потому, что при хаотичном порядке заполнения дерева, идентификаторы строк будут присвоены в порядке их добавления, а после того, как будет выполнен метод ЗначениеВРеквизитФормы, идентификаторы строк присвоятся заново. И помимо того, что их нумерация увеличится на количество элементов в дереве, она еще будет заново упорядочена. И в этом случае никакое «Идентификатор — КоличествоСтрок + 1», уже не поможет. Т.к. например, строке с идентификатором «3» при количестве строк равным 10, не обязательно будет присвоен идентификатор «12», ей вполне может быть присвоен идентификатор с другим номером, например «15». Можете проверить.
Конечно, если у вас не происходит интерактивной работы пользователя с деревом, к примеру, если оно у вас заполняется программно и всегда по порядку, или изначально заполняется методом ЗначениеВРеквизитФормы, то тогда описанный вами способ будет работать.

Читайте также:  Дерево влюбленных своими руками

(7) VBod, да все верно. Я тоже заметил такую особенность, поэтому и пришлось говнокодить как «Идентификатор — КоличествоСтрок + 1». Но другого способа не нашел.

а что делать в этом случае?

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

Пользователи захотели сами править дерево 🙂

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

ДеревоНаКлиенте.Получить(ИндексСтрокиНаСервере)

получаем строку в дереве на клиенте, и разворачиваем ее. Только не забудьте, что индекс уникален только в пределах одного уровня дерева, поэтому получение строки на клиенте по индексу, нужно производить, находясь на соответствующем уровне дерева.

Источник

Как развернуть (свернуть) строки дерева значений?

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

По умолчанию, при помещении на форму табличного поля или таблицы формы, связанных с деревом значений, оно показывается в свернутом виде. Если нужно, чтобы при открытии формы дерево значений показывалось в раскрытом виде, проще всего воспользоваться свойством НачальноеОтображениеДерева таблицы (табличного поля). Оно может принимать одно из следующих значений:

Читайте также:  Беседа деревья нашего двора
НеРаскрывать
(NoExpand)
отображать строки дерева в свернутом виде (по умолчанию)
РаскрыватьВерхнийУровень
(ExpandTopLevel)
отображать развернутыми строки дерева значений первого уровня
РаскрыватьВсеУровни
(ExpandAllLevels)
отображать развернутыми все строки дерева значений

Внимание! Программная установка свойства НачальноеОтображениеДерева на клиенте в режиме управляемого приложения неизбежно ведет к вызову сервера

Теперь рассмотрим варианты программного сворачивания\разворачивания строк дерева значений. Реализация этих методов может отличаться для обычных и управляемых форм.

Дерево значений на управляемых формах

Пример для сворачивания всех строк дерева значений:

//получаем подчиненные элементы ДанныеФормыДерево СтрокиДерева = ДеревоДокументов.ПолучитьЭлементы(); Для каждого СтрокаДерева Из СтрокиДерева Цикл //получаем идентификатор строки в таблице формы СтрокаДереваИД = СтрокаДерева.ПолучитьИдентификатор(); //проверяем состояние строки Если Элементы.ДеревоДокументов.Развернут(СтрокаДереваИД) = Истина Тогда //сворачиваем строку дерева Элементы.ДеревоДокументов.Свернуть(СтрокаДереваИД); КонецЕсли; КонецЦикла; 

Пример для разворачивания всех строк дерева значений верхнего уровня:

//получаем подчиненные элементы ДанныеФормыДерево СтрокиДерева = ДеревоДокументов.ПолучитьЭлементы(); Для каждого СтрокаДерева Из СтрокиДерева Цикл //получаем идентификатор строки в таблице формы СтрокаДереваИД = СтрокаДерева.ПолучитьИдентификатор(); //проверяем состояние строки Если Элементы.ДеревоДокументов.Развернут(СтрокаДереваИД) = Ложь Тогда //разворачиваем строку дерева Элементы.ДеревоДокументов.Развернуть(СтрокаДереваИД); КонецЕсли; КонецЦикла; 

Если нужно сворачивать и разворачивать вложенные строки, потребуется доработать данный код, добавив рекурсию

Дерево значений на обычных формах

С обычными формами дела обстоят проще: обращение к серверу для обычных форм не так критично, как для управляемых, поэтому раскрыть все строки дерева можно так:

ЭлементыФормы.ДеревоДокументов.НачальноеОтображениеДерева = НачальноеОтображениеДерева.РаскрыватьВсеУровни; 

Но в большинстве случаев лучше использовать следующий код, который гарантированно работает

//свернуть строки верхнего уровня Для каждого ПодчиненнаяСтрока Из ДеревоДокументов.Строки Цикл Если ЭлементыФормы.ДеревоДокументов.Развернут(ПодчиненнаяСтрока) Тогда ЭлементыФормы.ДеревоДокументов.Свернуть(ПодчиненнаяСтрока); КонецЕсли; КонецЦикла; //развернуть строки верхнего уровня Для каждого ПодчиненнаяСтрока Из ДеревоДокументов.Строки Цикл Если ЭлементыФормы.ДеревоДокументов.Развернут(ПодчиненнаяСтрока) = Ложь Тогда ЭлементыФормы.ДеревоДокументов.Развернуть(ПодчиненнаяСтрока); КонецЕсли; КонецЦикла; 

Источник

Читайте также:  Герметик радуга forwood для дерева
Оцените статью