Как найти максимальный уровень строк исходного дерева значений и вывести его на форму в реквизит "Уровень"?
Как найти максимальный уровень строк исходного дерева значений и вывести его на форму в реквизит "Уровень"? Во время отладки возникает ошибка Поле объекта не обнаружено (СтрокиДЗ)
{Обработка.Тест4.Форма.Форма.Форма(48)}: КоличествоУровней(ДеревоЗначений.СтрокиДЗ);
{Обработка.Тест4.Форма.Форма.Форма(42)}: ВыполнитьРезультатНаСервере();
Код ниже:
{Обработка.Тест4.Форма.Форма.Форма(48)}: КоличествоУровней(ДеревоЗначений.СтрокиДЗ);
{Обработка.Тест4.Форма.Форма.Форма(42)}: ВыполнитьРезультатНаСервере();
Код ниже:
&НаСервере
Процедура ВыполнитьРезультатНаСервере()
КоличествоУровней(ДеревоЗначений.СтрокиДЗ);
КонецПроцедуры
Функция КоличествоУровней(СтрокиДЗ)
Если СтрокиДЗ.Количество() = 0 Тогда Возврат 0 КонецЕсли;
КоличествоУровней = 0;
Для Каждого СтрокаДЗ ИЗ СтрокиДЗ Цикл
КоличествоУровней = Макс(КоличествоУровней(СтрокаДЗ.Строки), КоличествоУровней);
КонецЦикла;
Возврат КоличествоУровней + 1;
КонецФункции
ПоказатьПрикрепленные файлы:
Тест4.epf

По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Я так понял там упр. формы, соответственно тип значения реквизита - ДанныеФормыДерево а не ДеревоЗначений.
ДеревоЗначений1 = РеквизитФормыВЗначение(ДеревоЗначений); //Получаем ДеревоЗначений
Далее обходите рекурсией как вы и делаете (только учтите первый комментарий, свойство "Строки" а не "СтрокиДЗ").
Можно обходить и само ДанныеФормыДерево (метод ПолучитьЭлементы()). Но это долго, гораздо дольше чем ДеревоЗначений.
Вообще обходить дерево - долго. Лучше при добавлении строк запомнить максимальный уровень.
С деревьями на форме работают обычно РеквизитФормыВЗначение -> ДеревоЗначений -> ЗначениеВРеквизитФормы. Но при этом теряются идентификаторы строк, и слетает текущая строка дерева после серверного вызова :(. Что бы восстановить текущую строку я бы перед серверным вызовом записал некий адрес текущей строки [1,2,3] и потом установил бы туда текущую строку. Как их то красивых решений этой проблемы не находил.
ДеревоЗначений1 = РеквизитФормыВЗначение(ДеревоЗначений); //Получаем ДеревоЗначений
Далее обходите рекурсией как вы и делаете (только учтите первый комментарий, свойство "Строки" а не "СтрокиДЗ").
Можно обходить и само ДанныеФормыДерево (метод ПолучитьЭлементы()). Но это долго, гораздо дольше чем ДеревоЗначений.
Вообще обходить дерево - долго. Лучше при добавлении строк запомнить максимальный уровень.
С деревьями на форме работают обычно РеквизитФормыВЗначение -> ДеревоЗначений -> ЗначениеВРеквизитФормы. Но при этом теряются идентификаторы строк, и слетает текущая строка дерева после серверного вызова :(. Что бы восстановить текущую строку я бы перед серверным вызовом записал некий адрес текущей строки [1,2,3] и потом установил бы туда текущую строку. Как их то красивых решений этой проблемы не находил.
&НаСервере
Процедура ВыполнитьРезультатНаСервере()
ДеревоЗначенийРек = РеквизитФормыВЗначение("ДеревоЗначений");
//ДеревоЗначенийРек.Строки.Очистить();
КоличествоУровней(ДеревоЗначенийРек.Строки);
ЗначениеВРеквизитФормы(ДеревоЗначенийРек, "ДеревоЗначений");
КонецПроцедуры
Функция КоличествоУровней(СтрокиДЗ)
Если СтрокиДЗ.Количество() = 0 Тогда Возврат 0 КонецЕсли;
КоличествоУровней = 0;
Для Каждого СтрокаДЗ ИЗ СтрокиДЗ Цикл
КоличествоУровней = Макс(КоличествоУровней(СтрокаДЗ.Строки), КоличествоУровней);
КонецЦикла;
Возврат КоличествоУровней + 1;
КонецФункции
ПоказатьПолучается максимальный уровень = 3, а нужно КоличествоУровней = 4 в итоге. Как быть?
(4) Уж не знаю, на сколько актуально (ну мало ли, вдруг кому-то пригодится), но я бы сделал так – увеличивал уровень после определения, есть ли подчиненные строки и перед их обходом:
&НаКлиенте
Процедура ВыполнитьРезультат(Команда)
ВыполнитьРезультатНаСервере();
КонецПроцедуры
&НаСервере
Процедура ВыполнитьРезультатНаСервере()
МаксимальныйУровень = 0;
РеквизитДерево = РеквизитФормыВЗначение("ДеревоЗначений");
СтрокиДереваЗначений = РеквизитДерево.Строки;
Если СтрокиДереваЗначений.Количество() > 0 тогда
ТекущийУровень = 1;
ОбойтиСтрокиДерева(СтрокиДереваЗначений,ТекущийУровень,МаксимальныйУровень);
КонецЕсли;
Уровень = МаксимальныйУровень;
КонецПроцедуры
&НаСервере
Процедура ОбойтиСтрокиДерева(СтрокиДереваЗначений,ТекущийУровень,МаксимальныйУровень)
Для каждого СтрокаДерева из СтрокиДереваЗначений цикл
Если СтрокаДерева.Строки.Количество() > 0 тогда
//Если текущая строка дерева содержит подчиненные строки,
//значит, получаем значение следующего уровня...
СледующийУровень = ТекущийУровень + 1;
//...и обходим его строки
ОбойтиСтрокиДерева(СтрокаДерева.Строки,СледующийУровень,МаксимальныйУровень);
Иначе
//Если текущая строка дерева не содержит подчиненных строк,
//то определим, является ли текущий уровень максимальным
МаксимальныйУровень = Макс(ТекущийУровень,МаксимальныйУровень);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Показать Функция МаксимальныйУровеньДЗ(ДеревоЗначений)
МаксУровень = 0;
КопияДЗ = ДеревоЗначений.Скопировать();
КопияДЗ.Колонки.Добавить("ДляВыгрузки",Новый ОписаниеТипов("Число",
Новый КвалификаторыЧисла(1, 0, ДопустимыйЗнак.Неотрицательный)));
МассивСтрок = КопияДЗ.Строки.НайтиСтроки(Новый Структура("ДляВыгрузки",0),Истина);
Для Каждого СтрокаДЗ Из МассивСтрок Цикл
МаксУровень = Макс(МаксУровень, СтрокаДЗ.Уровень());
КонецЦикла;
Возврат МаксУровень;
КонецФункции
ПоказатьВроде быстрее работает, чем рекурсивный обход.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот