Имя: Пароль:
1C
1С v8
подскажите по рекурсии
0 LivingStar
 
21.03.12
12:24
не работает функция, пока что тестовая, довожу до работоспособности. но она не возвращает значение, подскажите как правильно?

// №15. Процедура пересчета суммы полатежа, рассчета текущей оплаты.
Функция ПересчетСуммыПлатежа(ТЗ,Инд)
   Рез_ = ТЗ.Получить(Инд);
   х = 0;
   Если (НомерПриложенияПриОплате <> Рез_.Номерприложения) и Инд<>0 Тогда
       СпУникальностиОплат_1.Очистить();
       СпУникальностиОплат_2.Очистить();
       Оплачивается = 0;
       ТекОпл       = кОплате;
       кОплате      = 0;
       Возврат        ТекОпл;
   КонецЕсли;
   Если СпУникальностиОплат_1.НайтиПоЗначению(Рез_.НомерЗаказа     + " " +
                                              Рез_.НомерПриложения + " " +
                                              Рез_.НомерПоручения  + " " +
                                              Рез_.СуммаВзаиморасчета) = неопределено Тогда
       Если Оплачивается = 0 Тогда
           Если ОплаченныеСуммы.НайтиПоЗначению(Рез_.НомерЗаказа + " " + ?(Рез_.СуммаОплатыЗаказа=0,Рез_.СуммаЗаказа,Рез_.СуммаОплатыЗаказа)) = Неопределено Тогда
               Оплачивается = ?(Рез_.СуммаОплатыЗаказа=0,Рез_.СуммаЗаказа,Рез_.СуммаОплатыЗаказа);
           Иначе
               Инд = Инд + 1;
               //Возврат "-";
           КонецЕсли;
       ИначеЕсли Оплачивается < 0 Тогда
       ИначеЕсли Оплачивается > 0 Тогда
       КонецЕсли;
       Если кОплате = 0 Тогда
           кОплате     = ?(кОплате=0,Рез_.СуммаВзаиморасчета,кОплате+Рез_.СуммаВзаиморасчета);
           Оплачивается = Оплачивается - кОплате;            
           СпУникальностиОплат_1.Добавить(Рез_.НомерЗаказа     + " " +
                                          Рез_.НомерПриложения + " " +
                                          Рез_.НомерПоручения  + " " +
                                          Рез_.СуммаВзаиморасчета);
       Иначе
           Оплачивается = Оплачивается - кОплате;            
           СпУникальностиОплат_1.Добавить(Рез_.НомерЗаказа     + " " +
                                          Рез_.НомерПриложения + " " +
                                          Рез_.НомерПоручения  + " " +
                                          Рез_.СуммаВзаиморасчета);
       КонецЕсли;
       Если Оплачивается > 0 Тогда
           кОплате                  = 0; // сумма переплаты переходит в переменную кОплате для следующих операций с суммами оплаты                
           НомерПриложенияПриОплате = Рез_.Номерприложения;
           НомерПоручения           = Рез_.НомерПоручения;
           Инд     = Инд + 1;
           ПересчетСуммыПлатежа(ТЗ,Инд);    
       ИначеЕсли Оплачивается < 0 Тогда
           Если ОплаченныеСуммы.НайтиПоЗначению(Рез_.НомерЗаказа + " " + Рез_.СуммаОплатыЗаказа) = неопределено Тогда
               ОплаченныеСуммы.Добавить(   Рез_.НомерЗаказа + " " + СуммыКОплате[т]);
               т = т +1;
           КонецЕсли;
           кОплате      = Оплачивается*-1; // сумма переплаты переходит в переменную кОплате для следующих операций с суммами оплаты                
           Оплачивается = 0;
           НомерПриложенияПриОплате = Рез_.Номерприложения;
           НомерПоручения           = Рез_.НомерПоручения;
           Инд = Инд + 1;
           ПересчетСуммыПлатежа(ТЗ,Инд);    
       КонецЕсли;
       ТекОпл      = Оплачивается * -1;
       Если Оплачивается > 0 Тогда
           Если НомерПоручения <> Рез_.НомерПоручения Тогда
               кОплате = Рез_.СуммаВзаиморасчета;    
           Иначе
               кОплате = 0;    
           КонецЕсли;
       ИначеЕсли Оплачивается <= 0 Тогда
           Если ОплаченныеСуммы.НайтиПоЗначению(Рез_.НомерЗаказа + " " + Рез_.СуммаОплатыЗаказа) = неопределено Тогда
               Если ОплаченныеСуммы.Количество() > т Тогда
                   ОплаченныеСуммы.Добавить(   Рез_.НомерЗаказа + " " + СуммыКОплате[т]);
               КонецЕсли;
               т = т +1;
           КонецЕсли;
           кОплате      = Оплачивается*-1; // сумма переплаты переходит в переменную кОплате для следующих операций с суммами оплаты                
           Оплачивается = 0;
       КонецЕсли;
       НомерПриложенияПриОплате = Рез_.Номерприложения;
       НомерПоручения           = Рез_.НомерПоручения;
   Иначе
       Инд     = Инд + 1;
       //Возврат "-";    
   КонецЕсли;    
   //Инд     = Инд + 1;
   Возврат 0;
КонецФункции
1 Maxus43
 
