Как в СКД получить данные за три последних месяца от текущей даты?

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

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

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

Анализ проблемы: путаница в синтаксисе функций работы с датами

Основная причина трудностей при решении подобных задач — смешивание разных стандартов написания кода в экосистеме 1С. Разработчику необходимо четко разделять три контекста:

  1. Встроенный язык (код модулей): здесь мы используем привычные функции вроде КонецМесяца(), ДобавитьМесяц() или ТекущаяДата().
  2. Язык запросов: в теле запроса (в том числе в параметрах виртуальных таблиц) используются функции КОНЕЦПЕРИОДА() и ДОБАВИТЬКДАТЕ(), причем тип периода пишется как ключевое слово без кавычек (например, МЕСЯЦ, ДЕНЬ).
  3. Язык выражений СКД: на вкладке «Параметры» в схеме компоновки данных используется свой собственный синтаксис. Здесь функция КонецПериода() требует передачи типа периода в виде строки в кавычках (например, "Месяц"). Использование функции встроенного языка КонецМесяца() или синтаксиса запросов без кавычек здесь приведет к ошибке компоновки.

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

Рассмотрим по шагам три способа реализации нашей задачи.

Способ 1. Настройка выражений параметров в СКД (Рекомендуемый)

Самый правильный и изящный способ с точки зрения архитектуры СКД — оставить текст запроса максимально простым, а всю логику расчета дат перенести на вкладку «Параметры» компоновщика данных. Это позволит избежать нагромождения формул в самом запросе.

Допустим, в запросе СКД используется обращение к виртуальной таблице оборотов:


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

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

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

Вариант А: Три месяца, включая текущий. Например, сегодня 15 февраля. Нам нужны полные декабрь, январь и текущий февраль. Началом периода должно стать 1 декабря. Смещение назад составляет ровно 2 месяца.

В колонку «Выражение» для параметра НачалоПериода запишем формулу на языке СКД:

НачалоПериода(ДобавитьКДате(ТекущаяДата(), "Месяц", -2), "Месяц")

Для параметра КонецПериода запишем формулу, которая вернет конец текущего месяца:

КонецПериода(ТекущаяДата(), "Месяц")

Вариант Б: Три последних полностью завершенных месяца (без текущего). Например, сегодня 15 февраля. Нам нужны полные ноябрь, декабрь и январь. Начало периода — 1 ноября (смещение на 3 месяца назад), конец периода — 31 января (смещение на 1 месяц назад).

Выражение для НачалоПериода:

НачалоПериода(ДобавитьКДате(ТекущаяДата(), "Месяц", -3), "Месяц")

Выражение для КонецПериода:

КонецПериода(ДобавитьКДате(ТекущаяДата(), "Месяц", -1), "Месяц")

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

Способ 2. Расчет дат непосредственно в параметрах виртуальной таблицы запроса

Если по каким-то причинам требуется жестко прописать формулу расчета прямо в тексте запроса, мы можем использовать функции языка запросов. В этом случае параметром отчета будет выступать некая базовая дата (например, &ДатаДок или &ВыбДата), от которой будет строиться смещение.

Посмотрим, как выглядит текст запроса для получения данных за 3 последних месяца (включая текущий):


ВЫБРАТЬ
    ПродажиОбороты.Номенклатура,
    ПродажиОбороты.КоличествоОборот КАК Количество
ИЗ
    РегистрНакопления.Продажи.Обороты(
        НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаДок, МЕСЯЦ, -2), МЕСЯЦ),
        КОНЕЦПЕРИОДА(&ДатаДок, МЕСЯЦ),
        Запись,
        ) КАК ПродажиОбороты

Важные нюансы этого способа:

Способ 3. Использование системного типа «СтандартныйПериод»

Этот способ является стандартом разработки в среде 1С. Он позволяет задать отчету динамический период по умолчанию (за последние 3 месяца), но при этом оставляет пользователю удобную возможность интерактивно изменить этот период при необходимости.

Разберем этот вариант по шагам:

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

    &ПериодОтчета.ДатаНачала

  6. В поле «Выражение» для параметра КонецПериода пропишем:

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

Теперь пользователь в настройках отчета будет видеть удобное поле выбора периода, где он сможет одним нажатием выбрать «Текущий месяц», «Прошлый квартал» или установить произвольный интервал, а виртуальная таблица запроса всегда будет получать точные даты начала и окончания.

Рекомендация по обработке точной границы периода

При работе с датой окончания периода на уровне платформы 1С часто возникает проблема «последней секунды». Если конечная дата установлена без указания времени (например, 31.01.2024 00:00:00), то документы, проведенные в течение этого последнего дня, могут не попасть в выборку виртуальной таблицы оборотов.

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

← На главную