Обновление связанного документа: перед записью vs при записи

1. triviumfan 94 24.07.24 11:43 Сейчас в теме
Доброго дня, коллеги.

Измученный вопрос при каком событии следует обновлять связанный документ с текущим.
Мне не понятно, почему в типовых решених УчетНДС.АктуализироватьСчетаФактурыВыданныеПередЗаписью() происходит пометка удаления и отмена проведения СФ именно в событии ПередЗаписью() документа-продажи, ведь транзакция только началась и есть большая вероятность, что она откатится. Есть объяснения для чего это делается?
Стандарт std465 гласит, что в нём выполняются действия по записи связанной с объектом данных в других объектах конфигурации, а также выполняются другие действия, связанные с изменением объекта. Тогда почему не в нём?
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. usershmuser 24.07.24 12:26 Сейчас в теме
(1) Логично предположить, что все изменения должны происходить перед записью т.к. при записи происходят другие процедуры и в типовых решениях эти процедуры скорее всего затрагивают данные из изменяемого документа (какие либо проверки).
В том же стандарте написано:
на момент выполнения обработчика, объект уже записан в БД

Соответственно, процедуры, которые нужно делать до записи в БД делаются перед записью, а не в процессе.
5. triviumfan 94 24.07.24 13:54 Сейчас в теме
(2) Перед записью делаются проверки, которые не перенесли или не могут быть перенесены в обработку проверки заполнения, а также заполнение служебных реквизитов объекта. Исключением может быть создание каких-либо ссылок, которые нужны для заполнения текущего объекта. При записи уже имеется ссылка и обычно все связанные объекты создают здесь. Мне не понятен конкретный пример, который десятилетиями используется в типовых конфигурациях.
3. usershmuser 24.07.24 12:43 Сейчас в теме
(1)
при каком событии следует обновлять связанный документ с текущим

Вот тут зависит от:
1. Что необходимо обновлять в связанном документе.
2. Как это повлияет на текущий.

Если какая то справочная информация изменилась и не влияет на текущий документ, то можно делать хоть после записи.
Если логика предполагает возврат ссылок из связанного документа (например какой либо документ перерасчета), то необходимо делать перед записью.
4. triviumfan 94 24.07.24 13:49 Сейчас в теме
(3)
Вот тут зависит от:
1. Что необходимо обновлять в связанном документе.
2. Как это повлияет на текущий.

Я ведь привёл конкретный пример - отмена проведения и пометка на удаление всех счетов-фактур документа-продажи.
6. usershmuser 24.07.24 13:56 Сейчас в теме
(4) Ты определись

Измученный вопрос при каком событии следует обновлять связанный документ с текущим.


или


почему в типовых решених УчетНДС.АктуализироватьСчетаФактурыВыданныеПередЗаписью() происходит пометка удаления и отмена проведения СФ именно в событии ПередЗаписью() документа-продажи


или


почему происходит пометка удаления и отмена проведения СФ


На первый и второй вопрос я ответил в контексте своих знаний, полученных на просторах обучающих материалов и рекомендаций по разработке, применение зависит только от решаемых задач.
На третий - стоит спросить разработчиков/бухгалтеров.
7. Vadim_174 2 24.07.24 23:03 Сейчас в теме +0.5 $m
(1) В событии ПриЗаписи обычно создаются для нового документа связанные объекты. А в событии ПередЗаписью обновляются связанные объекты.
Это потому что в событии ПередЗаписью доступна проверка текущей изменяемой версии объекта и версии БД, соответственно можно сравнить что изменилось и в зависимости от этого уже делать какие то действия. Причина в этом.
Тоесть на Вашем примере, если пометка удаления не изменилась то и никаких действий не будет сделано. Так же кроме счет фактур могут быть какие нибудь документы корректировки например, в которых нужно обновить допустим Дату и Номер корректируемого документ (текущего, если это реализация к примеру) - просто сравниваем ЭтотОбъект.Номер = Ссылка.Номер и если не равно обновляем реквизиты в корректировке. А если НЕ ЗначениеЗаполнено(ЭтотОбъект.Ссылка) (это новый объект) то ничего не обновляем потому что нечего еще обновлять, связанные документы еще не создались и это пройзойдет уже в событии ПриЗаписи.
Так же ПередЗаписью обычно проверяют на пометку в какой нибудь обмен, тоесть если чтото в объекте изменилось то включаем в обмен, если нет соответственно ничего не делаем. Таким образом уменьшается общая нагрузка на систему.