21.03.12
12:26
иди в больницу, хорош работать
2 LivingStar
 
21.03.12
12:27
возврат срабатывает в этом блоке
   Если (НомерПриложенияПриОплате <> Рез_.Номерприложения) и Инд<>0 Тогда
       СпУникальностиОплат_1.Очистить();
       СпУникальностиОплат_2.Очистить();
       Оплачивается = 0;
       ТекОпл       = кОплате;
       кОплате      = 0;
       Возврат        ТекОпл;
   КонецЕсли;

но она сбрасывается потом в      ПересчетСуммыПлатежа(ТЗ,Инд);  

а не в первичный вызов функции из основной программы
3 YFedor
 
21.03.12
12:27
(0) Отладчик спасет отца русской демократии
4 ЗлобнийМальчик
 
21.03.12
12:27
если вам надо подсказать по рекурсии - не пользуйте рекурсию.
5 Fragster
 
гуру
21.03.12
12:27
по рекурсии подскажу одно - у меня 1ска падает на глубине рекурсии где-то около 1500
6 Fragster
 
гуру
21.03.12
12:28
(5)+ это я условие выхода неправильно задал, да
7 Ненавижу 1С
 
гуру
21.03.12
12:28
(2)
>> но она сбрасывается потом в      ПересчетСуммыПлатежа(ТЗ,Инд);  
>> а не в первичный вызов функции из основной программы

сбрасывает в предыдущий вызов
8 ЗлобнийМальчик
 
21.03.12
12:29
(5) че прям весь сервер????
9 LivingStar
 
21.03.12
12:29
(4) бъюсь с одной задачей и наделал глобальных переменных но все тупиково
подумал сделать это рекурсией, но то же что то не то!
10 LivingStar
 
21.03.12
12:30
(7) а как сделать то что бы сраболтал возврат?
11 Ненавижу 1С
 
гуру
21.03.12
12:32
(10) слишком тяжелый код чтобы понять ДЛЯ ЧЕГО?
12 Fish
 
гуру
21.03.12
12:32
(8) Не, сервер не падает. Падает клиент. Это известная фишка 1С. У меня даже есть обработочка со счетчиком рекурсии. 8.1 падала где-то на 800 цикле, 8.2 стала падать попозже :))) При этом 1с даже "мяу" не говорит, просто тупо вылетает.
13 Fragster
 
гуру
21.03.12
12:33
(8) не, у меня то в толстом клиенте обычном приложении выполнялось
14 ЗлобнийМальчик
 
21.03.12
12:34
>>бъюсь с одной задачей и наделал глобальных переменных но все тупиково
>>подумал сделать это рекурсией, но то же что то не то!
забейте на рекурсию - это значительно сложнее обычного кода (люди так не мыслят)
разбейте задачу на блоги-подпрограммы - тогда вам бде самому понятнее
15 Fragster
 
гуру
21.03.12
12:35
(14) да ладно, кирпич весит килограмм и пол кирпича
16 Ненавижу 1С
 
гуру
21.03.12
12:35
(14) это смотря у кого какой склад ума
17 Fish
 
гуру
21.03.12
12:36
(5) Сейчас проверил, 8.2.15 падает на глубине рекурсии 1801 :)
18 Wern
 
21.03.12
12:38
Любую рекурсию можно переписать, без ее использования.
19 Fish
 
гуру
21.03.12
12:39
(18) А обход дерева с неизвестной глубиной вложенности сделай без рекурсии.
20 Fish
 
гуру
21.03.12
12:41
(14) "забейте на рекурсию - это значительно сложнее обычного кода (люди так не мыслят)"
А по мне так ничего сложного. Просто, чтобы понять рекурсию, надо понять рекурсию :)))
21 Ненавижу 1С
 
гуру
21.03.12
12:41
(19) я могу сделать
22 Wern
 
21.03.12
12:42
А в чем проблема? цикл, в цикле мы либо погружаемся глубже если есть куда, либо берем следующий того же уровня, если он есть, либо возвращаемся к родителю. если возвращаться некуда значит все закончили.
23 Ненавижу 1С
 
гуру
21.03.12
12:43
(22) надо еще хранить стек текущей вложенности
24 Fish
 
гуру
21.03.12
12:44
(23) Можно, конечно и без рекурсии, но, имхо, рекурсией как-то проще и понятнее.
25 Wern
 
21.03.12
12:47
(23) Необязательно стек, он нужен только для возврата к родителю. А родителя и без стека найти не сложно.
26 Ненавижу 1С
 
гуру
21.03.12
12:47
24) я ни с кем не спорю, более того - делал бы с рекурсией
27 Mort
 
21.03.12
12:49
(23) Компилятор так и делает ))) Тока зачем делать это за него?
28 Ненавижу 1С
 
гуру
21.03.12
12:50
(25) иногда невозможно
29 Ненавижу 1С
 
гуру
21.03.12
12:50
(27) см (26)
30 Fish
 
гуру
21.03.12
12:50
(25) Давай пример кода, для справочника с уровнем вложенности 10.
31 Wern
 
21.03.12
12:54
(30) смотри (22) справочник от дерева ничем не отличается.
32 Fish
 
гуру
21.03.12
13:05
(31) Пример в (22) не взлетит.