Почему виртуальная таблица оборотов регистра накопления возвращает неверные данные и как это исправить

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

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

Сравнение запроса к виртуальной таблице и физической таблице

Рассмотрим типовую ситуацию. При обращении к виртуальной таблице оборотов используется следующий запрос:


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

В то же время прямой запрос к физической таблице движений показывает совершенно другие, фактически верные числа:


ВЫБРАТЬ
    усКонтрольПриемки.ОжидаемаяПриемка КАК ОжидаемаяПриемка,
    усКонтрольПриемки.Номенклатура КАК Номенклатура,
    СУММА(усКонтрольПриемки.КоличествоЗапланировано),
    СУММА(усКонтрольПриемки.КоличествоЗапланировано - усКонтрольПриемки.КоличествоСкорректировано) КАК КоличествоЗапланированоНачальное,
    СУММА(усКонтрольПриемки.КоличествоПринято),
    СУММА(усКонтрольПриемки.КоличествоСкорректировано),
    СУММА(усКонтрольПриемки.КоличествоЗапланировано - усКонтрольПриемки.КоличествоСкорректировано - усКонтрольПриемки.КоличествоПринято) КАК РасхожденияПриемкиДэ
ИЗ
    РегистрНакопления.усКонтрольПриемки КАК усКонтрольПриемки
СГРУППИРОВАТЬ ПО
    ОжидаемаяПриемка,
    Номенклатура

Выясним основные причины, приводящие к подобным расхождениям, и шаги по их устранению.

1. Рассинхронизация итогов регистра накопления

Виртуальная таблица Обороты не читает каждую строку физической таблицы движений, а обращается к предварительно рассчитанным агрегатам в таблице итогов регистра. В случаях некорректного завершения сеансов, аварийных сбоев СУБД или прямого вмешательства в базу данных рассчитанные итоги могут разойтись с реальными записями.

Стандартное «Тестирование и исправление» (ТИИ) не всегда гарантирует полное исправление агрегатов оборотных регистров. Для принудительного и полного пересчета итогов выполним программный пересчет через встроенный язык 1С:


// Полный пересчет итогов по конкретному регистру
РегистрыНакопления.усКонтрольПриемки.ПересчитатьИтоги();

// Либо пересчет за заданный интервал дат
РегистрыНакопления.усКонтрольПриемки.ПересчитатьИтогиЗаПериод(ДатаНачала, ДатаОкончания);

Также проверим актуальность границы рассчитанных итогов через стандартную обработку Управление итогами или метод УстановитьПериодРассчитанныхИтогов().

2. Передача условий отбора в параметры виртуальной таблицы

Проанализируем структуру параметров виртуальной таблицы. В оборотном регистре виртуальная таблица принимает следующие параметры:

  1. НачалоПериода — начальная дата выборки;
  2. КонецПериода — конечная дата выборки;
  3. Периодичность — периодичность группировки (например, Месяц, Регистратор, Авто);
  4. Условие — условия отбора по измерениям регистра.

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

Перенесем условие фильтрации непосредственно в параметры виртуальной таблицы:


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

3. Особенности работы с периодами и группировками в СКД

При использовании системы компоновки данных (СКД) ручная группировка СГРУППИРОВАТЬ ПО в тексте запроса чаще всего является избыточной, так как СКД сама управляет агрегацией ресурсов согласно настройкам на вкладке «Настройки» и «Ресурсы».

Если в схеме компоновки данных параметры &ДатаНачала и &ДатаОкончания жестко прописаны в тексте запроса, они могут конфликтовать со стандартным периодом отчета СКД. Если период задается пользователем в настройках отчета, рекомендуется доверить управление границами периодов механизму СКД либо явно передавать в параметры начало и конец дня:


// В коде инициализации отчета
ПараметрыОтчета.Установить("ДатаНачала", НачалоДня(ВыбДатаНачала));
ПараметрыОтчета.Установить("ДатаОкончания", КонецДня(ВыбДатаОкончания));

4. Влияние механизма разделения итогов

Если для оборотного регистра включено свойство Разделение итогов (Split Totals), платформа оптимизирует параллельную запись движений, записывая промежуточные итоги с разными разделителями. Если регламентное задание по свертке разделенных итогов не выполняется вовремя, при запросах к виртуальной таблице могут возникать временные неточности или задержки. Проверим активность регламентного задания по свертке итогов либо временно отключим разделение итогов для регистра, после чего выполним пересчет.

← На главную