Как в отчете СКД настроить условие с необязательным фильтром по контрагенту?

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

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

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

Способ 1. Использование расширения языка запросов (фигурные скобки)

Если требуется передать необязательный параметр непосредственно в текст запроса, используются фигурные скобки { }. Конструкция внутри скобок включается в итоговый SQL-запрос только тогда, когда пользователь устанавливает соответствующее значение отбора или параметра.

Проанализируем синтаксис наложения условий через фигурные скобки:

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

Способ 2. Настройка отбора средствами компоновки данных без изменения текста запроса

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

В этом случае прописывать условия с помощью фигурных скобок в тексте запроса не обязательно. Отбор настраивается в схеме компоновки или программно:

  1. Интерактивно: Перейдем на вкладку «Настройки» -> «Отбор» и добавим поле Контрагент. Пользователь сможет самостоятельно включать или отключать данный флаг в форме отчета.
  2. Программно через компоновщик настроек:
    
    ЭлементОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = МойКонтрагент;
    ЭлементОтбора.Использование = Истина;
    

Критически важные рекомендации по оптимизации запроса

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

  1. Обращение через точку к составному полю Регистратор:
    Поле Регистратор в регистрах бухгалтерии имеет составной тип данных. Конструкция Регистратор.Контрагент или Регистратор.Проведен заставляет СУБД выполнять неявное левое соединение (LEFT JOIN) со всеми таблицами документов, которые могут выступать регистраторами этого регистра.
    Решение: Если контрагент содержится в аналитике (субконто) регистра, обращайтесь к субконто напрямую. Если контрагент есть только в документе, рекомендуется предварительно выбрать нужные ссылки во временную таблицу с отбором по контрагенту, проиндексировать их, а затем соединять с виртуальной таблицей.
  2. Лишняя проверка проведения документов:
    Условие Регистратор.Проведен = ИСТИНА является избыточным для виртуальных таблиц оборотов и остатков. Виртуальные таблицы регистров по умолчанию формируются только на основе активных записей (где Активность = ИСТИНА). Непроведенные документы не имеют активных движений, поэтому обращаться к реквизитам регистратора для этой проверки не требуется.
  3. Использование необязательных соединений:
    Если в запросе используются левые соединения со справочниками (например, с таблицей ДоговорыКонтрагентов), выделите соединение как необязательное на вкладке «Компоновка данных» -> «Таблицы». В таком случае СКД не будет выполнять физическое соединение таблиц на стороне СУБД, если поля присоединяемой таблицы не выбраны пользователем в отчете.
← На главную