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

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет
← На главную

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

Суть проблемы: столкновение логики запроса и механизмов СКД

Рассмотрим типичную ситуацию. Нам необходимо построить отчет по оплатам за октябрь 2022 года. В этом отчете мы хотим видеть не только сами платежи, но и документы, к которым эти оплаты привязаны (например, расходные накладные). Если оплата пришла 15.10.2022, а накладная была выписана 03.11.2022 (отгрузка после аванса), мы ожидаем увидеть эту накладную в отчете.

В консоли запросов все работает идеально: запрос честно выбирает оплаты за октябрь и подтягивает связанные документы за любую дату. Однако в СКД те документы, дата которых выходит за границы октября «вперед» (например, ноябрьские), внезапно исчезают из результата. Это происходит из-за того, что СКД — это не просто транслятор запроса к базе данных, а интеллектуальный построитель, который активно вмешивается в текст запроса перед его выполнением.

Причина №1: Зарезервированные имена параметров

Одной из главных особенностей СКД является наличие зарезервированных имен параметров. К ним относятся НачалоПериода, КонецПериода и Период. Разберем подробнее, как система их обрабатывает:

  1. Автоматическая подстановка: Если в схеме компоновки включена галочка «Автозаполнение», СКД анализирует запрос и ищет в нем виртуальные таблицы или поля с типом Дата.
  2. Конфликт имен: Если вы создали свои параметры с именами &НачалоПериода и &КонецПериода и привязали их, например, к стандартному периоду в настройках, СКД считает их «своими».
  3. Глобальная фильтрация: Система может неявно наложить условие ГДЕ Период МЕЖДУ &НачалоПериода И &КонецПериода на все таблицы в запросе, включая физические таблицы регистров, даже если вы этого не просили.

Проанализируем фрагмент запроса, который может вызывать проблему в СКД:


ВЫБРАТЬ
    РасчетыСПокупателями.Регистратор КАК Регистратор,
    РасчетыСПокупателями.Документ КАК Документ,
    РасчетыСПокупателями.Сумма КАК СуммаОплаты
ИЗ
    РегистрНакопления.РасчетыСПокупателями КАК РасчетыСПокупателями
ГДЕ
    РасчетыСПокупателями.Период МЕЖДУ &НачалоПериода И &КонецПериода

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

Решение проблемы через уникальные имена параметров

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

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

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

Причина №2: Влияние ролей полей

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

Для решения ситуации проанализируем следующие действия:

Причина №3: Расширение языка запросов и фигурные скобки

СКД использует специальные конструкции в фигурных скобках {}, которые называются расширением языка запросов. Рассмотрим пример использования этих конструкций для управления периодом:


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

Параметр {(&ПериодНеИспользовать)} сообщает системе компоновки, что к данной виртуальной таблице не нужно автоматически применять глобальный период отчета. Это критически важно, когда в одном отчете вы соединяете данные за разные периоды или хотите получить «сопутствующие» данные, не ограниченные основным фильтром.

Разберем по шагам правильную настройку параметров виртуальной таблицы

Чтобы гарантировать, что СКД не подставит свои значения в параметры виртуальной таблицы Обороты или ОстаткиИОбороты, рекомендуется явно указывать параметры внутри круглых скобок, но вне фигурных:

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

Заключение

Разница в поведении Консоли запросов и СКД обусловлена механизмом автозаполнения и использованием зарезервированных имен. Чтобы ваш отчет всегда выдавал ожидаемый результат, следуйте правилу: для сложной логики, где данные могут выходить за границы периода (как в случае с авансами и последующими отгрузками), всегда используйте уникальные имена параметров и явно управляйте ролями полей в наборах данных. Это избавит вас от «невидимых» условий ГДЕ, которые СКД услужливо добавляет в ваш код.

← На главную