Почему при проведении документа в 1С движения дублируются и как это исправить?

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

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

Понимание механизма работы движений

Для начала вспомним, как работает платформа 1С:Предприятие. Когда вы устанавливаете свойство Записывать = Истина у объекта Движения, платформа при выполнении метода Записать() анализирует состояние набора записей в памяти:

  1. Если набор записей не был прочитан (пуст), платформа считает, что это новая запись.
  2. Если набор записей был прочитан (содержит данные из базы), платформа перед записью новых данных автоматически очищает старые записи, относящиеся к данному регистратору.

Дублирование возникает тогда, когда набор записей считается «прочитанным», но логика программы не очищает его корректно, или когда в процессе выполнения ОбработкиПроведения происходит обращение к коллекции движений, которое провоцирует их чтение из базы данных.

Способ 1: Принудительная очистка коллекции движений

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

Разберем пример реализации в модуле объекта:


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // Гарантированно очищаем старые движения
    Движения.ОстаткиТМЦ.Очистить();
    
    // Устанавливаем признак записи
    Движения.ОстаткиТМЦ.Записывать = Истина;
    
    // ... ваш код формирования движений ...
    Движение = Движения.ОстаткиТМЦ.Добавить();
    // ... заполнение реквизитов ...
КонецПроцедуры

Этот метод является «золотым стандартом» разработки, так как он делает код предсказуемым и независимым от внешних факторов, таких как настройки формы или механизмы БСП.

Способ 2: Проверка навигационных ссылок и свойств формы

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

Почему может не помогать автоматическое удаление?

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

Советы по отладке

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

  1. Поставьте точку останова в самом начале процедуры ОбработкаПроведения.
  2. В окне «Табло» или «Выражение» проверьте значение Движения.ИмяРегистра.Количество().
  3. Если до начала формирования движений количество больше 0, значит, они были прочитаны ранее.
  4. После вызова Движения.ИмяРегистра.Очистить() значение должно стать равным 0.

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

← На главную