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