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

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

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

Разберем подробно, почему возникает подобное рассогласование данных, чем отличаются различные методы пересчета итогов в платформе «1С:Предприятие 8» и как гарантированно устранить ошибки в регистрах накопления.

Причины появления рассогласования остатков после свертки

Проанализируем внутреннее устройство регистров накопления остатков. Платформа 1С хранит информацию в базе данных СУБД в нескольких связанных таблицах:

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

Когда мы формируем отчет за неограниченный период («без периода»), платформа считывает данные из таблицы актуальных итогов или выполняет прямое суммирование движений. Однако, когда мы задаем конкретный интервал отчета (например, с 01.01.2016), механизм виртуальной таблицы остатков платформы берет зафиксированные остатки из таблицы месячных итогов на эту границу и накладывает движения за выбранный интервал.

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

В чем разница между ПересчитатьИтоги() и ПересчитатьИтогиЗаПериод()?

Многие разработчики выполняют штатную процедуру «Тестирование и исправление» (ТиИ) в конфигураторе с установленным флагом пересчета итогов или вызывают метод менеджера регистра ПересчитатьИтоги(). Однако стандартный пересчет не всегда решает проблему «зависших» месячных срезов глубоких прошлых периодов.

Выясним различия между методами менеджера регистра накопления:

  1. ПересчитатьИтоги() — обновляет только текущие (актуальные) итоги в рамках установленной границы рассчитанных итогов. Если в старых периодах остались рассогласованные записи, они могут остаться нетронутыми в таблице месячных итогов СУБД.
  2. ПересчитатьИтогиЗаПериод(<НачалоПериода>, <КонецПериода>) — выполняет принудительный помесячный пересчет за указанный интервал. Если метод вызван без параметров, платформа полностью пересчитывает абсолютно все месячные итоги регистра от самого первого движения до текущего момента на основании реально существующих записей в таблице движений.

Способ 1. Программный полный сброс и перестроение итогов

Рассмотрим наиболее надежный программный способ очистки и перестроения таблицы итогов конкретного регистра. Сначала мы временно отключаем использование итогов (это очищает агрегатные таблицы в СУБД), затем включаем их обратно и принудительно рассчитываем заново по всей истории движений.

Выполним следующий фрагмент кода во внешней обработке (обязательно в монопольном режиме):


ИмяРегистра = "ПартииТоваровНаСкладахБухгалтерскийУчет";
МенеджерРегистра = РегистрыНакопления[ИмяРегистра];

// Отключаем и включаем итоги для физической очистки таблиц в СУБД
МенеджерРегистра.УстановитьИспользованиеИтогов(Ложь);
МенеджерРегистра.УстановитьИспользованиеИтогов(Истина);

// Выполняем полный помесячный пересчет без параметров
МенеджерРегистра.ПересчитатьИтогиЗаПериод();

Если требуется выполнить данную операцию для всех регистров накопления конфигурации после масштабной свертки, применим циклический обход метаданных:


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

Способ 2. Использование обработки «Управление итогами»

Рассмотрим интерактивный способ без написания программного кода через режим «1С:Предприятие»:

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

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

Иногда при прерывании процесса свертки или некорректном удалении объектов в базе могут остаться записи движений, у которых документ-регистратор был удален, но признак Активность = Истина сохранился. В интерфейсе такие записи не видны в разрезе документов, но они продолжают влиять на виртуальные остатки.

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


ВЫБРАТЬ
    Регистр.Регистратор КАК Регистратор,
    Регистр.Период КАК Период
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладахБухгалтерскийУчет КАК Регистр
ГДЕ
    Регистр.Регистратор.Ссылка ЕСТЬ NULL

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

Особенности даты документов ввода остатков

Обратим внимание на важный нюанс позиционирования документов свертки по временной шкале:

  1. Документы ввода начальных остатков (например, КорректировкаЗаписейРегистров или ВводНачальныхОстатков) должны быть проведены строго последней секундой свернутого периода — 31.12.2015 23:59:59.
  2. Если документ остатков проведен датой 01.01.2016 00:00:00, то при формировании отчета с отбором на начало дня 01.01.2016 (с исключением границы времени) данные ввода остатков могут не попасть в начальное сальдо отчета.

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

← На главную