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