Имя: Пароль:
1C
1С v8
8.2. Управляемое. Странное поведения выполнения кода рекурсивной функции
0 Pro-tone
 
23.09.11
10:18
Написал функцию для перебора строк дерева значений:


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

   КонецЦикла;    
   
   Возврат Рез;

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


После условного выхода из цикла по "Прервать" идет в "КонецФункции" как и должно быть, а вот после начинается хз что - выполнение идет снова в рекурсивный вызов  внутри цикла "ПроверкаСуществующихПозицийСервер(СтрокаДерева, ПарамМаршрут, ПарамТС, Уровень+1);" ну и дальше понимаете только все хуже.

Что это означает ? Глюки платформы ?
1 Axel2009
 
23.09.11
10:19
так там небось прервать для одного из вызова функции, а в стеке штук 10, прервано из 1го, а в 9 то тоже надо прерывать
2 Defender aka LINN
 
23.09.11
10:20
(0) Оно туда не "идет". Оно туда возвращается.
3 Pro-tone
 
23.09.11
10:21
(1) мы прерываем цикл, "Прервать" вне него не работает
4 Axel2009
 
23.09.11
10:21
(3) цикл то прервал. а весь стек вызовов то кто прерывать будет?
5 Pro-tone
 
23.09.11
10:22
(2) я писал точно такое же на 7.7 все отлично прерывалось и выходило из цикла, так выводили в 7.7 например группировки в отчетах
6 Pro-tone
 
23.09.11
10:22
(4) ок. Как прервать весь стек вызовов если не через "Прервать" ?
7 Axel2009
 
23.09.11
10:26
заводишь переменную "НуЧтоПораПрерывать" = Истина. и прерывай
8 Pro-tone
 
23.09.11
10:38
Сделал так:

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


Теперь вываливает ошибку:

{Справочник.Контрагенты.Форма.ФормаЭлемента.Форма(198)}: Ошибка при вызове метода контекста (ПроверкаСуществующихПозицийСервер)
   Если ПроверкаСуществующихПозицийСервер(Дерево,СтруктураВыбораМаршрута.Маршрут,СтруктураВыбораМаршрута.ТС) = Ложь Тогда
по причине:
Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа.
по причине:
Ошибка преобразования данных XDTO:
НачалоСвойства: param    Форма: Элемент    Тип: {http://www.w3.org/2001/XMLSchema}anyType
по причине:
Ошибка отображения типов:
Отсутствует отображение для типа '{http://v8.1c.ru/8.1/data/core}ValueTree'
9 Pro-tone
 
23.09.11
10:43
Я не пойму ! Почему такая ошибка, я ведь не возвращаю тип "ДеревоЗначений", я же возвращаю функцией в форму "Булево" !
10 Pro-tone
 
23.09.11
10:58
.
11 Pro-tone
 
23.09.11
11:06
..
12 Axel2009
 
23.09.11
11:10
а в остановке по ошибке что в Рез содержится?
13 Pro-tone
 
23.09.11
11:11
"Истина"
14 Pro-tone
 
23.09.11
11:11
&НаСервере
Функция  ПроверкаСуществующихПозицийСервер(ВыводимаяСтрока, ПарамМаршрут, ПарамТС, Уровень=0, НуЧтоПораПрерывать = Ложь)
   
   
   Если Уровень = 0 Тогда
       
       ВыводимаяСтрока = ДанныеФормыВЗначение(ВыводимаяСтрока, Тип("ДеревоЗначений"));
       ДеревоЗН = ВыводимаяСтрока;
       ЗначениеВДанныеФормы(ДеревоЗН, Дерево);

       Рез = Истина;
       
   КонецЕсли;
       
   Для Каждого СтрокаДерева Из ВыводимаяСтрока.Строки Цикл
       
       Если  НуЧтоПораПрерывать = Истина Тогда
           Рез = Ложь;
           Прервать;
       КонецЕсли;    
       
       Если СтрокаДерева.Маршрут = ПарамМаршрут И
           СтрокаДерева.ТС = ПарамТС  Тогда
           Рез = Ложь;
           НуЧтоПораПрерывать = Истина;
       КонецЕсли;
       
       ПроверкаСуществующихПозицийСервер(СтрокаДерева, ПарамМаршрут, ПарамТС, Уровень+1, НуЧтоПораПрерывать);
       
   КонецЦикла;    
   
   Возврат Рез;
   
КонецФункции


вернее ЛОЖЬ
15 Axel2009
 
23.09.11
11:14
(14) а если в самом начале указать Возврат Ложь; ошибка тоже будет?
16 H A D G E H O G s
 
23.09.11
11:15
(9) Ты это дерево в параметрах возвращаешь
17 H A D G E H O G s
 
23.09.11
11:15
(9) У тебя же не через ЗНАЧ параметр передается.
18 Axel2009
 
23.09.11
11:16
либо 2ую функцию на сервере которая будет запускать рекурсивную функцию
19 Pro-tone
 
23.09.11
11:17
(15) да, та же ошибка

(16) (17) хм, надо так ?

Функция  ПроверкаСуществующихПозицийСервер(Знач(ВыводимаяСтрока), ПарамМаршрут, ПарамТС, Уровень=0, НуЧтоПораПрерывать = Ложь)
20 Axel2009
 
23.09.11
11:18
без скобок
21 Pro-tone
 
23.09.11
11:23
Вот так заработало !!!!!!!!

&НаСервере
Функция  ПроверкаСуществующихПозицийСервер(ЗНАЧ ВыводимаяСтрока, ПарамМаршрут, ПарамТС, Уровень=0, НуЧтоПораПрерывать = Ложь)
   
   
   Если Уровень = 0 Тогда
       
       ВыводимаяСтрока = ДанныеФормыВЗначение(ВыводимаяСтрока, Тип("ДеревоЗначений"));
       ДеревоЗН = ВыводимаяСтрока;
       ЗначениеВДанныеФормы(ДеревоЗН, Дерево);

       Рез = Истина;
       
   КонецЕсли;
       
   Для Каждого СтрокаДерева Из ВыводимаяСтрока.Строки Цикл
       
       Рез = Истина;

       Если  НуЧтоПораПрерывать = Истина Тогда
           Рез = Ложь;
           Прервать;
       КонецЕсли;    
       
       Если СтрокаДерева.Маршрут = ПарамМаршрут И
           СтрокаДерева.ТС = ПарамТС  Тогда
           Рез = Ложь;
           НуЧтоПораПрерывать = Истина;
       КонецЕсли;
       
       ПроверкаСуществующихПозицийСервер(СтрокаДерева, ПарамМаршрут, ПарамТС, Уровень+1, НуЧтоПораПрерывать);
       
   КонецЦикла;    
   
   Возврат Рез;
   
КонецФункции


(17), (20) Спасибо вам добрые люди !!!

Только я так в СП не нашел что такое "Знач" ((
22 MadHead
 
23.09.11
11:25
(21) по ссылке или по значению передается параметр
23 Pro-tone
 
23.09.11
11:41
(22) Ок. Спасибо
24 Axel2009
 
23.09.11
12:16
(23) в СП ищи Процедура или Функция. там описывается
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс