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

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

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

Почему исчезают записи при перепроведении

Проанализируем стандартную последовательность действий платформы 1С при проведении документа. Поведение системы определяется свойством объекта метаданных Удаление движений (вкладка «Движения» в свойствах документа):

  1. Режим «Удалять автоматически» (установлен по умолчанию): перед вызовом процедуры ОбработкаПроведения платформа принудительно удаляет все существующие движения документа по всем регистрам, входящим в состав его движений. Вид регистра (накопления, сведений, бухгалтерии или расчета) роли не играет. Если в коде обработчика накладывается условие, из-за которого набор записей по регистру не заполняется, в базе данных фиксируется пустое состояние — старые записи удалены платформой, а новые не сформированы.
  2. Режим «Удалять автоматически при отмене проведения»: платформа не очищает движения перед началом проведения. Очистка выполняется только при непосредственной отмене проведения документа. При проведении система перезаписывает только те наборы записей, у которых свойство Записывать установлено в значение Истина.
  3. Режим «Не удалять автоматически»: автоматическая очистка не выполняется вовсе. Разработчик обязан самостоятельно программно управлять удалением и записью каждого набора.

Таким образом, если оставить режим «Удалять автоматически» и просто запретить формирование строк в ОбработкаПроведения, платформа предварительно сотрет старые данные, оставив регистр пустым.

Способ 1. Использование режима «Удалять автоматически при отмене проведения»

Рассмотрим наиболее простое и эффективное платформенное решение. Переведем управление записью движений в полуавтоматический режим.

Разберем по шагам реализацию данного подхода:

  1. Откроем свойства нужного документа в дереве метаданных конфигуратора.
  2. На вкладке «Движения» найдем свойство Удаление движений и установим значение Удалять автоматически при отмене проведения.
  3. В модуле объекта документа в процедуре ОбработкаПроведения явно настроим флаги записи для каждого регистра в зависимости от условий.

Посмотрим на пример кода в модуле объекта:


Процедура ОбработкаПроведения(Отказ, РежимПроведения)

	// Если дата документа меньше контрольной даты, запрещаем перезапись регистра
	Если Дата < КонтрольнаяДата Тогда
		Движения.ОстаткиНоменклатуры.Записывать = Ложь;
	Иначе
		// Формируем движения стандартным образом
		Движения.ОстаткиНоменклатуры.Записывать = Истина;
		
		Для Каждого Стр Из Товары Цикл
			Движение = Движения.ОстаткиНоменклатуры.Добавить();
			Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
			Движение.Период = Дата;
			Движение.Номенклатура = Стр.Номенклатура;
			Движение.Количество = Стр.Количество;
		КонецЦикла;
	КонецЕсли;

	// Для остальных регистров движения могут формироваться в штатном режиме
	Движения.Продажи.Записывать = Истина;
	// ... заполнение регистра Продажи ...

КонецПроцедуры

Важный момент: при таком подходе интерактивная отмена проведения документа пользователем сотрет все движения. Если требуется защитить движения от удаления и при отмене проведения, необходимо переопределить обработчик ОбработкаУдаленияПроведения, установив свойство Удаление движений в значение Не удалять автоматически.


Процедура ОбработкаУдаленияПроведения(Отказ)

	// Очищаем только те регистры, которые разрешено менять
	Если Дата >= КонтрольнаяДата Тогда
		// Платформа очистит регистры, если свойство Записывать установлено в Истина
		Движения.ОстаткиНоменклатуры.Записывать = Истина;
		Движения.ОстаткиНоменклатуры.Очистить();
	Иначе
		// Запрещаем очистку регистра
		Движения.ОстаткиНоменклатуры.Записывать = Ложь;
	КонецЕсли;

	Движения.Продажи.Записывать = Истина;
	Движения.Продажи.Очистить();

КонецПроцедуры

Способ 2. Сохранение и восстановление набора записей через ДополнительныеСвойства

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

Разберем реализацию через события объекта:

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

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

	Если РежимЗаписи = РежимЗаписиДокумента.Проведение И Дата < КонтрольнаяДата Тогда
		// Считываем текущие движения из базы данных до их удаления
		Набор = РегистрыНакопления.ОстаткиНоменклатуры.СоздатьНаборЗаписей();
		Набор.Отбор.Регистратор.Установить(Ссылка);
		Набор.Прочитать();
		
		// Сохраняем выгруженную таблицу в дополнительные свойства документа
		ДополнительныеСвойства.Вставить("СохраненныеДвиженияОстатки", Набор.Выгрузить());
	КонецЕсли;

КонецПроцедуры

Процедура ОбработкаПроведения(Отказ, РежимПроведения)

	Если Дата < КонтрольнаяДата И ДополнительныеСвойства.Свойство("СохраненныеДвиженияОстатки") Тогда
		// Восстанавливаем старые движения
		ТаблицаДвижений = ДополнительныеСвойства.СохраненныеДвиженияОстатки;
		Движения.ОстаткиНоменклатуры.Загрузить(ТаблицаДвижений);
		Движения.ОстаткиНоменклатуры.Записывать = Истина;
	Иначе
		// Стандартный алгоритм проведения
		Движения.ОстаткиНоменклатуры.Записывать = Истина;
		// ... заполнение движений ...
	КонецЕсли;

КонецПроцедуры

Риски и ограничения частичного проведения документов

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

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

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

← На главную