Почему не работает период в отчете СКД и как это исправить?

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

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

В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем логику работы виртуальных таблиц СКД и рассмотрим несколько способов ее решения.

Причина №1. Неправильная привязка параметров к «Стандартному периоду»

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

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

Как правильно настроить связь параметров:

  1. Откроем схему компоновки данных и перейдем на вкладку Параметры.
  2. Добавим новый параметр (если его еще нет), назовем его, например, ПериодОтчета и установим для него тип данных СтандартныйПериод.
  3. Для системных параметров НачалоПериода и КонецПериода заполним колонку Выражение:
    • Для НачалоПериода укажем выражение: &ПериодОтчета.ДатаНачала
    • Для КонецПериода укажем выражение: &ПериодОтчета.ДатаОкончания
  4. Установим флаг Ограничение доступности для параметров НачалоПериода и КонецПериода. Это скроет их от пользователя на форме настройки, оставив доступным только понятное поле ПериодОтчета.

Теперь при выборе периода на форме СКД будет автоматически раскладывать его на граничные даты и передавать в виртуальную таблицу.

Причина №2. Логическая ловушка таблицы «ОстаткиИОбороты» при выводе аналитики

Это неочевидный нюанс, на который разработчики часто тратят часы отладки. Допустим, мы правильно настроили связь параметров, но отчет все равно выводит документы за пределами выбранного интервала времени. Почему это происходит?

Проанализируем структуру нашего запроса. Если в выбранных полях отчета или в его группировках присутствует детальное поле-аналитика (например, ДокументРасчетов, Регистратор, Заказ или Договор), виртуальная таблица ОстаткиИОбороты начнет рассчитывать остатки в разрезе этой аналитики.

Если у клиента есть незакрытый долг по накладной, созданной три года назад, этот документ должен присутствовать в отчете за текущий месяц, так как по нему есть входящий и исходящий остатки. С точки зрения СУБД и бизнес-логики отчет работает абсолютно корректно. Но разработчику кажется, что фильтр по периоду «сломался», так как в отчете выводятся старые документы.

Как решить эту проблему в зависимости от бизнес-требований:

Вариант А. Нам нужны только документы, по которым были движения в выбранном периоде.
В этом случае вместо виртуальной таблицы ОстаткиИОбороты следует использовать таблицу Обороты. В ней физически отсутствуют остатки, поэтому старые документы без движений в выбранном периоде в отчет не попадут.

Вариант Б. Нам нужны остатки, но мы хотим скрыть документы без движений в текущем периоде.
Для этого наложим отбор на ресурсы оборотов в настройках СКД на вкладке «Настройки» -> «Отбор». Добавим условие:

СуммаОборотПриход <> 0 ИЛИ СуммаОборотРасход <> 0

Это скроет строки с нулевыми оборотами, оставив только активные в выбранном периоде документы.

Причина №3. Использование фигурных скобок и расширения языка запросов СКД

Иногда разработчики пытаются решить проблему параметров с помощью фигурных скобок, записывая запрос следующим образом:


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

Давайте разберем, как работают фигурные скобки {} в СКД. Это элементы расширения языка запросов компоновки данных. Они делают параметры необязательными:

Если вы используете фигурные скобки, убедитесь, что параметры действительно заполняются в коде или связаны с доступными пользователю полями настроек, иначе отбор по периоду просто проигнорируется системой.

Причина №4. Опасный антипаттерн: фильтрация через условие «ГДЕ»

Часто в попытках «заставить» период работать разработчики прибегают к следующей конструкции в запросе:


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

Внимание! Это грубейшая техническая ошибка, которая приведет к катастрофическому падению производительности на реальной базе данных.

Разберем, почему так делать категорически нельзя:

На крупных базах данных использование конструкции ГДЕ Период МЕЖДУ... для виртуальных таблиц остатков гарантированно приведет к зависанию сервера или ошибке переполнения базы временных таблиц (tempdb).

Причина №5. Отсутствие настроек ролей для полей периодов

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

Если отчет выводит странные пустые строки в итогах или путает остатки местами, выполним следующие шаги по настройке ролей полей:

  1. В схеме СКД перейдем на вкладку Набор данных.
  2. В списке полей найдем наши периоды и откроем колонку Роль для каждого из них.
  3. Настроим их роли следующим образом (задавая им тип «Период» и непрерывную нумерацию):
    • Для поля ПериодСекунда установим роль: Период, Порядковый номер: 1
    • Для поля Регистратор установим роль: Период, Порядковый номер: 2 (дополнительно укажем, что это обязательное поле)
    • Если используется поле НомерСтроки, установим ему роль: Период, Порядковый номер: 3

Правильная разметка ролей периодов гарантирует, что СКД сможет корректно рассчитать остатки на момент времени каждого конкретного документа в отчете.

Резюме и чек-лист для проверки отчета

Если в вашем отчете СКД не работает период, последовательно проверьте его по следующему алгоритму:

  1. Связаны ли параметры виртуальной таблицы НачалоПериода и КонецПериода со стандартным периодом на вкладке «Параметры»? Установлены ли для них ограничения доступности?
  2. Не выводите ли вы в отчет детальные документы, по которым есть остатки, но не было движений в выбранном интервале? Если да — наложите отбор на обороты или перейдите на виртуальную таблицу Обороты.
  3. Если вы используете фигурные скобки {} в параметрах виртуальной таблицы — убедитесь, что соответствующие параметры заполнены и передаются в запрос.
  4. Убедитесь, что вы не используете условие фильтрации по датам в секции ГДЕ для виртуальных таблиц остатков.
← На главную