По поводу начала транзакции, это не особенно имеет значение, в любом случае все изменения сделанные в рамках транзакции откатятся в случае ошибки в этой транзакции.
triviumfan; +1 Ответить
8. triviumfan 94 26.07.24 11:26 Сейчас в теме
(7)
Тоесть на Вашем примере, если пометка удаления не изменилась то и никаких действий не будет сделано.

Всё равно не сходится, можно сделать это по-православному - при записи. Если пометка на удаление уже была и процедура снова попытается обработать связанные СФ, то они ведь уже будут помечены на удаление ранее и она ничего не будет делать.
Ну, или на крайняк - в таких случаях проверку на изменения делают в ПередЗаписью(), далее передают флаг через ДоволнительныеСвойства объекта, а в ПриЗаписи() уже создают связанные объекты или как в данном случае обрабатывают удаление/отмену проведения счетов-фактур.
10. Vadim_174 2 26.07.24 12:48 Сейчас в теме
(8)
Всё равно не сходится, можно сделать это по-православному - при записи. Если пометка на удаление уже была и процедура снова попытается обработать связанные СФ, то они ведь уже будут помечены на удаление ранее и она ничего не будет делать.
Ну, или на крайняк - в таких случаях проверку на изменения делают в ПередЗаписью(), далее передают флаг через ДоволнительныеСвойства объекта, а в ПриЗаписи() уже создают связанные объекты или как в данном случае обрабатывают удаление/отмену проведения счетов-фактур.


В том то и дело, что если пометка удаления не изменилась то и ничего проверять не нужно. И обращаться к другим объектам базы тоже не нужно. Вы как бы уменьшаете количество запросов таким образом. А в случае с обменами там вообще очень много действий лишних .

А именно создание (новых) связанных объектов, да, по православному, ПриЗаписи, все верно.
11. Vadim_174 2 26.07.24 12:57 Сейчас в теме
(10) и еще забыл добавить по поводу проброса через ДополнительныеСвойства между событиями, это так же делается для уменьшения нагрузки, так, если ПриЗаписи чтото пойдет не так то будет Отказ = Истина и по этому условию мы не будем делать лишних действий. Наверное проверить ПередЗаписью и пробросить в ПриЗаписи будет эффективнее, если учитывать что ПриЗаписи может произойти какая то проблема и транзакция откатится, но в целом разница не большая, как часто бывают проблемы при записи ? Зависит от этого, видимо в стандартных решениях посчитали что эффект незначительный.
12. Vadim_174 2 26.07.24 13:00 Сейчас в теме
(8) да и вот решил посмотреть что пишут на ИТС, так там вроде как тоже самое только другими словами https://its.1c.ru/db/v8std#content:464:hdoc
13. usershmuser 26.07.24 13:04 Сейчас в теме
(11)
в стандартных решениях

Там только разработчикам известно, почему именно так, а не иначе, они художники и так видят.
У любого разработчика есть свое видение того, как оно должно быть, а вот совпадет оно с видением другого разработчика или нет - неизвестно.
Вообще тема достаточно философская. Считаю что использование ПередЗаписью и ПриЗаписи необходимо использовать в зависимости от поставленных задач. Все действия в 1с происходят поочередно, а вот куда воткнуть свой код - нужно думать головой, либо потратить время на тестирование и выяснить отличия (действий и скорости)
14. triviumfan 94 26.07.24 14:33 Сейчас в теме
(10)
В том то и дело, что если пометка удаления не изменилась то и ничего проверять не нужно. И обращаться к другим объектам базы тоже не нужно. Вы как бы уменьшаете количество запросов таким образом. А в случае с обменами там вообще очень много действий лишних .

