Как решить проблему с последовательными периодами и виртуальными таблицами в СКД 1С?

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

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

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

Выясняем причину: почему запрос ломается в СКД?

Главным виновником такого поведения является механизм Автозаполнения (флаг Автозаполнение на вкладке Наборы данных в СКД). По умолчанию этот флаг всегда включен для новых наборов данных типа "Запрос".

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

  1. Унификация параметров виртуальных таблиц: Когда СКД видит в тексте запроса обращения к виртуальным таблицам (например, СрезПоследних, Обороты или ОстаткиИОбороты), она пытается оптимизировать работу с базой данных. Если автозаполнение включено, СКД принудительно заменяет ваши собственные параметры периодов (такие как &ПериодС или &ПериодПо) на стандартные глобальные параметры схемы.
  2. Игнорирование логики разработчика: Из-за автоматической замены параметров разные части объединенного запроса начинают использовать одни и те же даты. В итоге логика последовательности периодов (когда один период плавно перетекает в другой) полностью нарушается, и вторая часть запроса возвращает пустой результат.
  3. Необязательность параметров в фигурных скобках: Попытка просто обернуть параметры в фигурные скобки без дополнительной настройки часто приводит к тому, что данные вообще исчезают. Фигурные скобки {} — это расширение языка запросов СКД, которое делает параметры необязательными. Если СКД считает, что параметр не заполнен или не настроен должным образом на вкладке параметров, она просто исключает его из запроса к виртуальной таблице, что приводит к неконтролируемому срезу данных.

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

Способ 1. Отключение автозаполнения (Самый быстрый и надежный метод)

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

Разберем этот процесс по шагам:

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

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

Способ 2. Использование фигурных скобок с жесткой фиксацией параметров

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

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


ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних({&ПериодС}, ) КАК ЦеныНоменклатурыСрезПоследних

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

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

Чтобы этот запрос не терял данные при выполнении, выполним следующую настройку:

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

Способ 3. Связывание параметров через выражения СКД (Удобно для пользователя)

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

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

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

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

ДобавитьКДате(&ПериодОтчета.ДатаНачала, "Месяц", 1)

Важный нюанс: обработка границ периодов в СрезПоследних

При работе со стыками дат в СКД очень часто возникает классическая проблема "последней секунды". Виртуальная таблица СрезПоследних рассчитывает остатки или значения на **начало** указанной секунды. Если документ проведен ровно в граничную секунду (например, 31.12.2025 23:59:59), то простой срез на эту дату может не захватить изменения.

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

ДобавитьКДате(КонецПериода(&ПериодПо, "День"), "Секунда", 1)

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

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

← На главную