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