Почему не записывается программно созданная операция в модуле проведения 1С 7.7 и как это исправить

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

В разработках на платформе 1С:Предприятие 7.7 периодически возникает задача: при проведении одного документа необходимо автоматически сформировать, заполнить и записать отдельную бухгалтерскую операцию или другой документ. Однако при попытке реализовать такую логику непосредственно внутри процедуры ОбработкаПроведения() разработчики сталкиваются с тем, что созданный объект либо не сохраняется в базе вовсе, либо выдает ошибку вида <Объект не найден> при просмотре в мониторе пользователей.

Рассмотрим подробно причины такого поведения платформы 1С 7.7 и разберем проверенные архитектурные решения этой проблемы.

Анализ исходного кода и проявление проблемы

Посмотрим на классический пример кода, который часто пытается использовать разработчик внутри модуля проведения документа:


Процедура ОбработкаПроведения()  
    // Формирование и заполнение ТЗ остатков...
    Если Тз.КоличествоСтрок() > 0 Тогда  
        Тз.ВыбратьСтроки(); 
        Оп2 = СоздатьОбъект("Операция");
        Оп2.Новая();
        Пока Тз.ПолучитьСтроку() = 1 Цикл 
            Оп2.НоваяПроводка(); 
            Оп2.Дебет.Счет = Тз.ДебетСчет;
            Оп2.Дебет.Суб1 = Тз.Суб1;
            Оп2.Кредит.Счет = Тз.КредитСчет;
            Оп2.Дебет.Суб2 = Тз.Суб2;
            Оп2.Сумма = Тз.Сум; 
        КонецЦикла;
        
        Оп2.Содержание = "Дополнительная операция";
        Оп2.ДатаОперации = ДатаДок; 
        Оп2.ЗаписатьПроводки();
        Оп2.Записать();  
        
        // Интерактивное открытие формы созданной операции
        ОткрытьФормуМодально(Оп2.Документ);
    КонецЕсли;
КонецПроцедуры

При таком подходе визуально форма операции может даже открыться, содержать правильные проводки, реквизиты и номер. Однако после завершения проведения документа созданная операция бесследно исчезает из базы данных.

Причины ошибки и особенности работы 1С 7.7

Проанализируем физику работы платформы 1С 7.7, чтобы понять, почему этот код не работает так, как ожидается:

  1. Автоматическая транзакция процедуры проведения: Процедура ОбработкаПроведения() в 1С 7.7 всегда исполняется платформой внутри служебной неявной транзакции. Все действия с объектами внутри этого блока объединяются. Платформа 7.7 не поддерживает автономные или независящие от родителя вложенные транзакции.
  2. Особенности объекта «Операция»: В версии 7.7 «Операция» — это специальный служебный объект, который неотрывно связан с документом-владельцем. Попытка создать проводки через СоздатьОбъект("Операция") без корректного документа-контейнера вне текущей транзакции не позволяет платформе правильно зафиксировать объект в системных таблицах (в частности, в 1SJOURN).
  3. Интерактивные вызовы внутри транзакции: Вызов блокирующих диалогов, таких как ОткрытьФормуМодально(), прямо в момент активной транзакции проведения блокирует системные таблицы и нарушает логику контекста записи, что приводит к откату изменений и появлению записи <Объект не найден>.

Варианты правильного решения задачи

Разберем способы решения данной задачи в зависимости от требований бизнес-логики.

Способ 1. Запись проводок в контексте самого проводимого документа

Если цель состоит лишь в том, чтобы сформировать дополнительные движения по счетам, не создавая отдельный документ в журнале, правильнее задействовать механизм движения самого проводимого документа:


Процедура ОбработкаПроведения()
    // Работаем напрямую с операцией текущего документа
    Операция.НоваяПроводка();
    Операция.Дебет.Счет = СчетПоДебету;
    Операция.Кредит.Счет = СчетПоКредиту;
    Операция.Сумма = СуммаОперации;
    // При завершении проведения платформа сама запишет проводки
КонецПроцедуры

Способ 2. Вынос логики в форму документа (разделение процессов)

Если бизнес-процесс требует именно создания отдельного независимого документа «Операция» (например, для корректировки остатков до проведения основного документа), создание этой операции необходимо полностью вынести за пределы проведения.

Рассмотрим алгоритм реализации через форму документа:

  1. Добавить на форму документа кнопку (например, «Проверить и скорректировать остатки») или выполнять проверку в предопределенной процедуре модуля формы ПриЗаписи().
  2. Перед проведением проверять остатки на счетах и формировать Таблицу Значений нехватающих позиций.
  3. Из модуля формы программно создавать, заполнять и записывать операцию по заполнению остатков. Так как в этот момент транзакция проведения документа ещё не открыта, создание и запись операции пройдут штатно:

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

Способ 3. Запуск через ОбработкаОжидания()

Если создание операции должно происходить автоматически при отмене проведения, в форме документа можно перехватить факт отказа проведения и передать процедуру создания операции в фоновую обработку через ОбработкаОжидания("ИмяПроцедуры", 1). Данный метод выполнит код через 1 секунду — уже после того, как платформа полностью завершит транзакцию проведения и снимет все блокировки.

Выводы

Главное правило при работе с 1С 7.7: нельзя создавать, модифицировать и записывать сторонние транзакционные объекты (другие документы и операции) внутри процедуры ОбработкаПроведения(). Для корректной работы всегда разделяйте процесс создания подчинённых/вспомогательных объектов и процесс проведения основного документа на уровне контекста формы.

← На главную