Проанализируем типовую ситуацию: при выполнении запроса к виртуальной таблице остатков регистра накопления платформа возвращает отрицательное или не соответствующее действительности значение, хотя документов с движениями за указанный период нет. Разберем, как устроено хранение остатков в платформе 1С:Предприятие, выясним причину сбоя и рассмотрим пошаговые методы исправления.
Физически в СУБД регистр накопления с поддержкой остатков состоит из нескольких связанных таблиц:
Когда мы обращаемся к виртуальной таблице Остатки, платформа не сканирует все движения с момента начала ведения базы данных. Она берет ближайшие рассчитанные итоги из таблицы итогов и прибавляет (или вычитает) движения из таблицы движений за интервал между точкой итогов и запрошенной датой. Если связь между этими таблицами нарушается или итоги не были рассчитаны вовремя, виртуальная таблица начинает возвращать неверные данные.
Выясним основные факторы, приводящие к расхождению данных:
ИспользоватьРазделениеИтогов, в базе формируются фоновые разделенные записи. При отсутствии регулярного слияния итогов могут возникать искажения данных.Разберем наиболее надежный способ полного восстановления таблиц итогов через тестирование информационной базы:
Если требуется восстановить итоги без монопольного захвата всей базы, воспользуемся стандартным функционалом управления итогами:
Посмотрим на пример программного восстановления итогов конкретного регистра накопления с помощью встроенного языка 1С:
// Полный пересчет итогов по конкретному регистру накопления
РегистрыНакопления.ДПАТ_ИзносПробегШин.ПересчитатьИтоги();
// Установка актуального периода рассчитанных итогов
КонечнаяДата = КонецМесяца(ТекущаяДата());
РегистрыНакопления.ДПАТ_ИзносПробегШин.УстановитьПериодРассчитанныхИтогов(КонечнаяДата);
Проанализируем частые ошибки при обращении к виртуальным таблицам остатков в запросах.
1. Перенос фильтрации в параметры виртуальной таблицы
В исходном запросе условие по серии номенклатуры было ошибочно помещено в блок ГДЕ. При таком подходе СУБД сначала собирает остатки по всем сериям базы и лишь потом отсекает лишнее. Передадим условие во второй параметр виртуальной таблицы:
ВЫБРАТЬ
ДПАТ_ИзносПробегШинОстатки.ПробегОстаток КАК ПробегОстаток,
ДПАТ_ИзносПробегШинОстатки.СерияНоменклатуры КАК СерияНоменклатуры
ИЗ
РегистрНакопления.ДПАТ_ИзносПробегШин.Остатки(
&Период,
СерияНоменклатуры = &СерияНоменклатуры
) КАК ДПАТ_ИзносПробегШинОстатки
2. Использование объекта Граница для точного позиционирования
Если передать в параметр &Период обычную дату, остатки рассчитываются на начало указанной секунды, исключая документы, проведенные в этот же момент. Для точного включения или исключения движений используем объект Граница:
// Включая движения текущей секунды:
ГраницаВключая = Новый Граница(ТекущаяДата(), ВидГраницы.Включая);
Запрос.УстановитьПараметр("Период", ГраницаВключая);
// Для получения остатков на момент проведения конкретного документа:
Запрос.УстановитьПараметр("Период", ДокументСсылка.МоментВремени());