При обслуживании и свертке баз данных на платформе 1С:Предприятие разработчики нередко сталкиваются с ситуацией: после программного удаления документов за прошлые периоды запрос к виртуальной таблице остатков регистра накопления начинает возвращать неверные данные или строки с представлением <Объект не найден> в измерениях (например, в партиях). При этом в реальной таблице движений таких записей уже нет. Разберем внутреннее устройство регистров накопления, выясним причину такого поведения платформы и рассмотрим правильные сценарии удаления документов и пересчета итогов.
Для понимания сути проблемы проанализируем, как регистр накопления остатков устроен на уровне СУБД. В базе данных для одного регистра формируются две ключевые физические таблицы:
Когда мы обращаемся к виртуальной таблице РегистрНакопления.ПартииТоваровНаСкладах.Остатки(&Момент), платформа 1С не сканирует всю историю движений с момента создания базы. Запрос берет ближайшие агрегаты из физической таблицы итогов и прибавляет или вычитает дельту записей из таблицы движений за интервал между точкой итогов и указанным моментом времени. Если в таблице итогов содержались исторические агрегаты по партии, которая затем была физически удалена из базы без предварительной отмены проведения, таблица итогов остается рассинхронизированной с движениями, что приводит к появлению ссылок на несуществующие объекты.
Рассмотрим типовую ошибку, когда документы удаляются методом УдалитьОбъекты() без предварительной отмены проведения:
УстановитьМонопольныйРежим(Истина);
УдалитьОбъекты(МассивНаУдаление, Истина);
УстановитьМонопольныйРежим(Ложь);
Параметр проверки ссылочной целостности (второй параметр со значением Истина) выполняет поиск ссылок в объектах метаданных и физических таблицах базы данных. Однако служебная таблица итогов регистра накопления является расчетным агрегатом, и платформа может не заблокировать удаление документа-партии, если все движения регистратора были удалены вместе с ним. В результате в таблице итогов сохраняются старые срезы с «битыми» ссылками в измерении партий.
Кроме того, если ранее в базе выполнялись регламентные операции с отключением итогов через УстановитьИспользованиеИтогов(Ложь) без последующего пересчета, расхождения между реальными движениями и таблицей итогов накапливаются незаметно.
Чтобы избежать искажения агрегатов и появления битых ссылок, разберем корректную последовательность действий при программном удалении документов:
УдалитьОбъекты().Посмотрим на пример кода корректной отмены проведения перед удалением:
Для Каждого СсылкаНаДокумент Из МассивДокументов Цикл
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
Если ДокументОбъект <> Неопределено Тогда
Если ДокументОбъект.Проведен Тогда
ДокументОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
КонецЕсли;
КонецЕсли;
КонецЦикла;
УстановитьМонопольныйРежим(Истина);
УдалитьОбъекты(МассивДокументов, Истина);
УстановитьМонопольныйРежим(Ложь);
Если рассинхронизация уже произошла, восстановить соответствие виртуальной таблицы остатков первичным движениям можно несколькими способами.
Рассмотрим случай, когда расхождение обнаружено только в одном регистре (например, ПартииТоваровНаСкладах). Чтобы не блокировать работу всей информационной базы полным пересчетом, используем менеджер регистра:
РегистрыНакопления.ПартииТоваровНаСкладах.ПересчитатьИтоги();
Данный метод полностью перестраивает физическую таблицу итогов на основе данных таблицы движений для выбранного регистра.
Если требуется пересчитать агрегаты за конкретный временной интервал (например, за прошлый закрываемый год), воспользуемся объектом УправлениеИтогами:
НачалоИнтервала = НачалоГода(Дата("20120101"));
КонецИнтервала = КонецГода(Дата("20121231"));
УправлениеИтогами.ПересчитатьИтогиЗаПериод(НачалоИнтервала, КонецИнтервала);
В случаях масштабных сбоев или после глобальной свертки данных рекомендуется запустить регламентную процедуру «Тестирование и исправление» в Конфигураторе или через командную строку. При этом необходимо отметить следующие опции:
Таким образом, несоответствие остатков движениям является не системной ошибкой платформы, а результатом удаления объектов без предварительной отмены проведения. Соблюдение правил очистки данных и регулярное обслуживание итогов гарантируют полную целостность партионного и складского учета.