Как в СКД работает параметр "Период" по умолчанию для остатков и среза последних?

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

При разработке отчетов в Системе Компоновки Данных (СКД) разработчики часто сталкиваются с вопросом: как именно система обрабатывает параметры виртуальных таблиц, если они не указаны явно в тексте запроса? Проанализируем типичную ситуацию на примере соединения таблицы остатков товаров и таблицы цен номенклатуры.

Посмотрим на классический пример запроса, где мы выбираем остатки товаров и актуальные цены на них:


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

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

Влияние флага "Автозаполнение"

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

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

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

Разница во включении границы периода

Теперь выясним причину частых ошибок и микрорасхождений в отчетах. Хотя СКД и передает один и тот же параметр &Период в обе виртуальные таблицы, на уровне платформы 1С эти таблицы обрабатывают тип "Дата" по-разному:

  1. Таблица остатков: получает данные строго на начало указанной секунды. Движения, совершенные внутри этой конкретной секунды, в остатки не войдут.
  2. Таблица среза последних: получает данные, включая указанную секунду.

Это означает, что если на переданную дату (с точностью до секунды) в базе проводились документы, влияющие на остатки и цены, вы можете получить рассинхронизацию данных: цены учтут последние изменения, а остатки — нет.

Как правильно решить проблему с получением данных на конец дня

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

Способ 1: Использование выражений СКД

Перейдите на вкладку "Параметры" в схеме компоновки данных. Для стандартного параметра &Период в колонке "Выражение" пропишите следующую функцию:

КонецПериода(&Период, "День")

При такой настройке, если пользователь укажет дату "15.10.2023 00:00:00", СКД автоматически преобразует её в "15.10.2023 23:59:59". Данные будут получены корректно.

Способ 2: Использование типа "Стандартный период"

Это более гибкий и профессиональный подход. Создайте новый пользовательский параметр, назовем его &ВыбранныйПериод, и назначьте ему тип СтандартныйПериод. Стандартный параметр &Период скройте от пользователя (снимите галочку ограничения доступности).

Затем в выражении для скрытого параметра &Период пропишите:

&ВыбранныйПериод.ДатаОкончания

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

Особенности при добавлении таблиц оборотов

Рассмотрим еще один важный нюанс. Что произойдет, если к нашему запросу мы добавим виртуальную таблицу оборотов (например, РегистрНакопления.ТоварыНаСкладах.Обороты)?

В этом случае при включенном автозаполнении СКД проанализирует запрос и добавит еще два стандартных параметра: &НачалоПериода и &КонецПериода. Это может запутать конечного пользователя, так как для расчета остатков будет использоваться старый параметр &Период, а для оборотов — новые параметры начала и конца.

Чтобы отчет формировался согласованно по единым датам, разработчику необходимо связать эти параметры на вкладке "Параметры". Например, можно установить выражение для параметра &Период равным параметру &КонецПериода и скрыть его. Тогда пользователь будет оперировать только началом и концом периода, а система сама подставит конец периода для расчета актуальных остатков и среза последних.

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

← На главную