В практике разработки на платформе 1С:Предприятие часто встречается ситуация, когда при запросе к виртуальной таблице остатков регистра накопления (например, Остатки) разработчик видит данные, которых там быть не должно. Это происходит потому, что записи, помеченные как неактивные (флаг Активность = Ложь), по какой-то причине продолжают учитываться в итоговых значениях. Давайте детально разберем природу этого явления и выясним, как исправить подобные расхождения.
Для начала проанализируем внутреннюю архитектуру регистров накопления. В системе 1С данные хранятся не в одной таблице, а в нескольких физических таблицах СУБД. Основная таблица содержит детальные записи (движения), а вспомогательные таблицы итогов хранят агрегированные данные (обычно на начало каждого месяца). Когда мы обращаемся к виртуальной таблице Остатки, платформа не сканирует все движения с момента начала учета. Вместо этого она берет ближайшие рассчитанные итоги и прибавляет к ним движения за короткий промежуток времени.
Проблема «фантомных остатков» возникает в тот момент, когда нарушается синхронизация между основной таблицей движений и таблицей итогов. В нормальном состоянии, если у записи снимается флаг Активность, система автоматически корректирует таблицу итогов, вычитая значения этой записи. Если же в процессе записи произошел программный сбой, аварийное завершение сеанса или использовались специфические режимы записи (например, Загрузка = Истина), данные в основной таблице могут стать неактивными, а в таблице итогов изменения не зафиксируются.
Это стандартный и наиболее надежный метод решения проблемы. Если мы обнаружили, что виртуальные таблицы возвращают некорректные значения, первым делом следует выполнить пересчет итогов. Разберем по шагам, как это сделать:
Во время этого процесса система полностью очистит существующие таблицы итогов и заново сформирует их на основании данных из основной физической таблицы движений, учитывая актуальное состояние флага Активность. После завершения операции «фантомные» записи исчезнут из виртуальных таблиц.
Бывают ситуации, когда монопольный доступ к базе (необходимый для работы Конфигуратора) получить невозможно, а исправить итоги нужно здесь и сейчас. В этом случае мы можем воспользоваться средствами встроенного языка 1С. Рассмотрим, как программно инициировать пересчет итогов для конкретного регистра накопления.
Для этого мы можем использовать менеджер регистра накопления. Посмотрим на пример кода, который выполняет пересчет:
// Пример программного пересчета итогов для конкретного регистра
РегистрИмя = РегистрыНакопления.ОстаткиТоваров;
// Отключаем использование итогов (это очистит таблицы итогов)
РегистрИмя.УстановитьИспользованиеИтогов(Ложь);
// Включаем обратно (система начнет расчет заново)
РегистрИмя.УстановитьИспользованиеИтогов(Истина);
Также существует метод ПересчитатьИтоги(), который можно вызвать для определенного периода. Проанализируем ситуацию: если мы знаем, что проблема возникла в конкретном месяце, мы можем выполнить пересчет только за этот период, чтобы сэкономить время и ресурсы сервера.
В типовых конфигурациях (таких как ERP, УТ 11, БП 3.0) предусмотрены встроенные обработки для управления итогами. Если вы не хотите писать код, выполните следующие действия:
Чтобы окончательно выяснить причину расхождений, мы рекомендуем сравнить данные из виртуальной таблицы с данными физической таблицы. Разберем пример запроса, который поможет локализовать ошибку. Если сумма по физической таблице (с фильтром Активность = Истина) не совпадает с суммой из виртуальной таблицы — значит, итоги «развалились».
Посмотрим на пример диагностического запроса:
ВЫБРАТЬ
СУММА(ТекДвижения.Количество) КАК СуммаПоФизическойТаблице
ИЗ
РегистрНакопления.ИмяВашегоРегистра КАК ТекДвижения
ГДЕ
ТекДвижения.Активность = ИСТИНА
И ТекДвижения.Номенклатура = &Номенклатура
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
СУММА(ТекОстатки.КоличествоОстаток)
ИЗ
РегистрНакопления.ИмяВашегоРегистра.Остатки( , Номенклатура = &Номенклатура) КАК ТекОстатки
Если результаты этих двух запросов различаются, значит, ваше решение — пересчет итогов одним из описанных выше способов.
Рассмотрим подробнее причины, которые могут приводить к таким ошибкам в будущем, чтобы минимизировать риск их повторения:
ОбменДанными.Загрузка = Истина система отключает многие проверки. Если вы программно меняете активность записей в этом режиме, платформа может «забыть» обновить итоги. Всегда вызывайте пересчет или обновление итогов после массовых загрузок.Подводя итог, можно сказать: виртуальные таблицы в 1С — это мощный инструмент оптимизации, но они полностью зависят от целостности вспомогательных таблиц итогов. При любых подозрениях на некорректность остатков по неактивным записям, первым делом выполняйте полный пересчет итогов. Это действие безопасно и в 99% случаев решает проблему.