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

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

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

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

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

Посмотрим на пример запроса к виртуальной таблице регистра бухгалтерии:


ВЫБРАТЬ
    ХозрасчетныйОстаткиИОбороты.Субконто3.ДоговорКонтрагента КАК Договор,
    ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Материал,
    ХозрасчетныйОстаткиИОбороты.СуммаНачальныйОстатокДт КАК ОстатокНаНачало,
    ХозрасчетныйОстаткиИОбороты.СуммаОборотДт КАК Приход,
    ХозрасчетныйОстаткиИОбороты.СуммаОборотКт КАК Расход,
    ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстатокДт КАК ОстатокНаКонец
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
        &НачалоПериода,
        &КонецПериода,
        ,
        ,
        Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.МатериалыПереданныеВПереработку),
        ,
    ) КАК ХозрасчетныйОстаткиИОбороты
{ГДЕ
    ХозрасчетныйОстаткиИОбороты.Субконто1 = &Контрагент}

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

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

Способ 2. Использование стандартных полей отбора СКД

Вместо жесткой привязки к параметру &Контрагент можно описать поле отбора в фигурных скобках с использованием конструкции .*. Это дает пользователю возможность использовать не только точное равенство, но и сложные виды сравнения (например, В списке, В группе, Не равно):


ВЫБРАТЬ
    ХозрасчетныйОстаткиИОбороты.Субконто3.ДоговорКонтрагента КАК Договор,
    ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Материал,
    ХозрасчетныйОстаткиИОбороты.СуммаНачальныйОстатокДт КАК ОстатокНаНачало,
    ХозрасчетныйОстаткиИОбороты.СуммаОборотДт КАК Приход,
    ХозрасчетныйОстаткиИОбороты.СуммаОборотКт КАК Расход,
    ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстатокДт КАК ОстатокНаКонец
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
        &НачалоПериода,
        &КонецПериода,
        ,
        ,
        Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.МатериалыПереданныеВПереработку),
        ,
    ) КАК ХозрасчетныйОстаткиИОбороты
{ГДЕ
    ХозрасчетныйОстаткиИОбороты.Субконто1.* КАК Контрагент}

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

Способ 3. Условие с проверкой на пустую ссылку через ВЫБОР КОГДА

Проанализируем еще один подход, предложенный на форуме, — обработку условия через конструкцию ВЫБОР КОГДА прямо в секции ГДЕ без использования синтаксиса СКД:


ГДЕ
    ВЫБОР
        КОГДА &Контрагент ЕСТЬ NULL
            ИЛИ &Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
        ТОГДА ИСТИНА
        ИНАЧЕ ХозрасчетныйОстаткиИОбороты.Субконто1 = &Контрагент
    КОНЕЦ

Рассмотрим подробнее особенности этого метода:

  1. Плюсы: запрос работает даже в том случае, если параметр передан как пустая ссылка, не вызывая синтаксических ошибок.
  2. Минусы: такой предикат ухудшает производительность. Реляционные СУБД (например, Microsoft SQL Server или PostgreSQL) не могут эффективно использовать индексы при наличии логических выражений ИЛИ и ВЫБОР в условиях соединения и фильтрации. Это приводит к полному сканированию таблицы итогов (Table Scan / Index Scan) вместо быстрого точечного поиска (Index Seek).

Рекомендации по оптимизации виртуальных таблиц

Выясним причину, по которой фильтрацию по субконто лучше передавать в параметры самой виртуальной таблицы:

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

← На главную