Имя: Пароль:
1C
1С v8
Переполнение стека встроенного языка на сервере 1С
0 lite777
 
26.10.20
09:00
Добрый день, 1с Розница, создал подписку на событие ,Источник РегистрНакопленияНаборЗаписей.Продажи, Событие-ПриЗаписи , обработчик в общем модуле-,
цель заполнить созданный самостоятельно реквизит Регистра продажи-КОНТРАГЕНТ,при изменение РГ продажи ,
в частности при проведении чека выдает такую ошибку--"Переполнение стека встроенного языка на сервере"


Процедура РГПродажиПриЗаписи(Источник, Отказ, Замещение) Экспорт
                
        Для Каждого ТекДвижение Из  Источник Цикл
            
            ТекДвижение.Контрагент=ТекДвижение.Регистратор.Клиент ;
        
            
        КонецЦикла;
        Источник.Записать() ;

КонецПроцедуры
1 Волшебник
 
26.10.20
09:02
При изменении идёт запись объекта Источник, в нём вызывается РГПродажиПриЗаписи, в которой вызывается Источник.Записать()...

бесконечная рекурсия
2 ДенисЧ
 
26.10.20
09:03
А ты сам прикинь..
Ты записываешь источник, ака набор записей регистра. При это срабатывает подписка при записи. В которой ты записываешь источник. При это срабатывает подписка при записи...
Продолжать? )))
Белые люди (BLdM) такие финты делают в ПередЗаписью
3 Конструктор1С
 
26.10.20
09:11
(0) в этом коде ужасно всё. Это надо умудриться, чтобы на четыре строки кода сделать три грубые ошибки
4 lite777
 
26.10.20
09:32
(3) Где три ?Не умничай
5 lodger
 
26.10.20
09:35
(4)
первая ошыбка Источник.Записать() ;
вторая ТекДвижение.Регистратор.Клиент ;
третья размещение "ТекДвижение.Регистратор.Клиент ;" в цикле.
6 lodger
 
26.10.20
09:35
я так вижу (с)
7 ДенисЧ
 
26.10.20
09:36
(5) 2 и 3 - пофиг. После первого обращения уже в кеше всё. Да и, скорее всего, регистратор в этот момент уже в кеше.
8 lite777
 
26.10.20
09:40
Прямо разнесли в пух и прах)
9 lodger
 
26.10.20
09:47
(7) это когда регистратор переменная. а когда регистратор это реквизит тикающей переменной (пускай даже один и тот же), платформа может и не оптимизировать гуанокод.
10 lite777
 
26.10.20
09:52
А как надо сделать то в итоге ?
11 H A D G E H O G s
 
26.10.20
09:56
Еще и в ПриЗаписи.
Нифига он не запишет.
12 H A D G E H O G s
 
26.10.20
09:57
Именно поэтому автор попробовал Записать()

На шару.
13 H A D G E H O G s
 
26.10.20
09:57
Используйте ПередЗаписью()
14 lodger
 
26.10.20
09:58
(10) перевесь подписку на ПередЗаписью.

в начале процедура из отбора или первой записи достань регистратор.
проверь тип регистратора на нужный
получи из регистратора Клиент.

а дальше как было.
15 SleepyHead
 
гуру
26.10.20
10:02
(10) а нафига ты вообще источник перезаписываешь?
16 lite777
 
26.10.20
10:13
Процедура РГПродажиПриЗаписи(Источник, Отказ, Замещение) Экспорт
    
    
    Для Каждого ТекДвижение Из  Источник Цикл

            
            ТекДвижение.Контрагент=ТекДвижение.ДокументПродажи.Клиент ;
            


        КонецЦикла;


    
    
КонецПроцедуры
17 lite777
 
26.10.20
10:13
так вроде идет
18 ДенисЧ
 
26.10.20
10:16
(17) неправильно. У тебя не попадёт результат
В (14) написано праувильно
19 lite777
 
26.10.20
10:19
(18) в РГ продажи котрагент залетает норм
20 lite777
 
26.10.20
10:47
Спасибо! Всем
21 Конструктор1С
 
27.10.20
10:33
(4) ошибки:
1. Вместо ПриЗаписи нужно было использовать ПередЗаписью. При входе в обработчик ПриЗаписи объект уже записан в БД
2. Источник.Записать() приводит к повторной записи, это твоя бесконечная рекурсия
3. ТекДвижение.Регистратор.Клиент считывает документ со всеми табличные частами и сохраняет его в КЭШе, совершенно лишнее дёрганье данных. Правильнее получить эти данные один раз и затем подставлять
есть ещё пара моментов, до которых можно было бы докапаться. Но пока что хватит
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.