Как правильно настроить отчет на базе виртуальной таблицы ОстаткиИОбороты, чтобы корректно отображались остатки в разрезе регистратора

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Анализ проблемы: почему Регистратор ломает остатки

Рассмотрим стандартный запрос, который часто пишут начинающие разработчики:


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

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

Проанализируем ситуацию на примере. Допустим, у нас есть две записи:

  1. Документ «Начисление» на 10 000 руб. (Приход).
  2. Документ «Расходный кассовый ордер» на 10 000 руб. (Расход).

Если мы используем периодичность Регистратор в запросе, в строке с «Начислением» отчет покажет конечный остаток 10 000 руб., так как на момент записи этого документа выплаты еще не было. В строке с «РКО» конечный остаток будет 0. В итоге пользователь видит в иерархии по сотруднику сумму остатков из разных строк, и данные не обнуляются так, как ожидалось.

Решение №1: Использование периодичности Авто

Первый и самый важный шаг — это отказ от жесткого указания регистратора в параметрах виртуальной таблицы. Вместо этого мы должны использовать значение Авто. Разберем, как изменить запрос:


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

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

Решение №2: Правильная настройка ролей полей в СКД

Просто изменить запрос недостаточно. Чтобы СКД понимала, как правильно вычислять остатки при наличии поля Регистратор, необходимо зайти в конструктор схемы компоновки данных на закладку «Наборы данных» и проверить колонку «Роли». Это критически важный момент для корректной работы ресурсов.

Проанализируем необходимые настройки ролей:

  1. Для измерений (Партнер, Договор): Убедимся, что у них стоит роль Измерение. Если поле составного типа (например, ОбъектРасчетов), проверьте, чтобы в разных документах в это поле попадали одинаковые значения. Если в одном документе договор заполнен, а в другом — нет, СКД разделит эти остатки на разные строки.
  2. Для поля Регистратор: Установим роль Период. В свойствах роли укажите тип периода Дополнительный.
  3. Для поля ПериодСекунда: Рекомендуется добавить это поле в запрос. Ему следует назначить роль Период с порядковым номером 1. Это поможет системе правильно сортировать документы внутри одной секунды и корректно рассчитывать нарастающий итог.

Выясним причину, почему поле СуммаКонечныйОстаток иногда ведет себя странно. В СКД для полей остатков автоматически устанавливаются правила расчета итогов. Если роли настроены верно (указаны измерения и периоды), СКД не будет просто суммировать значения конечных остатков из всех строк. Она возьмет значение остатка только из последнего периода в группировке. Именно поэтому после настройки ролей и перехода на периодичность Авто отчет начнет показывать «0» в итоговой строке по сотруднику.

Решение №3: Проверка аналитики (измерений)

Если после выполнения предыдущих шагов остаток все равно не обнуляется, нам нужно проанализировать сами данные в регистре. Выясним, нет ли расхождений в аналитических разрезах. В конфигурациях типа «Управление торговлей 11» или «ERP» объект расчетов может определяться автоматически.

Рассмотрим типичную ситуацию:

С точки зрения системы это два разных «кошелька». В одном у нас «+10 000», в другом «-10 000». В отчете, если группировка по договору выведена, мы увидим две строки. Если же группировка по договору скрыта, а выведен только Регистратор, визуально будет казаться, что суммы должны схлопнуться, но по факту они относятся к разным измерениям. Чтобы проверить это, временно добавьте все измерения регистра в детальные записи отчета. Если вы увидите пустые значения в колонках аналитики — причина в некорректном заполнении документов или логике работы регистратора.

Особенности производительности и итоги

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

Подведем итог нашего совместного разбора:

  1. Всегда используйте Авто вместо Регистратор в параметрах виртуальной таблицы ОстаткиИОбороты внутри СКД.
  2. Всегда проверяйте роли полей: измерения должны быть помечены как Измерение, а регистратор и периоды — как Период.
  3. Если остатки не сходятся — ищите различие в измерениях регистра (Партнер, Договор, Объект расчетов).

Соблюдение этих правил гарантирует, что ваши отчеты будут не только показывать верные данные, но и работать максимально быстро даже на больших объемах данных.

← На главную