Где происходит запись движений в регистр накопления "Расчеты с контрагентами" при проведении ПКО и как ее отладить?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

В этой статье мы подробно разберем внутренние механизмы платформы «1С:Предприятие 8», управляющие записью движений, выясним, почему так происходит, и научимся безошибочно находить точный момент физической записи в базу данных.

1. Главная причина: Автоматическая (неявная) запись движений платформой

Основная особенность проведения документов в 1С заключается в том, что физическая запись движений в СУБД по умолчанию происходит неявно самой платформой после успешного завершения процедуры ОбработкаПроведения в модуле объекта документа.

Рассмотрим пошагово, как выглядит этот процесс «под капотом» системы:

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

Из-за того, что запись выполняется платформой автоматически на шаге 4–6, разработчику кажется, что запись происходит «внезапно» между завершением подписок и открытием формы.

2. Как свойство «Запись движений при проведении» влияет на логику работы

То, как именно платформа решает, какие регистры нужно записать в конце транзакции проведения, регулируется свойством метаданных документа «Запись движений при проведении». Проанализируем два основных режима работы этого свойства:

3. Пошаговая инструкция: Как поймать момент записи в отладчике

Чтобы увидеть физический момент записи набора в СУБД и точно определить инициатора (платформа это делает автоматически или в коде все же есть принудительный вызов), выполним следующие действия:

Шаг 1. Переход в модуль набора записей регистра

Откроем конфигуратор, найдем регистр накопления РасчетыСКонтрагентами (или любой другой интересующий нас регистр). Щелкнем по нему правой кнопкой мыши, выберем пункт «Открыть модуль набора записей».

Шаг 2. Создание обработчиков событий

Если в модуле набора записей отсутствуют стандартные обработчики событий, нам необходимо их создать. Напишем следующий код:


Процедура ПередЗаписью(Отказ, Замещение)
    // Сюда устанавливаем точку останова
    ПредупреждениеОтладка = Истина; 
КонецПроцедуры

Процедура ПриЗаписи(Отказ, Замещение)
    // Сюда также можно установить точку останова
    ПредупреждениеОтладка = Истина;
КонецПроцедуры

Шаг 3. Настройка серверной отладки

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

  1. На сервере приложений «1С:Предприятие» должен быть запущен сеанс службы с ключом -debug.
  2. В конфигураторе перейдем в меню Отладка -> Подключение и проверим, что в списке подключенных информационных баз присутствует рабочий процесс сервера.

Шаг 4. Анализ стека вызовов (Call Stack)

Запустим сеанс «1С:Предприятие» в режиме отладки, откроем нужный документ Приходный кассовый ордер (ПКО) и выполним его проведение. Когда отладчик остановится на точке останова в процедуре ПередЗаписью модуля набора записей регистра:

  1. Откроем окно Стек вызовов (в меню конфигуратора: Отладка -> Окна -> Стек вызовов или сочетанием клавиш Ctrl + Alt + C).
  2. Проанализируем содержимое окна:
    • Если в стеке вызовов непосредственно над процедурой ПередЗаписью нет строк кода конфигурации (сразу отображается системный вызов платформы), значит, запись выполняется неявно самой платформой после выхода из процедуры ОбработкаПроведения модуля документа.
    • Если в стеке вызовов над процедурой присутствует строка из общего модуля или модуля документа, содержащая вызов метода Движения.РасчетыСКонтрагентами.Записать(), значит, в конфигурации отрабатывает явная запись из кода.

4. Различия в логике проведения между поколениями конфигураций 1С

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

Понимая эти тонкости работы платформы «1С:Предприятие 8» и умея пользоваться модулем набора записей совместно со стеком вызовов, вы всегда сможете быстро локализовать, в какой именно момент и под воздействием какого алгоритма данные попадают в регистры накопления.

← На главную