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