Почему в регистре накопления формируются некорректные остатки и как это исправить?

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

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

Как формируются остатки в регистрах накопления

Физически в СУБД регистр накопления с поддержкой остатков состоит из нескольких связанных таблиц:

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

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

Основные причины появления ошибочных остатков

Выясним основные факторы, приводящие к расхождению данных:

  1. Рассинхронизация таблиц движений и итогов: сбои транзакций, некорректное аварийное выключение сервера или ошибки СУБД могут привести к тому, что движения записались, а таблица итогов не обновилась.
  2. Смещение границы рассчитанных итогов: если дата актуальности итогов отстает от текущего периода, платформе приходится восстанавливать цепочку остатков динамически «на лету», что повышает вероятность ошибок и замедляет работу системы.
  3. Включенное разделение итогов: если для регистра включено свойство ИспользоватьРазделениеИтогов, в базе формируются фоновые разделенные записи. При отсутствии регулярного слияния итогов могут возникать искажения данных.

Способ 1. Пересчет итогов средствами конфигуратора

Разберем наиболее надежный способ полного восстановления таблиц итогов через тестирование информационной базы:

  1. Создадим резервную копию информационной базы.
  2. Запустим базу в режиме Конфигуратор.
  3. В главном меню откроем пункт Администрирование → Тестирование и исправление...
  4. В открывшемся окне установим флаг Пересчет итогов.
  5. Нажмем кнопку Выполнить и дождемся завершения операции.

Способ 2. Управление итогами в режиме «1С:Предприятие»

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

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

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

Посмотрим на пример программного восстановления итогов конкретного регистра накопления с помощью встроенного языка 1С:


// Полный пересчет итогов по конкретному регистру накопления
РегистрыНакопления.ДПАТ_ИзносПробегШин.ПересчитатьИтоги();

// Установка актуального периода рассчитанных итогов
КонечнаяДата = КонецМесяца(ТекущаяДата());
РегистрыНакопления.ДПАТ_ИзносПробегШин.УстановитьПериодРассчитанныхИтогов(КонечнаяДата);

Корректное составление запросов к виртуальным таблицам

Проанализируем частые ошибки при обращении к виртуальным таблицам остатков в запросах.

1. Перенос фильтрации в параметры виртуальной таблицы

В исходном запросе условие по серии номенклатуры было ошибочно помещено в блок ГДЕ. При таком подходе СУБД сначала собирает остатки по всем сериям базы и лишь потом отсекает лишнее. Передадим условие во второй параметр виртуальной таблицы:


ВЫБРАТЬ
    ДПАТ_ИзносПробегШинОстатки.ПробегОстаток КАК ПробегОстаток,
    ДПАТ_ИзносПробегШинОстатки.СерияНоменклатуры КАК СерияНоменклатуры
ИЗ
    РегистрНакопления.ДПАТ_ИзносПробегШин.Остатки(
        &Период, 
        СерияНоменклатуры = &СерияНоменклатуры
    ) КАК ДПАТ_ИзносПробегШинОстатки

2. Использование объекта Граница для точного позиционирования

Если передать в параметр &Период обычную дату, остатки рассчитываются на начало указанной секунды, исключая документы, проведенные в этот же момент. Для точного включения или исключения движений используем объект Граница:


// Включая движения текущей секунды:
ГраницаВключая = Новый Граница(ТекущаяДата(), ВидГраницы.Включая);
Запрос.УстановитьПараметр("Период", ГраницаВключая);

// Для получения остатков на момент проведения конкретного документа:
Запрос.УстановитьПараметр("Период", ДокументСсылка.МоментВремени());
← На главную