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

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

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

Разбираем механику работы виртуальных таблиц

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

  1. Обращение к физической таблице итогов: Платформа хранит рассчитанные итоги в таблице с постфиксом _AccumRgT. Обычно эти итоги рассчитаны на начало каждого месяца.
  2. Добор данных из таблицы движений: Система берет ближайшие к нужной дате рассчитанные итоги и прибавляет или вычитает к ним реальные движения из основной таблицы (_AccumRg) за период между датой итогов и датой запроса.
  3. Текущие итоги: Если дата запроса пустая или установлена далеко в будущее, система обращается к так называемым «текущим итогам» (в базе они хранятся на дату 01.11.3999).

Выясним причину, по которой автор темы сначала не увидел результата: корректировка была сделана концом месяца, и запрос остатков выполнялся на этот же момент времени. В 1С важно учитывать границу периода. Если запрос делается на момент времени документа, сам документ (корректировка) может не войти в выборку в зависимости от настроек границы запроса. Проанализируем ситуацию: на начало следующего месяца остатки обнулились, так как документ корректировки гарантированно попал в расчет.

Проблема «разбухания» итогов и «нулевых» остатков

Существует заблуждение, что если сумма по регистру равна нулю, то запись из базы исчезает. Проанализируем, почему это не так. В таблице итогов _AccumRgT записи хранятся в разрезе всех измерений. Если ваше движение «Приход» имело заполненное измерение Склад, а движение «Расход» в корректировке — нет, то в таблице итогов останутся две строки:

В сумме (агрегированно) отчет может показать ноль, но физически в таблице итогов записи останутся. Это и есть то самое «разбухание». Рассмотрим подробнее последствия такого накопления «хвостов»:

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

Как правильно закрывать остатки в ноль

Чтобы корректировка действительно «схлопнула» записи в таблице итогов, необходимо обеспечить полную идентичность измерений. Выясним, на что обратить внимание при программном заполнении или использовании документа КорректировкаЗаписейРегистров:

1. Идентичность измерений: Каждое измерение (Склад, Номенклатура, Характеристика, Серия, Заказ) должно в точности совпадать с тем, что зависло в остатках. Если в остатке измерение NULL, в корректировке оно тоже должно быть NULL.

2. Использование правильного типа движения: Если остаток положительный, делаем движение Расход. Если отрицательный — Приход.

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


ВЫБРАТЬ
    Рег.Номенклатура,
    Рег.Склад,
    Рег.КоличествоОстаток
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК Рег
ГДЕ
    Рег.КоличествоОстаток = 0

Такие записи — прямой кандидат на очистку, так как они свидетельствуют о несовпадении каких-то скрытых измерений или разделителей.

Зачем нужен пересчет итогов?

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

Это помогает в следующих случаях:

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

Рекомендации по поддержанию здоровья регистров

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

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

Таким образом, мы выяснили, что «зависшие» остатки чаще всего являются следствием невнимательности к моменту времени запроса или различий в измерениях регистра. Правильное понимание работы _AccumRgT позволяет не только исправлять ошибки учета, но и существенно оптимизировать скорость работы системы.

← На главную