Текущий уровень дерева значений

Как найти максимальный уровень строк исходного дерева значений и вывести его на форму в реквизит «Уровень»?

Как найти максимальный уровень строк исходного дерева значений и вывести его на форму в реквизит «Уровень»? Во время отладки возникает ошибка Поле объекта не обнаружено (СтрокиДЗ)
: КоличествоУровней(ДеревоЗначений.СтрокиДЗ);
: ВыполнитьРезультатНаСервере();

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

(1) СтрокиДЗ есть Строки, а не строкиДЗ.

Если вы передаете строку в качестве параметра функции, должно быть

Для Каждого СтрокаДЗ ИЗ СтрокиДЗ.Строки Цикл

Я так понял там упр. формы, соответственно тип значения реквизита — ДанныеФормыДерево а не ДеревоЗначений.

ДеревоЗначений1 = РеквизитФормыВЗначение(ДеревоЗначений); //Получаем ДеревоЗначений
Далее обходите рекурсией как вы и делаете (только учтите первый комментарий, свойство «Строки» а не «СтрокиДЗ»).
Можно обходить и само ДанныеФормыДерево (метод ПолучитьЭлементы()). Но это долго, гораздо дольше чем ДеревоЗначений.

Вообще обходить дерево — долго. Лучше при добавлении строк запомнить максимальный уровень.

