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