Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
05 окт 2025, 05:54

Проблема с деревом значений

Автор skillful, 02 окт 2025, 08:29

0 Пользователей и 1 гость просматривают эту тему.

skillful

Здравствуйте. Помогите решить проблему. Начал работать с деревом значений. Дерево находится на форме обработки. Код такой:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

ДеревоЗначений = РеквизитФормыВЗначение("Типы");

Корень1 = ДеревоЗначений.Строки.Добавить();
Корень1.Наименование = "Один";
Корень1.Картинка = БиблиотекаКартинок.ТипНеопределено;

Корень2 = ДеревоЗначений.Строки.Добавить();
Корень2.Наименование = "Два";
Корень2.Картинка = БиблиотекаКартинок.ТипЧисло;

Корень3 = ДеревоЗначений.Строки.Добавить();
Корень3.Наименование = "Три";
Корень3.Картинка = БиблиотекаКартинок.ТипСтрока;

Корень4 = ДеревоЗначений.Строки.Добавить();
Корень4.Наименование = "Четыре";
Корень4.Картинка = БиблиотекаКартинок.ТипДата;

Корень5 = ДеревоЗначений.Строки.Добавить();
Корень5.Наименование = "Пять";
Корень5.Картинка = БиблиотекаКартинок.ТипБулево;

ЗначениеВРеквизитФормы(ДеревоЗначений, "Типы");

КонецПроцедуры

Дерево заполнилось. Выполняю определенный код удаления строк по индексу: ДЛЯ ПРИМЕРА ПЫТАЮСЬ УДАЛИТЬ ВСЕ СТРОКИ

&НаСервере
Функция ПоискНаСервере()

ДерЗнач = РеквизитФормыВЗначение("Типы");


Для Каждого Строка_Рек Из ДерЗнач.Строки Цикл

//удаление по индексу
ИндексСтроки = ДерЗнач.Строки.Индекс(Строка_Рек);
ДерЗнач.Строки.Удалить(ИндексСтроки);

КонецЦикла;

ЗначениеВРеквизитФормы(ДерЗнач, "Типы");

КонецФункции

После первого выполнения кода остаются строки
Два
Четыре

После второго выполнения кода остаются строки
Четыре

После Третьего выполнения кода
Пусто

Вроде как сразу должны все строки удалиться, после первого выполнения кода, а у меня постепенно удаляются.

Пробовал так еще удалить строки, чтобы сразу осталась строка "Три"
КолВоСимвол = СтрНайти(НРег(Строка_Рек.Наименование), НРег("Три"), НаправлениеПоиска.СНачала);

Если КолВоСимвол = 0 Тогда

НайдСтрока = ДерЗнач.Строки.Найти(Строка_Рек.Наименование, "Наименование");
Если НайдСтрока <> Неопределено Тогда
ДерЗнач.Строки.Удалить(НайдСтрока);
КонецЕсли;

КонецЕсли;

Первое выполнение
Два
Три
Пять

Второе и последующие выполнения
Три

Что, я сделал не правильно?

antoneus

Цитата: skillful от 02 окт 2025, 08:29Что, я сделал не правильно?

Пытался изменить коллекцию во время обхода этой коллекции. Rookie mistake)

Если надо удалить все строки - ДерЗнач.Строки.Очистить()Если надо удалить все строки, не гоняя дерево из реквизита в значение и обратно - Типы.ПолучитьЭлементы().Очистить()
Если надо удалить строки по условию - создаем массив, в него складываем удаляемые строки (на самом деле это ссылки на строки), потом в цикле по массиву удаляем строки дерева.

ДерЗнач.Строки.Удалить(ЭлементМассива)

skillful

Спасибо большое. Заработало! :ooifh:

skillful

antoneus, Подскажите пожалуйста, а как удалить строки второго уровня по условию? Второй массив создавать?

antoneus

Если эти строки можно найти отбором, через метод НайтиСтроки - тогда вызываем этот метод со вторым параметром Истина - тогда будет искать на всех уровнях.