А я вот считаю, что если пометка удаления не изменилась, то ПриЗаписи() сделать запрос к таблице СФ, который ничего не вернёт (т.к.они уже были помечены ранее) не сделает никакой нагрузки - это смешно.
А вот при кейсе, когда перед записью что случится и будет отмена транзации, в которой была запись в БД всех связанных счетов-фактур - вот тут как раз и вопрос к оптимизации и мой вопрос. При записи такое менее вероятно, т.к. объект уже записан в БД.

Вот листинг кода:
Процедура АктуализироватьСчетаФактурыВыданныеПередЗаписью(ПараметрыРегистрации, Знач РежимЗаписи, Знач ПометкаУдаления, Знач Проведен) Экспорт
	
	СчетФактураВыданныйНеТребуется = СчетФактураВыданныйНеТребуется(ПараметрыРегистрации);
	ДокументПроведен = Ложь;
	Если РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
		ДокументПроведен = Истина;
	ИначеЕсли РежимЗаписи = РежимЗаписиДокумента.Запись И Проведен Тогда
		ДокументПроведен = Истина;
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст = ""; // Запрос к СФ
	
	УстановитьПривилегированныйРежим(Истина);
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		
		ПометитьНаУдаление = Ложь;
		ОтменитьПроведение = Ложь;
		
		Если НЕ Выборка.ПометкаУдаления
			 И (ПометкаУдаления
			    Или Выборка.Организация <> ПараметрыРегистрации.Организация
			    Или СчетФактураВыданныйНеТребуется) Тогда
			ПометитьНаУдаление = Истина;
		ИначеЕсли Выборка.Проведен И НЕ ДокументПроведен Тогда
			ОтменитьПроведение = Истина;
		КонецЕсли;
		
		Если ПометитьНаУдаление Тогда
			ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
                        ДокументОбъект.УстановитьПометкуУдаления(Истина);
		КонецЕсли;
		
		Если ОтменитьПроведение Тогда
			ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
			ДокументОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
		КонецЕсли;
		
	КонецЦикла;
	
	УстановитьПривилегированныйРежим(Ложь);
	
КонецПроцедуры
Показать

Этот запрос выполнится в любом случае, так что замечание некорректно.
15. Vadim_174 2 26.07.24 15:56 Сейчас в теме
(14) это которая конфигурация?
16. triviumfan 94 26.07.24 18:13 Сейчас в теме
(15) ERP. Но вангую, что похожая семантика и в УТ/КА, а также БП.
17. spacecraft 26.07.24 18:29 Сейчас в теме
(14)
А вот при кейсе, когда перед записью что случится и будет отмена транзации, в которой была запись в БД всех связанных счетов-фактур - вот тут как раз и вопрос к оптимизации

Это все в одной транзакции. Нормально все.
(14)
При записи такое менее вероятно, т.к. объект уже записан в БД

Это абсолютно не важно в данном случае с точки зрения оптимизации.
18. triviumfan 94 29.07.24 10:21 Сейчас в теме +0.5 $m
(17)
Это абсолютно не важно в данном случае с точки зрения оптимизации.

Эм... и почему же?
В транзации будет куча операций записи в БД, которые с высокой вероятностью нужно откатить. При записи все проверки уже выполнены, поля заполнены и консистентны, отказ от записи может быть только при контроле остатков при проведении. Не понимаю, почему это не важно. Стандарт 465 говорит об обратном.
19. spacecraft 29.07.24 19:05 Сейчас в теме
(18)
В транзации будет куча операций записи в БД, которые с высокой вероятностью нужно откатить. При записи все проверки уже выполнены

А в той "куче" документов не может быть отмены транзакций?
Т.е. сделали "все проверки". Перешли в ПриЗаписи. Запустили записи "кучи" других связанных документов и там огребли отказ.
Это еще если после записи той самой "кучи" не требуется вносить изменения в сам текущий документ.
Да и данные во время транзакции еще не помещены в рабочие данные, а находятся в транзакционном кэше.
9. homer_ 79 26.07.24 11:47 Сейчас в теме
Теория - потому что вы могли в текущем документе убрать/поправить/удалить ссылку на документ который отменяете и если вы захотите обратится к документу после проведения - то есть риск, что вы не сможете найти ссылку в текущем документе. +
По вопросу из темы - НДС это СФ. А СФ может иметь отличную дату от документа и соответственно при отмене документа проверяется доступность на редактирования СФ.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот