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