С деревьями на форме работают обычно РеквизитФормыВЗначение -> ДеревоЗначений -> ЗначениеВРеквизитФормы. Но при этом теряются идентификаторы строк, и слетает текущая строка дерева после серверного вызова :(. Что бы восстановить текущую строку я бы перед серверным вызовом записал некий адрес текущей строки [1,2,3] и потом установил бы туда текущую строку. Как их то красивых решений этой проблемы не находил.

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

Получается максимальный уровень = 3, а нужно КоличествоУровней = 4 в итоге. Как быть?

Читайте также:  Период обработки плодовых деревьев от вредителей весной

(4) Уж не знаю, на сколько актуально (ну мало ли, вдруг кому-то пригодится), но я бы сделал так – увеличивал уровень после определения, есть ли подчиненные строки и перед их обходом:

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

Источник

Как определить уровень в дереве значений

(3) Что значит «дерево значений на форме обработки»? Это элемент формы?
Работать нужно с данными элемента, то что в поле ПутьКДанным в свойствах элементах, а не самим элементом.

&НаКлиенте Процедура ПодсчитатьУровни(Команда) КвоУровней = 0; ПодсчитатьУровниНаСервере(КвоУровней); Сообщить("Максимальное количество уровней = " + КвоУровней); КонецПроцедуры &НаСервере Процедура ПодсчитатьУровниНаСервере(КвоУровней) ДеревоОбъект = РеквизитФормыВЗначение("ДеревоЗн"); КвоУровней = 0; КолвоУровнейДерева(ДеревоОбъект,КвоУровней); КонецПроцедуры &НаСервере Процедура КолвоУровнейДерева(СтрДер, К) Для Каждого стрДерева из СтрДер.Строки Цикл К = Макс(К, СтрДер.Уровень()); Если стрДерева.Строки.Количество() <> 0 Тогда КолвоУровнейДерева(стрДерева, К); КонецЕсли; КонецЦикла; КонецПроцедуры
К = Макс(К, стрДерева.Уровень());

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

(11), а я ничего не писал, что оно есть, на клиенте есть «неудобное» ДанныеФормыДерево.
Относительный аналог «Для Каждого стрДерева из ДеревоЗн.Строки Цикл» является «Для Каждого стрДерева из ДеревоЗн.ПолучитьЭлементы() Цикл»

как вариант: https://forum.infostart.ru/forum9/topic113341/ (сам принцип), понятно, что цикл можно можно сделать рекурсивно

Читайте также:  Какая бывает деревья прилагательные

в цикле считай всё, что хочешь

(14) Ну мало ли. Все таки арсенал методов для работы с прикладным ДЗ шире, чем с ДанныеФормыКоллекция. Все зависит от задачи и используемых данных.

Источник

1С 8.3 Дерево значений — Программист 1С Минск. Автоматизация бизнеса.

Дерево Значений в 1С 8.3 — это иерархический динамически набор любого типа. По своим функциям и структуре (колонки и строки) очень схожа с Таблицей Значений, но есть виртуальная колонка «Родитель». Дерево значений рекомендуется использовать для работы именно с иерархической информацией . Каждая строка дерева значений имеет свойства «Родитель» и «Строки», а также может иметь любое количество подчиненных строк. Операции с помощью встроенного функционала (сортировка, раскраска строк, поиск, итоги, различные отборы ) могут производится с учетом подчиненных строк / уровней иерархии.

&НаСервере
Процедура ЗаполнениеРеквизитаФормыДеревоЗначений ()

// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение ( «ДеревоЗначНаФорме» );
// ДеревоЗначений = Новый ДеревоЗначений; — если без реквизита

ДЗ_Корень = ДеревоЗначений . Строки . Добавить ();
ДЗ_Корень . Наименование = «Самый верхний уровень» ;

ДЗ_1уровень = ДЗ_Корень . Строки . Добавить ();
ДЗ_1уровень . Наименование = «1-ая папка (группа)» ;

ЭлементДЗ_1 = ДЗ_1уровень . Строки . Добавить ();
ЭлементДЗ_1 . Наименование = «Первый (вложенный) элемент» ;

ДЗ_2уровень = ДЗ_Корень . Строки . Добавить ();
ДЗ_2уровень . Наименование = «2-ая папка (группа)» ;

ЭлементДЗ_1 = ДЗ_2уровень . Строки . Добавить ();
ЭлементДЗ_1 . Наименование = «Первый (вложенный) элемент» ;

ЭлементДЗ_2 = ДЗ_2уровень . Строки . Добавить ();
ЭлементДЗ_2 . Наименование = «Второй (вложенный) элемент» ;

// Преобразование ДеревоЗначений в реквизит формы (табличное поле)
ЗначениеВРеквизитФормы ( ДеревоЗначений , «ДеревоЗначНаФорме» );

&НаСервере
Процедура ЗаполнениеРеквизитаФормыДеревоЗначенийИзЗапроса ()

Запрос = Новый Запрос ;
Запрос . Текст = «ВЫБРАТЬ
| Материалы.Ссылка КАК Наименование
| Материалы.Родитель КАК Родитель
|ИЗ
| Справочник.Материалы КАК Материалы
|УПОРЯДОЧИТЬ ПО
| Наименование ИЕРАРХИЯ
|ИТОГИ ПО
| Родитель» ;

//Внимание! Если правильно не указать вид обхода результата выборки по запросу,
//то мы получим обычную таблицу значений
ДеревоЗначений = Запрос . Выполнить (). Выгрузить ( ОбходРезультатаЗапроса . ПоГруппировкамСИерархией );

// Заполнение дерева значений из результата запроса
// колонка «Материалы» – это элемент справочника, колонка «Родитель» – это группа
ЗначениеВРеквизитФормы ( ДеревоЗначений , «ДеревоЗначНаФорме» ); // Преобразование в реквизит формы (табличное поле)

Читайте также:  Чем покрывают деревья от насекомых

&НаСервере
Процедура ПоискСтрокиВДеревеЗначений () // найдём 1-ю строку со значением «Элемент №1» в дереве значений

// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение ( «ДеревоЗначНаФорме» );

// Поиск строки. (если строка не найдена, вернёт «Неопределено»)
НайденнаяСтрокаДЗ = ДеревоЗначений . Строки . Найти ( «Первый (вложенный) элемент» , «Наименование» , Истина);

// Анализ результата поиска
Если НайденнаяСтрокаДЗ = Неопределено Тогда
Сообщить ( «Строка не найдена» );
Иначе // вренёт первую найденную строку
Сообщить ( «Найдена: » + НайденнаяСтрокаДЗ . Наименование + » (» + НайденнаяСтрокаДЗ . Родитель . Наименование + «)» );
КонецЕсли;

&НаСервере
Процедура ПоискВсехСтрокВДеревеЗначений ()

// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение ( «ДеревоЗначНаФорме» );

// Создаем структуру для поиска (условие)
НаименованиеДляПоиска = «Первый (вложенный) элемент» ;
ПараметрыОтбора = Новый Структура ;
ПараметрыОтбора . Вставить ( «Наименование» , НаименованиеДляПоиска );

// Поиск всех строк содержащих наименование «Первый (вложенный) элемент»
МассивСтрок_ДЗ = ДеревоЗначений . Строки . НайтиСтроки ( ПараметрыОтбора , Истина);

// Проверка найдены ли строки
Если МассивСтрок_ДЗ . Количество () = 0 Тогда
Сообщить ( «Ни одной строкис наименованием » + НаименованиеДляПоиска + » не найдено!» );
КонецЕсли;

// Перебор строк
Для Каждого Строка_ДЗ Из МассивСтрок_ДЗ Цикл

Если Строка_ДЗ . Родитель = Неопределено Тогда
Сообщить ( «Корень дерева значений: » + Строка_ДЗ . Наименование );
Иначе
Сообщить ( Строка_ДЗ . Наименование + » — » + Строка_ДЗ . Родитель . Наименование );
КонецЕсли

&НаСервере
Процедура УдалениеСтрокиИзДереваЗначений ()

// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение ( «ДеревоЗначНаФорме» );
// С помощью данных методов возможно удаление конкретных строк
// Важно! При удалении либо очистки строки — все её подчинённые строки удалятся

// 1.Очистка всех строк
ДеревоЗначений . Строки . Очистить ();

// 2. Удаление по конкретному индексу
ДеревоЗначений . Строки . Удалить ( 0 );

// 3.Или удаление по конкретному наименованию
НайтиСтроку = ДеревоЗначений . Строки . Найти ( » Легированная сталь » , «Наименование» );
Если НЕ НайтиСтроку = Неопределено Тогда
ДеревоЗначений . Строки . Удалить ( НайтиСтроку );
КонецЕсли;

ЗначениеВРеквизитФормы ( ДеревоЗначений , «ДеревоЗначНаФорме» ); // Преобразование в реквизит формы (табличное поле)

Источник

Оцените статью