Как в СКД установить дату начала одного периода равной дате окончания другого периода?

Программист Управленческий учет IT и автоматизация бизнеса
← На главную

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

Анализ проблемы: почему стандартные параметры не всегда подходят

Когда мы добавляем в запрос СКД виртуальные таблицы (например, СрезПоследних) или используем условия по периоду, система автоматически включает механизм "Автозаполнения". Этот механизм создает стандартные параметры НачалоПериода и КонецПериода. Однако, если нам нужно, чтобы КонецПериода1 был равен НачалуПериода2, стандартное поведение СКД может игнорировать наши попытки ручной привязки. Проанализируем ситуацию: пользователь хочет ввести одну дату или один период, а система должна сама распределить эти значения между разными частями запроса.

Решение №1: Использование выражений в параметрах СКД

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

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

Теперь в тексте запроса мы можем свободно использовать эти параметры. Выясним, как это выглядит в коде запроса:


ВЫБРАТЬ
    РегистрСведений.ФизическоеЛицо,
    РегистрСведений.Состояние
ИЗ
    РегистрСведений.КадроваяИстория.СрезПоследних(&ДатаСреза, ) КАК РегистрСведений

Решение №2: Управление граничной секундой

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

Для параметра, отвечающего за начало второй части отчета (движений), в поле Выражение можно прописать добавление одной секунды:

ДобавитьКДате(&ПериодОтчета.ДатаНачала, "СЕКУНДА", 1)

Это позволит "развести" две части отчета во времени: срез возьмет состояние на начало секунды, а движения начнутся сразу после этого момента. Посмотрим на пример использования в условии физической таблицы:


ГДЕ
    КадроваяИстория.Период МЕЖДУ &НачалоДвижений И &ДатаКонца

Решение №3: Использование фигурных скобок и отключение автозаполнения

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

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

РегистрСведений.ИмяРегистра.СрезПоследних({(&ДатаСреза)}, )

Использование фигурных скобок вокруг параметра &ДатаСреза говорит СКД: "Используй именно этот параметр, даже если ты нашла другие подходящие по смыслу даты в схеме".

Если ситуация становится совсем сложной (например, в запросе много объединений и вложенных таблиц), мы можем полностью отключить флаг Автозаполнение на закладке Набор данных. В этом случае нам придется вручную добавить все поля в список полей набора данных, но зато мы получим 100% контроль над тем, куда и какие параметры подставляет система.

Решение №4: Объединение данных из разных периодов

Когда нам нужно вывести всё в одну таблицу, мы часто используем конструкцию ОБЪЕДИНИТЬ ВСЕ. Рассмотрим структуру такого запроса, где первая часть — это "входной остаток", а вторая — "изменения за период":


// Часть 1: Срез на начало
ВЫБРАТЬ
    "1. Остаток на начало" КАК ТипСтроки,
    Срез.ФизЛицо,
    Срез.Количество
ИЗ
    РегистрСведений.Численность.СрезПоследних(&ДатаСреза, ) КАК Срез

ОБЪЕДИНИТЬ ВСЕ

// Часть 2: Движения за период
ВЫБРАТЬ
    "2. Движение" КАК ТипСтроки,
    Движения.ФизЛицо,
    Движения.Количество
ИЗ
    РегистрСведений.Численность КАК Движения
ГДЕ
    Движения.Период > &ДатаСреза И Движения.Период <= &ДатаКонца

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

Рекомендации по оптимизации

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

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

← На главную