При разработке сложных отчетов в системе компоновки данных (СКД) часто возникает задача совмещения данных разного типа в одном наборе. Типичный пример: первая часть отчета должна показывать остатки (срез последних) на конкретную дату, а вторая часть — движения за период, который начинается ровно в ту же секунду, когда был сделан срез. Разберем подробно, как настроить такую логику, чтобы отчет работал корректно и был удобен для пользователя.
Когда мы добавляем в запрос СКД виртуальные таблицы (например, СрезПоследних) или используем условия по периоду, система автоматически включает механизм "Автозаполнения". Этот механизм создает стандартные параметры НачалоПериода и КонецПериода. Однако, если нам нужно, чтобы КонецПериода1 был равен НачалуПериода2, стандартное поведение СКД может игнорировать наши попытки ручной привязки. Проанализируем ситуацию: пользователь хочет ввести одну дату или один период, а система должна сама распределить эти значения между разными частями запроса.
Это самый надежный и гибкий способ. Его суть заключается в том, чтобы предоставить пользователю один понятный параметр, а технические параметры для запросов вычислять автоматически на уровне схемы компоновки. Рассмотрим по шагам, как это реализовать:
ПериодОтчета с типом СтандартныйПериод. Именно его будет видеть и заполнять пользователь.&ДатаСреза (тип Дата). В колонке Выражение пропишем:
&ПериодОтчета.ДатаНачала
Этот параметр мы будем использовать в виртуальной таблице среза последних.&ДатаКонца (тип Дата). В колонке Выражение укажем:
&ПериодОтчета.ДатаОкончания
&ДатаСреза и &ДатаКонца) обязательно установим флаг Ограничение доступности. Это скроет их от пользователя, чтобы не вносить путаницу в интерфейс.Теперь в тексте запроса мы можем свободно использовать эти параметры. Выясним, как это выглядит в коде запроса:
ВЫБРАТЬ
РегистрСведений.ФизическоеЛицо,
РегистрСведений.Состояние
ИЗ
РегистрСведений.КадроваяИстория.СрезПоследних(&ДатаСреза, ) КАК РегистрСведений
Проанализируем важный нюанс: если дата среза последних и дата начала движений совпадают (например, 01.01.2018 00:00:00), существует риск того, что запись, попавшая в срез, будет продублирована в движениях, если фильтр движений использует условие "больше или равно". Чтобы избежать этого, воспользуемся функциями языка выражений СКД для модификации даты.
Для параметра, отвечающего за начало второй части отчета (движений), в поле Выражение можно прописать добавление одной секунды:
ДобавитьКДате(&ПериодОтчета.ДатаНачала, "СЕКУНДА", 1)
Это позволит "развести" две части отчета во времени: срез возьмет состояние на начало секунды, а движения начнутся сразу после этого момента. Посмотрим на пример использования в условии физической таблицы:
ГДЕ
КадроваяИстория.Период МЕЖДУ &НачалоДвижений И &ДатаКонца
Если СКД продолжает навязывать свои стандартные параметры, нам необходимо взять управление в свои руки. Разберем, как работают фигурные скобки {} в тексте запроса. Они указывают компоновщику, что данное поле или параметр должны обрабатываться особым образом.
Например, для виртуальной таблицы среза последних это будет выглядеть так:
РегистрСведений.ИмяРегистра.СрезПоследних({(&ДатаСреза)}, )
Использование фигурных скобок вокруг параметра &ДатаСреза говорит СКД: "Используй именно этот параметр, даже если ты нашла другие подходящие по смыслу даты в схеме".
Если ситуация становится совсем сложной (например, в запросе много объединений и вложенных таблиц), мы можем полностью отключить флаг Автозаполнение на закладке Набор данных. В этом случае нам придется вручную добавить все поля в список полей набора данных, но зато мы получим 100% контроль над тем, куда и какие параметры подставляет система.
Когда нам нужно вывести всё в одну таблицу, мы часто используем конструкцию ОБЪЕДИНИТЬ ВСЕ. Рассмотрим структуру такого запроса, где первая часть — это "входной остаток", а вторая — "изменения за период":
// Часть 1: Срез на начало
ВЫБРАТЬ
"1. Остаток на начало" КАК ТипСтроки,
Срез.ФизЛицо,
Срез.Количество
ИЗ
РегистрСведений.Численность.СрезПоследних(&ДатаСреза, ) КАК Срез
ОБЪЕДИНИТЬ ВСЕ
// Часть 2: Движения за период
ВЫБРАТЬ
"2. Движение" КАК ТипСтроки,
Движения.ФизЛицо,
Движения.Количество
ИЗ
РегистрСведений.Численность КАК Движения
ГДЕ
Движения.Период > &ДатаСреза И Движения.Период <= &ДатаКонца
Обратим внимание на поле ТипСтроки. Оно критически важно для настройки группировок в СКД. С его помощью мы сможем в настройках отчета визуально разделить начальные данные и последующие изменения, создав иерархию или просто разные секции в одном отчете.
Рассмотрим несколько советов, которые помогут сделать отчет быстрее и стабильнее:
СрезПоследних, имеют тип Дата. Попытка передать туда СтандартныйПериод напрямую приведет к ошибке исполнения отчета.ГДЕ используются индексированные поля, такие как Период.Следуя этим правилам и используя механизм выражений параметров, вы сможете реализовать любую сложную логику управления периодами в СКД, обеспечив при этом корректность данных на стыках временных интервалов.