Дано:

Двухуровневое дерево:

Родитель1
    ПотомокР1.1
    ПотомокР1.2
    ПотомокР1.3
    ПотомокР1.N
Родитель2
    ПотомокР2.1
    ПотомокР2.2
    ПотомокР2.3
    ПотомокР2.N
РодительN
    ПотомокРN.1
    ПотомокРN.2
    ПотомокРN.3
    ПотомокРN.N

Пользователь задает несколько условий на значения потомков (Реквизит1Потомка Равно ЗначениеРеквизита1; Реквизит2Потомка НЕ Равно ЗначениеРеквизита2 и т.д.) добавляя условия в ТЧ. Между условиями может быть И/ИЛИ

Найти:

Алгоритм проверки соответствия потомков списку введенных условий.

Есть какие-нибудь идеи?
---
Для Каждого Стр из ТЗУсловий Цикл
   ЭлементДерева = ДеревоЭлементов.Найти(Стр.Потомок,,Истина);
   Если ЭлементДерева <> Неопределено Тогда
      РезультатВыполнения = Вычислить(ЭлементДерева[Строка(Стр.Реквизит)]+Стр.Условие+Стр.ЗначениеРеквизита);
   КонецЕсли;
КонецЦикла;
условия задавать общепринятыми обозначениями, <,>,<>,=,НЕ.
---
mozz, А что должно получиться на выходе?

В чем именно у Вас сложности?
---
M.Shalimov, На выходе должно получиться дерево, очищенное от потомков, не удовлетворяющих условиям.
Список условий заранее не известен.
Это может быть что-то типа: Потомок.Поставщик = ЗначениеПоставщик И (Потомок.Цена = ЗначениеЦена1 ИЛИ Потомок.Цена = ЗначениеЦена2) и т.д.
Список условий получаем из ТЧ выражения И/ИЛИ оттуда же.
---
mozz, пример ТЧ напиши, а то не понятно немного
---
NightGod,

примерно такая ТЧ на входе:

```1c
    ИИЛИ Фильтр по Вид сравнения Правое значение
    ПервыйФильтр Поставщик Равно Давальческий
    И Срок НЕРавно 10-12W
    И Приемка Равно 1
    ИЛИ Приемка Равно Импорт
```
---
mozz, может отбор замутить и в него передать твою ТЧ построчно?
---
mozz,
Можно создать схему СКД, добавить объектный набор, в него поместить дерево, а адльше типовыми средствами СКД работать.
Быстро, просто и оптимально.
---
mozz,
Второй вариант, в любом удобоном для Вас виде организовать хранение отбора.
Сделать рекурсивную функцию по обратному обходу строк дерева, с обходом вложенных строк.

Третий вариант, обойти дерево (рекурсия, ибо количество подчиненных строк неизвестно), во время обхода преобразовать к таблице значений, ролдителей строк добавить в строки ТЗ.
Дальше пишите запрос к ТЗ, помещаете во временную таблицу и дьяволически пишите условия для выборки.
Полученную ТЗ обртно преобразуетет к дереву.
---
в свое время перебирал дерво таким образом:

 Для каждого СтрокаПервогоУровня из ДеревоЗаказы.Строки цикл
  Для каждого СтрокаВторогоУровня Из СтрокаПервогоУровня.Строки Цикл
   Если ЭлементыФормы.Заказы.ТекущаяСтрока.НомерЗаказ = СтрокаВторогоУровня.НомерЗаказ тогда

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

Если из ссылок сделаем строки то будет так:

Вычислить(""+"="+"КакойтоКонтрагент")

На это пишет "Ошибка компиляции при вычислении выражения или выполнения фрагмента кода"
---
```1c
    Выполнить("Условие = "+ОбщееПравило)
    Если Условие Тогда
```

Общее правило при этом "Справочник.Контрагенты.ПустаяСсылка()=Справочник.Контрагенты.КакойтоКонтрагент"
Попробуйте так
---
Sevens,

Выполнить("Условие = "+ "Справочники.Контрагенты.ПустаяСсылка() = Справочники.Контрагенты.Давальческий")

{(1,1)} Ожидается выражение

(При этом Справочники.Контрагенты.Давальческий - предопределенный элемент справочника Контрагенты)
---
Я за скд и стандандартные отборы скд.
---
Решил задачу монструозно:

Не очень красиво, но работает...

&НаСервере
Процедура ФильтроватьДеревоНаСервере()
     Дерево = ДанныеФормыВЗначение(ТаблицаАнализ, Тип("ДеревоЗначений"));
    ТзУдаляемых = Новый ТаблицаЗначений;
    ТзУдаляемых.Колонки.Добавить("Строки");
    ТзУдаляемых.Колонки.Добавить("СтрокиУд");

 Для Каждого СтрокаПервогоУровня Из Дерево.Строки Цикл
 Для каждого СтрокаВторогоУровня Из СтрокаПервогоУровня.Строки Цикл
 Если НЕ ПодходитПоФильтрам(СтрокаВторогоУровня) тогда
             Новая = ТзУдаляемых.Добавить();
             Новая.Строки = СтрокаПервогоУровня.Строки;
             Новая.СтрокиУд = СтрокаВторогоУровня;
 КонецЕсли;
 КонецЦикла;
 КонецЦикла;

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

    ЗначениеВДанныеФормы(Дерево, ТаблицаСФильтром);
 КонецПроцедуры

 &НаСервере
 Функция ПодходитПоФильтрам(СтрокаДерева)

    ТЗУсловий = ДанныеФормыВЗначение(НастройкиФильтров, Тип("ТаблицаЗначений"));

   РезультатПроверки = Истина;
   Добавочное = Ложь;

 Для каждого Стр Из ТЗУсловий Цикл
 Если Стр.ИИЛИ = "ИЛИ" тогда
 Если Стр.ВидСравнения = "Равно" тогда
 Если СтрокаДерева[Строка(Стр.ФильтрПо)] = Стр.ПравоеЗначение тогда
               Добавочное = Истина;
 Иначе
               Добавочное = Ложь;
 КонецЕсли;
            РезультатПроверки = РезультатПроверки ИЛИ Добавочное;
 Иначе
 Если СтрокаДерева[Строка(Стр.ФильтрПо)] <> Стр.ПравоеЗначение тогда
               Добавочное = Истина;
 Иначе
               Добавочное = Ложь;
 КонецЕсли;
            РезультатПроверки = РезультатПроверки ИЛИ Добавочное;
 КонецЕсли;
 Иначе
 Если Стр.ВидСравнения = "Равно" тогда
 Если СтрокаДерева[Строка(Стр.ФильтрПо)] = Стр.ПравоеЗначение тогда
               Добавочное = Истина;
 Иначе
               Добавочное = Ложь;
 КонецЕсли;
            РезультатПроверки = РезультатПроверки И Добавочное;
 Иначе
 Если СтрокаДерева[Строка(Стр.ФильтрПо)] <> Стр.ПравоеЗначение тогда
               Добавочное = Истина;
 Иначе
               Добавочное = Ложь;
 КонецЕсли;
            РезультатПроверки = РезультатПроверки И Добавочное;
 КонецЕсли;
 КонецЕсли;

 КонецЦикла;

 Возврат РезультатПроверки;

 КонецФункции // ПодходитПоФильтрам()