Имя: Пароль:
1C
 
ПослеЗаписиНаСервере() не выполняется, если до этого был Отказ = Истина
0 SeiOkami
 
15.04.20
11:55
Добрый день.

В общем, столкнулся со, скорее всего, банальной ситуацией.
На УФ документа есть событие ПослеЗаписиНаСервере()
И оно обрабатывает после записи дополнительные свойства объекта.
Так вот, оказалось, что это событие не выполнится, если документ не завершит транзакцию.
И нет никаких событий, которые позволят обработать доп.свойства документа уже после попытки записи.
Или есть какие-то способы?
1 Ёпрст
 
15.04.20
11:59
(0)Дык если записи не было, то и события нет.
Зачем оно вам ?
2 ДенисЧ
 
15.04.20
12:03
Если документ не записался - то откуда возьмётся ПослеЗаписи() ?
finally в 1с пока нет...
3 SeiOkami
 
15.04.20
12:11
(1), в процессе записи происходят проверки. И подробные данные о результатах этих проверок хранятся в ДопСвойствах.
Нужно после попытки записи (даже неудачной) эти данные получить и сохранить в данных формы
4 Ненавижу 1С
 
гуру
15.04.20
12:13
(3) зачем? что делать когда проведение будет из списка вызвано или вообще не интерактивно?
5 Cyberhawk
 
15.04.20
12:14
(4) Очевидно же - запишет в ЖР. А вот если из формы, то красиво хочет показать пользователю.
6 Ненавижу 1С
 
гуру
15.04.20
12:17
(5) показать пользователю и так можно
СообщениеПользователю никто не отменял
7 SeiOkami
 
15.04.20
12:28
(4), это работает только при интерактивной записи из формы документа
8 SeiOkami
 
15.04.20
12:29
(5), это не сообщения, а структура с данными, которые потом отображаются пользователю
9 Ёпрст
 
15.04.20
12:39
(3)Ну и пиши эту хрень в ПриЗаписи куда нужно, если ошибка..Нафига после ?
10 ДенисЧ
 
15.04.20
12:42
(9) Так если ПриЗаписи отвалится, так и транзакция тоже )))
Куда предлагаешь писать?
11 Ёпрст
 
15.04.20
13:44
(10) в файл
12 SeiOkami
 
15.04.20
14:05
(11), мне эти данные нужны на время существования формы документа. Зачем в файл писать? 0_о
13 Ёпрст
 
15.04.20
14:06
(12) тогда показывай сообщение
14 Ёпрст
 
15.04.20
14:06
или пихай в оповещение
15 Ёпрст
 
15.04.20
14:07
как сделано, например во всех типовых при печати чека
16 Fragster
 
гуру
15.04.20
14:23
оповещение из модуля объекта не отправить
17 SeiOkami
 
15.04.20
14:32
(15), оповещение из модуля объекта?
18 SeiOkami
 
15.04.20
14:32
пока что придумал только один вариант - передавать в параметры записи адрес хранилища, в которое помещать нужные данные.
А ПередЗаписью подключать обработчик ожидания, который сработает после записи и получит результат из хранилища...
Не факт что сработает))
19 dezss
 
15.04.20
14:44
А почему обработка идет именно после, а не при или перед?
Там что, данные сильно меняются?
20 fisher
 
15.04.20
14:48
А ты, если видишь что это интерактивная запись - не отказывайся от нее :) Тогда сможешь словить ПриЗаписиНаСервере(), обработать все что надо и отказаться уже там.
А адрес временного хранилища для своей структуры пихай в доп-свойства в ПередЗаписьюНаСервере()
21 fisher
 
15.04.20
14:49
Хотя о чем это я? Не надо хранилища. Ты ж в ПриЗаписиНаСервере прямо доп-свойства и поймаешь.
22 fisher
 
15.04.20
14:51
(19) Бывает так, что проверка очень "тяжелая" и получение всех нужных данных требует почти дублирования всего алгоритма проведения.
23 fisher
 
