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