Если условие посложнее - применяем великую и ужасную рекурсию, массива хватит одного.

skillful

Не получилось, не пойму, что не так, не работает во втором уровне поиск. Вот код рабочий только для первого уровня:
ДеревоЗначений = РеквизитФормыВЗначение("Типы");   
   
    Корень1 = ДеревоЗначений.Строки.Добавить();
    Корень1.Наименование = "Произвольный";
    Корень1.Картинка = БиблиотекаКартинок.ТипНеопределено;
    //Корень1.Тип = БиблиотекаКартинок.ТипНеопределено;
   
   
    Корень2 = ДеревоЗначений.Строки.Добавить();
    Корень2.Наименование = "Число";
    Корень2.Картинка = БиблиотекаКартинок.ТипЧисло;
   
    Корень3 = ДеревоЗначений.Строки.Добавить();
    Корень3.Наименование = "Строка";
    Корень3.Картинка = БиблиотекаКартинок.ТипСтрока;
   
    Корень4 = ДеревоЗначений.Строки.Добавить();
    Корень4.Наименование = "Дата";
    Корень4.Картинка = БиблиотекаКартинок.ТипДата;
   
   
    Корень5 = ДеревоЗначений.Строки.Добавить();
    Корень5.Наименование = "Булево";
    Корень5.Картинка = БиблиотекаКартинок.ТипБулево;
   
   

    //**********   
   
    КореньСправочники = ДеревоЗначений.Строки.Добавить();
    КореньСправочники.Наименование = "СправочникСсылка";
    КореньСправочники.Картинка = БиблиотекаКартинок.Справочник;

    Для Каждого Спр Из Метаданные.Справочники Цикл

        Справочник = КореньСправочники.Строки.Добавить();
        Справочник.Наименование = Спр.Имя;
        Справочник.Картинка = БиблиотекаКартинок.Справочник;
   
    КонецЦикла;

   
   
   
    ДерЗнач = РеквизитФормыВЗначение("Типы");   
   
   
    ПоискТипа = "Авансовый";

   


    МассивУдаляемыхСтрок = Новый Массив;
   
    Для Каждого Строка_Рек Из ДерЗнач.Строки Цикл

        //Первый уровень - работает
        КолВоСимвол = СтрНайти(НРег(Строка_Рек.Наименование), НРег(ПоискТипа), НаправлениеПоиска.СНачала);
       
        Если КолВоСимвол = 0 Тогда       
           
            Если Строка_Рек.Наименование <> "СправочникСсылка" Тогда
                МассивУдаляемыхСтрок.Добавить(Строка_Рек);
            КонецЕсли;

        КонецЕсли;
        //Первый уровень - работает   

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

antoneus

Ну если во втором уровне искать, то

   
    Для Каждого Строка_Рек Из ДерЗнач.Строки Цикл
        МассивУдаляемыхСтрок = Новый Массив;
        Для Каждого СтрокаВторогоУровня Из Строка_Рек.Строки Цикл

            КолВоСимвол = СтрНайти(НРег(СтрокаВторогоУровня.Наименование), НРег(ПоискТипа), НаправлениеПоиска.СНачала);         

            Если КолВоСимвол = 0 Тогда       
           
                Если СтрокаВторогоУровня.Наименование <> "СправочникСсылка" Тогда
                    МассивУдаляемыхСтрок.Добавить(СтрокаВторогоУровня);
                КонецЕсли;

            КонецЕсли;
        КонецЦикла;
        Для Каждого ЭлементМассива Из МассивУдаляемыхСтрок Цикл
   
            Строка_Рек.Строки.Удалить(ЭлементМассива)
   
        КонецЦикла;

    КонецЦикла;   
   

skillful

Цитата: antoneus от 03 окт 2025, 13:12Ну если во втором уровне искать, то
Спасибо большое!!!

Похожие темы (5)

Рейтинг@Mail.ru

Поиск