15.04.20
14:53
Поэтому проверки бывает выгодно организовывать по оптимистическому алгоритму. Изначально считаем что все хорошо, но если все же что-то пошло не так - то тогда уже откатываемся и сигнализируем.
24 Fragster
 
гуру
15.04.20
15:04
(18) жди, скоро может будет готов "сервер оповещений", там хоть что хоть куда послать можно
25 dezss
 
15.04.20
15:12
(22) Да эт понятно.
А вот зачем показывать что-то кроме ошибки при неудачной записи, не понимаю.
26 SeiOkami
 
15.04.20
15:20
(25), пользователям нужен более подробный отчет. Данные для него уже собраны на этапе записи документа. Чтобы не собирать данные повторно, я их передаю через ДополнительныеСвойства.
27 dezss
 
15.04.20
15:45
(26) Так при отказе и показывай их, как вариант.
А так, да. Событий для показа чего-то нет. Обработчик вариант, конечно, но только если они форму раньше не закроют.
28 trad
 
15.04.20
15:47
1. не делать отказ в ПриЗаписи()
2. разбирать доп.параметры в данные формы в ПриЗаписиНаСервере()
3. делать отказ в ПриЗаписиНаСервере() если доп.параметры соответствующим образом заполнены
29 trad
 
15.04.20
16:06
полная, правильная реализация, даже без учета ограничения (7), такая

Процедура ПередЗаписьюНаСервере(...)
  ТекущийОбъект.ДополнительныеСвойства.Вставить("Отказ", Ложь);
КонецПроцедуры

Процедура ПриЗаписи(...)
  //тут необходимые проверки
  Если ПроверкиНеПройдены Тогда
    Если ДополнительныеСвойства.Свойство("Отказ") Тогда
      //заполнить другие ДополнительныеСвойства для передачи в форму
      //если из формы, то отказа будет там
      ДополнительныеСвойства.Отказ = Истина;
    Иначе
      //если не из формы, то отказ будет тут
      Отказ = Истина;
    КонецЕсли
  КонецЕсли
КонецПроцедуры

Процедура ПриЗаписиНаСервере(...)
  Отказ = ТекущийОбъект.ДополнительныеСвойства.Отказ;
  //перекладываем в форму другие ДополнительныеСвойства
КонецПроцедуры
30 trad
 
15.04.20
16:13
ну и раз это документ, то, при наличии проведения, нужно его проскочить

Процедура ОбработкаПроведения()
  Если ДополнительныеСвойства.Свойство("Отказ") И ДополнительныеСвойства.Отказ Тогда
    Возврат;
  КонецЕсли

  //далее проведение
КонецПроцедуры
31 SeiOkami
 
16.04.20
10:04
(20), (28), Спасибо за решение!
Проверил, всё гуд работает.
32 Ненавижу 1С
 
гуру
16.04.20
10:06
(28) это все хорошо конечно, но усложняет логику - теперь бизнес-данные хотя и косвенно зависят от представления
то есть надо всегда помнить, про этот самый параметр
33 trad
 
16.04.20
10:14
(32) "теперь бизнес-данные хотя и косвенно зависят от представления"
это так, но ТС этого и надо
34 fisher
 
16.04.20
10:20
(32) Критикуя - предлагай :)
35 trad
 
16.04.20
10:23
(32) "то есть надо всегда помнить, про этот самый параметр"
А зачем помнить

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

С другой стороны, контекст объекта не зависит от этого свойства. Если объект его не учтет, то объекту это не помешает. А если форма "забудет" ему его дать, то код написан, в этом смысле, безопасно.
36 Ненавижу 1С
 
гуру
16.04.20
10:39
(35) ПриЗаписи вообще убрать нельзя, только с условием по параметру
ибо может быть проведение не из формы
37 trad
 
16.04.20
10:54
(36) кто-то предлагает ПриЗаписи убрать?
38 Ненавижу 1С
 
гуру
16.04.20
11:11
(38) >>1. не делать отказ в ПриЗаписи()
39 trad
 
16.04.20
11:45
(38) Не делать отказ - с целью добраться до ПриЗаписиНаСервере
Да, "не делать отказ" - параметрическое поведение. Код приведен в (29)

