При разработке комплексных отчетов в Системе компоновки данных (СКД) часто требуется объединить информацию из разных источников: например, совместить данные специализированного регистра взаиморасчетов, типовых документов реализации и банковских выписок. Нередко разработчики сталкиваются с ситуацией, когда запрос, прекрасно работающий в консоли запросов, внутри отчета СКД возвращает строки только из первой секции объединения, а остальные данные полностью игнорируются.
Разберем подробно причины такого поведения схемы компоновки, выясним, как правильно настроить параметры отчета, и рассмотрим рекомендации по оптимизации структуры запросов.
Проанализируем типовую ситуацию. В тексте запроса используется конструкция ОБЪЕДИНИТЬ ВСЕ, где первая выборка обращается к виртуальной таблице регистра без жестких фильтров по реквизитам, а последующие выборки содержат строгое условие ГДЕ:
ГДЕ РеализацияУслуг.Период МЕЖДУ &ДатаНачало И &ДатаКонец
И РеализацияУслуг.Организация = &организация
И РеализацияУслуг.Регистратор.Контрагент.Ссылка = &контрагент
Если на вкладке Параметры схемы компоновки данных для параметров &организация или &контрагент установлена галочка Ограничение доступности, пользователь не видит эти параметры в форме отчета и не может передать в них значения. В результате на этапе выполнения запроса условия сравниваются с пустыми значениями или NULL, и вторая с третьей выборки возвращают 0 строк, в то время как первая выборка продолжает выводить данные.
Разберем по шагам, как исправить видимость и обязательность параметров в СКД:
&организация и &контрагент.Посмотрим на конструкцию условий. Использование жесткого блока ГДЕ Поле = &Параметр вынуждает платформу требовать обязательного наличия значения в параметре. Если пользователь захочет сформировать отчет по всем контрагентам сразу, такой запрос ничего не вернет.
В СКД для опциональных отборов применяется специальный синтаксис фигурных скобок. Если параметр или отбор не задан пользователем, компоновщик данных автоматически исключит условие из результирующего текста SQL-запроса:
ГДЕ
РеализацияУслуг.Период МЕЖДУ &ДатаНачало И &ДатаКонец
{ГДЕ
РеализацияУслуг.Организация.* КАК Организация,
РеализацияУслуг.Регистратор.Контрагент.* КАК Контрагент}
Такой подход позволяет избавиться от принудительной фильтрации, когда параметры остаются пустыми, и делает отчет гибким.
Проанализируем результирующие поля всех трех запросов в объединении. При выполнении ОБЪЕДИНИТЬ ВСЕ типы данных в одинаковых позициях выборки должны быть согласованы:
ДоговорКонтрагента, во втором — ссылка или пустая строка "", в третьем — строковое поле ДоговорКонтрагента.Наименование. В результате в одной колонке смешиваются ссылочный и строковый типы, что приводит к некорректной группировке и сбоям при наложении отборов в СКД. Для пустых значений ссылочных типов следует использовать пустую ссылку ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка) либо NULL.ВЫРАЗИТЬ(0 КАК ЧИСЛО(15, 2)), чтобы СКД корректно определила тип ресурса и рассчитала итоги.Рассмотрим дополнительные технические нюансы, которые влияют на стабильность и быстродействие подобных отчетов:
РеализацияУслуг.Регистратор.Контрагент производит обращение через точку к реквизиту составного типа Регистратор. На уровне СУБД это порождает неявные соединения со всеми существующими таблицами документов конфигурации, которые могут выступать регистраторами регистра. Всегда предпочтительнее выбирать контрагента и договор напрямую из измерений регистра или реквизитов конкретного документа.ЖурналДокументов.БанковскиеВыписки в аналитических отчетах не рекомендуется. Журналы предназначены для отображения списков в пользовательском интерфейсе. Для получения точных данных о поступлениях следует обращаться к табличной части Документ.ПоступлениеНаРасчетныйСчет.РасшифровкаПлатежа либо к соответствующему регистру накопления.