В какой момент платформа 1С на самом деле записывает движения документа в регистры?

Программист 1С v8.3 (Обычные формы) Управленческий учет
← На главную

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

Проанализируем типичную ситуацию: при проведении документа "Приходный кассовый ордер" в конфигурации УПП отладчик показывает, что после формирования движений и выполнения подписки на событие ПередЗаписьюРегистраНакопления, записи в регистре уже существуют, хотя явной команды на запись не было. Вопрос: где и когда происходит реальная запись в базу данных?

Жизненный цикл записи движений: разбираем по шагам

Ключ к пониманию кроется в том, что формирование движений и их фактическая запись в базу данных — это два разных этапа, управляемых самой платформой 1С в рамках единой транзакции проведения документа. Рассмотрим этот процесс по шагам.

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

Именно поэтому возникает ощущение, что запись происходит "между строк". Она действительно происходит между завершением кода в обработчике ПередЗаписью и началом выполнения следующего логического блока, например, обработчика ПослеЗаписи.

Как это проверить на практике?

Чтобы окончательно убедиться в этой последовательности и отследить момент записи, можно использовать простой и надежный метод — точки останова в модуле набора записей регистра.

Разберем по шагам, как это сделать:

  1. Откройте конфигуратор.
  2. Найдите нужный регистр накопления, например, РасчетыСКонтрагентами.
  3. Откройте его модуль набора записей. Если в нем нет процедур-обработчиков событий, создайте их.
  4. Добавьте следующий код и поставьте в нем точки останова:

Процедура ПередЗаписью(Отказ, Замещение)
    // Поставьте точку останова на следующей строке.
    // На этом этапе можно проверить содержимое набора записей (коллекция "ЭтотОбъект"),
    // но в базе данных этих записей еще нет.
    Сообщить("Сработало событие ПередЗаписью для регистра РасчетыСКонтрагентами.");
КонецПроцедуры

Процедура ПриЗаписи(Отказ)
    // Поставьте точку останова на следующей строке.
    // Когда выполнение дойдет сюда, данные уже будут физически записаны в базу данных.
    // Здесь можно выполнять действия, которые требуют наличия записи в БД.
    Сообщить("Сработало событие ПриЗаписи для регистра РасчетыСКонтрагентами.");
КонецПроцедуры

Теперь запустите отладку и проведите ваш документ. Вы увидите, как отладчик последовательно остановится сначала в процедуре ПередЗаписью, а затем, после невидимой операции записи, в процедуре ПриЗаписи. Изучение стека вызовов в этих точках поможет лучше понять контекст выполнения.

Важный совет: В таких конфигурациях, как УПП, которые часто подвергаются многочисленным доработкам, стандартное поведение платформы может быть изменено. Поэтому прямой анализ через отладку в модуле набора записей — самый надежный способ понять, что на самом деле происходит в вашей системе.

Итак, никакой магии нет. Есть четкая, хоть и не всегда очевидная, последовательность действий, выполняемых платформой 1С. Понимание этого механизма неявной записи поможет вам избежать ошибок и писать более предсказуемый и надежный код.

← На главную