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