Запись/Проведение не из формы никак не пострадает
Запись/Проведение никак не пострадает если форма забудет сформировать параметр
40 Ненавижу 1С
 
гуру
16.04.20
11:49
(39) согласен, норма вариант
единственное в новых типовых стали бросать исключения, когда в проведении что-то пошло не так
41 Cyberhawk
 
16.04.20
11:51
(30) Угу, а потом еще "проскочить" все подписки на событие проведения, которые не анализируют Отказ, а молча делают свое дело :)
42 fisher
 
16.04.20
11:53
(39) Если в очередной момент забудут о том, что модуле документа нужно не Отказ ставить при интерактивном проведении, а ДополнительныеСвойства.Отказ - то форма перестанет ловить событие и красиво формировать отчет об ошибках. Неудобненько. Особенно учитывая, что это стопудово будет плавающей проблемой. Но все равно лучше вариантов не проглядывается.
(41) Ихнее молчаливое дело спокойно откатится в итоге. Тут проблемы нет.
43 trad
 
16.04.20
11:54
(41) полезно было бы услышать альтернативные возможности
44 trad
 
16.04.20
11:57
(42) не подготовил свойство - не получил "красивость". Все эта зависимость остается контексте одной формы. Норм же
45 Cyberhawk
 
16.04.20
11:58
(42) "Тут проблемы нет" // Ну, на самом деле есть, когда из формы начнут по пессимистичному сценарию проводить много разных сеансов. Удлиняем транзакцию и сопутствующие блокировки, когда могли бы сразу отлуп до обработок проведения выдать.
Случай редкий, конечно, т.к. ожидаемый сценарий оптимистичный все-таки, но все-таки такое интерфейсное ублажение - это лишняя трата мозготоплива - приходится помнить про этот нюанс.
46 trad
 
16.04.20
12:00
(42) "Ихнее молчаливое дело" может зависеть от проведения которого не случилось, следовательно, что может пойти не так и привести к исключению
47 Cyberhawk
 
16.04.20
12:01
(46) Или наоборот - "молчаливое дело" может рассчитывать, что, мол, раз дошли до обработки проведения и там не отказ, то надо куда-нибудь с кем-нибудь этой инфой поделиться. А там на самом деле уже отказ, просто он пропущен (оттянут до возвращения выполнения кода в форму).
48 Cyberhawk
 
