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