Как при перепроведении документа не учитывать его старые движения по регистру накопления?

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

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

Выясним причину такого поведения и подробно разберем проверенные способы решения этой проблемы.

Причина возникновения проблемы на уровне платформы

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

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

Способ 1. Новая методика контроля остатков (запись движений перед проверкой)

Рассмотрим современный стандарт разработки в 1С. В этом подходе контроль остатков выполняется после принудительной записи новых движений документа в базу данных.

Разберем алгоритм по шагам:

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

Движения.ИмяРегистра.Записывать = Истина;
Движения.Записать();
  1. Выполняем запрос к виртуальной таблице Остатки на МоментВремени документа.
  2. Анализируем полученный результат. Если образовался отрицательный остаток, устанавливаем параметр Отказ = Истина, что приводит к отмене транзакции проведение.

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

Способ 2. Программное удаление движений через набор записей

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

Сделать это можно с помощью набора записей регистра накопления:


НаборЗаписей = РегистрыНакопления.ИмяРегистра.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Ссылка);
НаборЗаписей.Записать();

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

Способ 3. Изменение свойства документа в Конфигураторе

Посмотрим на ещё один вариант, который настраивается в свойствах объекта метаданных. У нужного документа можно изменить свойство «Удаление движений» на значение «Удалять автоматически».

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

Способ 4. Корректировка остатков в запросе (вычитание движений регистратора)

Рассмотрим ситуативный подход, когда движения документа вычитаются прямо в тексте запроса. В этом случае мы получаем текущие остатки и соединяем их с таблицей движений этого же документа, минусуя суммы и количества по конкретному регистратору.

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

Важные нюансы и ограничения платформы

При работе с остатками и перепроведении документов обратим внимание на следующие критические моменты:

  1. Управляемые блокировки: При считывании остатков в режиме управляемых блокировок следует обязательно устанавливать явную блокировку через объект БлокировкаДанных по считываемым измерениям регистра. Это исключает параллельное чтение неактуальных данных и предотвращает дедлоки.
  2. Использование момента времени: В параметрах виртуальной таблицы остатков следует всегда передавать МоментВремени (или объект Граница), а не просто дату. Это гарантирует точный выбор остатков на позицию документа.
  3. Сдвиг даты документа: Если дата документа переносится назад или вперед, момент времени документа меняется. Своевременное удаление старых движений позволяет избежать появления фантомных отрицательных остатков в промежуточных периодах.
← На главную