В процессе разработки на платформе 1С:Предприятие мы часто сталкиваемся с необходимостью оптимизации или рефакторинга чужого кода. Одной из типичных «ошибок новичка» или примеров неудачного проектирования является попытка принудительно записать объект документа непосредственно в процессе его проведения.
Давайте разберем, почему использование ЭтотОбъект.Записать() внутри ОбработкаПроведения является крайне нежелательным действием и к каким последствиям это может привести.
Процедура ОбработкаПроведения сама по себе является частью процесса записи документа в базу данных. Когда вы нажимаете кнопку «Провести», платформа инициирует транзакцию. Внутри этой транзакции происходит выполнение кода проведения. Попытка вызвать Записать() повторно в этот момент порождает ряд критических проблем:
Записать() внутри уже запущенной транзакции создает лишнюю нагрузку на сервер СУБД. При массовом проведении документов это приводит к кратному замедлению работы системы.Записать() снова запустит обработчики событий ПередЗаписью и ПриЗаписи. Это может привести к непредсказуемым результатам: повторной отправке уведомлений, лишнему обновлению статусов или ошибочному выполнению фоновых задач.Если в процессе проведения вы получаете данные, которые необходимо сохранить, рассмотрите следующие варианты архитектурных решений:
Вместо того чтобы хранить рассчитанные данные в реквизитах самого документа, вынесите их в РегистрСведений. Это позволит хранить информацию отдельно, легко получать ее с помощью запросов и не перегружать основной объект документа.
Если данные, которые вы хотите записать в реквизиты, можно рассчитать до начала проведения (например, на основе данных табличных частей), перенесите код вычисления в процедуру ПередЗаписью в модуле объекта. В этом случае документ запишется один раз, сразу с актуальными данными.
// Пример корректного подхода: расчет данных перед записью
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Рассчитываем сумму или себестоимость до того, как документ попадет в базу
ЭтотОбъект.СуммаДокумента = РассчитатьИтоговуюСумму();
КонецПроцедуры
Часто разработчики пытаются сохранить себестоимость или сумму списания в шапку документа просто для того, чтобы «видеть цифру в журнале». Проанализируйте, действительно ли это нужно для логики работы программы или это просто привычка. Для отображения итоговых сумм в журналах документов лучше использовать механизмы вывода данных в списках или отчеты по регистрам накопления, где и должны храниться все движения документа.
Помните, что чистота кода и соответствие архитектурным принципам платформы 1С — это залог стабильной работы системы под высокой нагрузкой. Избегайте «костылей» в виде принудительной записи объекта там, где это противоречит жизненному циклу транзакции!