При работе с системой компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда запрос, идеально работающий в консоли запросов, начинает выдавать странные результаты в отчете. Типичный пример — игнорирование параметров виртуальных таблиц регистра бухгалтерии, таких как СубконтоДт или СубконтоКт. В этой статье мы подробно разберем, почему это происходит и как заставить СКД корректно фильтровать данные.
Рассмотрим ситуацию: нам необходимо получить обороты по счету 26 в корреспонденции с другими счетами, но только по тем проводкам, где в качестве кредитового субконто выступают «Контрагенты». Мы пишем стандартный запрос к виртуальной таблице ХозрасчетныйОборотыДтКт:
ВЫБРАТЬ
ХозрасчетныйОборотыДтКт.СчетДт КАК СчетДт,
ХозрасчетныйОборотыДтКт.СубконтоДт1 КАК СубконтоДт1,
ХозрасчетныйОборотыДтКт.СчетКт КАК СчетКт,
ХозрасчетныйОборотыДтКт.СубконтоКт1 КАК СубконтоКт1,
ХозрасчетныйОборотыДтКт.Регистратор КАК Регистратор,
СУММА(ХозрасчетныйОборотыДтКт.СуммаОборот) КАК СуммаОборот
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(
&НачалоПериода,
&КонецПериода,
Запись,
СчетДт = &сч26,
,
,
ЗНАЧЕНИЕ(ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты),
) КАК ХозрасчетныйОборотыДтКт
СГРУППИРОВАТЬ ПО
ХозрасчетныйОборотыДтКт.СчетДт,
ХозрасчетныйОборотыДтКт.СубконтоДт1,
ХозрасчетныйОборотыДтКт.СчетКт,
ХозрасчетныйОборотыДтКт.СубконтоКт1,
ХозрасчетныйОборотыДтКт.Регистратор
Проблема заключается в том, что в консоли запросов этот код работает идеально, отсекая лишние корреспонденции (например, Дт 26 — Кт 70). Однако в СКД, как только мы добавляем в структуру отчета группировки и ресурсы, фильтр по типу субконто перестает действовать, и в отчет «прилетают» все обороты по 26 счету.
Проанализируем механизм работы СКД. Система компоновки данных не выполняет запрос в том виде, в котором вы его написали. Она выступает в роли генератора кода. На основе ваших настроек (группировок, выбранных полей, отборов) компоновщик макета создает исполняемый запрос, который может существенно отличаться от исходного.
Основные причины игнорирования параметров:
СубконтоКт используется в группировках, СКД пытается управлять его фильтрацией через собственные механизмы, конфликтуя с параметрами виртуальной таблицы.СубконтоКт предназначен не только для фильтрации, но и для упорядочивания. Передача одиночного значения через ЗНАЧЕНИЕ(...) иногда интерпретируется компоновщиком только как указание типа данных для колонки, но не как жесткое условие ГДЕ.Самый надежный способ заставить СКД учитывать параметры — это использовать механизм расширения языка запросов. Вместо жесткого прописывания типа субконто внутри скобок, мы укажем СКД, что этот параметр должен быть доступен для управления компоновщиком.
Изменим текст запроса в наборе данных:
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(
&НачалоПериода,
&КонецПериода,
Запись,
СчетДт = &сч26,
,
,
{&СубконтоКт},
) КАК ХозрасчетныйОборотыДтКт
Теперь на закладке «Параметры» в схеме СКД появится параметр СубконтоКт. Установите для него нужное значение (Вид субконто «Контрагенты»). Использование фигурных скобок {} явно говорит компоновщику, что этот фильтр должен быть включен во все генерируемые подзапросы, включая расчет итогов.
Рассмотрим ситуацию, когда мы не хотим выносить вид субконто в параметры пользователя. В этом случае нам нужно проверить, как СКД видит наши поля. Выполним следующие шаги:
Если отчет достаточно сложный и СКД продолжает вести себя непредсказуемо, проанализируем возможность отключения флага «Автозаполнение» в наборе данных запроса.
Когда «Автозаполнение» включено, СКД вольно интерпретирует ваш запрос. Если флаг снять, вам придется вручную указать все доступные поля на закладке «Набор данных», но это запретит системе произвольно менять структуру ИЗ вашего запроса при генерации временных таблиц для итогов. В этом случае параметры виртуальной таблицы, прописанные в круглых скобках, будут переданы в СУБД максимально близко к оригиналу.
Хотя фильтрация внутри параметров виртуальной таблицы работает быстрее на уровне СУБД, в случае проблем с СКД можно перенести условие в секцию ГДЕ или использовать параметры отбора СКД.
Выясним причину, почему это может помочь: условия в секции ГДЕ анализируются компоновщиком иначе и чаще всего накладываются на уже агрегированные данные или включаются в секцию WHERE итогового SQL-запроса более стабильно.
ГДЕ
ХозрасчетныйОборотыДтКт.СубконтоКт1 ССЫЛКА Справочник.Контрагенты
Важно: Этот способ менее эффективен с точки зрения производительности, так как система сначала выберет все обороты, а потом будет их фильтровать. Используйте его только в крайнем случае, если методы с фигурными скобками не дали результата.
Подводя итог, отметим: если вы заметили, что СКД игнорирует параметры СубконтоКт или СубконтоДт, в первую очередь попробуйте использовать расширение языка запросов {&СубконтоКт}. Это наиболее «правильный» с точки зрения архитектуры 1С способ взаимодействия с компоновщиком макета, который гарантирует корректную работу фильтров как в детальных записях, так и в сложных группировках с расчетом ресурсов.