16.04.20
12:02
Т.е., повторюсь, решение не безболезненное и поэтому неуниверсальное :(
49 fisher
 
16.04.20
12:03
(46) Это так. Но у ТС вряд ли будет пропуск проведения, как ты предполагаешь. Если бы нужные проверки можно было бы сделать без проведения, то и весь этот сыр-бор не нужен был. Т.е. вероятность исключения все равно остается, но она хотя бы не невелика. Тут уже ничего не поделаешь.
50 fisher
 
16.04.20
12:03
"хотя бы невелика"
51 fisher
 
16.04.20
12:04
(48) Да. Но вполне приемлемо, ИМХО, в отсутствие альтернатив.
52 trad
 
16.04.20
12:04
(47) "то надо куда-нибудь с кем-нибудь этой инфой поделиться"
Ну если эту "дележку инфой" делать в рамках транзакции, при этом эта "дележка" не откатываема, то - тоже не фонтан
53 fisher
 
16.04.20
12:05
(47) А вот это вполне реальный вариант, при котором будет очень больно.
54 fisher
 
16.04.20
12:08
(52) Ну а как еще организовать распределенную транзакцию между разными системами без брокера (как чаще всего и делается в 1С)? В какой-то момент приходится полагаться на то, что раз до последнего момента исключения нет, то транзакция завершена успешно.
55 trad
 
16.04.20
12:09
(53) нельзя делится "грязными" данными из транзакции. Это даже без обсуждаемого бантика
56 Cyberhawk
 
16.04.20
12:09
(49) "Если бы нужные проверки можно было бы сделать без проведения, то и весь этот сыр-бор не нужен был" // Погоди, так предлагаемый сыр-бор в (28) вроде как раз и предполагает, что проверки только до обработки проведения сделаны.
Т.е. он не учитывает кейс, когда надо при отлупе в обработке проведения протащить это в форму.
57 fisher
 
16.04.20
12:10
(56) Сама идея это учитывает как раз. trad это как опцию протащил.
58 Cyberhawk
 
16.04.20
12:11
(55) Пример не единственный. Просто факт остается фактом: мы скрываем от последующего кода флаг Отказа, и про это надо потом всегда помнить
59 trad
 
16.04.20
12:12
(54) слишком глубоко. Думать нужно в конкретной обстановке
60 Cyberhawk
 
16.04.20
12:12
(57) Ну т.е. если без обработки проведения никак, то нужно не в ПриЗаписи, а в ОбработкеПроведения городить эти доп. свойства и пропуск взвода Отказа, так?
61 trad
 
16.04.20
12:13
(60) " не в ПриЗаписи, а в ОбработкеПроведения "
Это зависит от характера проверок у ТС. Этого нам не известно
62 fisher
 
16.04.20
12:14
(60) Да. Придется заменять все Отказ = Истина на какой-нить ОтказатьсяОтЗаписи().
63 Cyberhawk
 
16.04.20
12:15
+(56) И ведь еще веселее будет, когда ты Отказ скрыл в ПриЗаписи, а в ОбработкахПроведения его типовой код все-таки взвел.
Все, в форму ничего не придет в таком случае же, т.е. схема разрушилась?
64 fisher
 
16.04.20
12:15
Но ТС и так уже что-то подобное делает, так как во всех точках отказа собирает инфу для последующего отображения.
65 Cyberhawk
 
16.04.20
12:15
(62) Вот и я про то же в (63) :)
66 trad
 
16.04.20
12:18
(63) ну да, ОбработкахПроведения нужно подгонять под правила принятые в данном контексте.
Я выше писал, что функциональности в одном контексте должны же играть по общим правилам
67 fisher
 
16.04.20
12:18
(63) Да. Любой "нелегальный" отказ приведет к необработке события. Но это можно захачить в последней подписке :) Типа если Отказ, а проведение интерактивное, то "отказываемся от отказа" и пишем инфу про необработанную ошибку, чтобы вовремя исправить.
68 Cyberhawk
 
16.04.20
12:19
(67) "Но это можно захачить в последней подписке :)" // А потом добавят еще одну подписку... или поменяют последовательность их выполнения
69 Cyberhawk
 
16.04.20
12:20
(66) Ну вот и возвращаемся к (32) :)
70 trad
 
16.04.20
12:21
(68) подписку обозвать - СамаяСамаяНаВсеВременаПоследняяПодписка
71 fisher
 
16.04.20
12:21
(69) Угу. А потом к (34)
72 trad
 
16.04.20
12:23
(69) пожалуй я соскочу
73 trad
 
16.04.20
12:25
на последок вякну. Подписки эти сами являются источниками (32)
74 fisher
 
16.04.20
12:28
(73) Так можно договориться до того, что весь код должен быть в линейной портянке а все остальное - от лукавого.
75 Ненавижу 1С
 
гуру
16.04.20
13:15
я сейчас одну крамольную вещь покажу, только ногами не бейте:

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    
    //ФлагЗаписи - реквизит формы, тип булево
    
    Если Не ФлагЗаписи Тогда
        ФлагЗаписи = Истина;
        Отказ = Истина;
        ВсеХорошо = Истина;
        Попытка
            Записать(ПараметрыЗаписи);                
        Исключение
            Заголовок = "Что-то пошло не так!";    // вот здесь обрабатываем!                    
            ВызватьИсключение;
        КонецПопытки;                    
    Иначе
        ФлагЗаписи = Ложь;
    КонецЕсли;     
    
КонецПроцедуры
76 fisher
 
16.04.20
14:17
(75) Идея понятна. Если не возникнет проблем с пробрасыванием ошибок через временное хранилище - то отличный выход.
Ошибка? Это не ошибка, это системная функция.