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

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

При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда параметры в шапке отчета заполнены верно, но результат оказывается пустым или некорректным. Особенно часто это происходит при использовании списков номенклатуры и условий В ИЕРАРХИИ. Проанализируем типичную проблему: в параметрах указана конкретная группа товаров, но в итоговом запросе система "видит" дополнительный пустой отбор, который блокирует вывод данных.

Разбор ситуации: Конфликт параметров и отборов

Рассмотрим пример запроса, который используется в отчете. Мы выбираем данные из документа РасходныйОрдерНаТовары и пытаемся отфильтровать их по списку номенклатуры, переданному через параметр &СписокТоваров.


ВЫБРАТЬ РАЗЛИЧНЫЕ
    РасходныйОрдерНаТоварыТоварыПоРаспоряжениям.Номенклатура КАК Номенклатура,
    РасходныйОрдерНаТовары.Дата КАК Дата,
    РасходныйОрдерНаТовары.Ссылка КАК Ссылка,
    СУММА(РАЗНОСТЬДАТ(РасходныйОрдерНаТовары.Дата, &Текущая_Дата, ДЕНЬ)) КАК КлвДнейСЗаказа
ИЗ
    Документ.РасходныйОрдерНаТовары КАК РасходныйОрдерНаТовары
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РасходныйОрдерНаТовары.ТоварыПоРаспоряжениям КАК РасходныйОрдерНаТоварыТоварыПоРаспоряжениям
    ПО РасходныйОрдерНаТовары.Ссылка = РасходныйОрдерНаТоварыТоварыПоРаспоряжениям.Ссылка
ГДЕ
    РасходныйОрдерНаТовары.Дата МЕЖДУ &ДатаНачала И &ДатаКонца
    И РасходныйОрдерНаТовары.Проведен = ИСТИНА
    И РасходныйОрдерНаТоварыТоварыПоРаспоряжениям.Номенклатура В ИЕРАРХИИ(&СписокТоваров)
СГРУППИРОВАТЬ ПО
    РасходныйОрдерНаТоварыТоварыПоРаспоряжениям.Номенклатура,
    РасходныйОрдерНаТовары.Дата,
    РасходныйОрдерНаТовары.Ссылка

Проанализируем, что происходит в режиме "1С:Предприятие". Пользователь выбирает в параметрах группу "Материалы", но отчет выводит странную диагностику: Отбор: Номенклатура В группе "". Выясним причину этого поведения. Проблема заключается в том, что в СКД существуют два независимых механизма фильтрации: Параметры данных (те, что мы прописали в тексте запроса через &) и Отбор (стандартный механизм компоновщика настроек).

Причина №1: "Фантомные" пользовательские настройки

Система 1С сохраняет настройки каждого отчета для каждого пользователя в специальном системном хранилище (Settings Storage). Если в процессе разработки вы меняли структуру отчета, удаляли или переименовывали поля, старые настройки могли "зависнуть" в кэше. Рассмотрим, как это работает: пользователь когда-то сформировал отчет с пустым отбором, и 1С запомнила это состояние. Даже если вы исправили запрос, система пытается наложить старый пустой фильтр поверх нового параметра.

Решение: Чтобы устранить эту проблему, необходимо сбросить пользовательские настройки. В режиме пользователя это делается через меню "Еще" — "Установить стандартные настройки". Если это не помогает, рекомендуется полностью удалить настройки отчета для текущего пользователя через "Администрирование" — "Настройки пользователей и прав" — "Очистка настроек".

Причина №2: Механизм "Автозаполнение"

Посмотрим на вкладку "Наборы данных" в конструкторе СКД. Там установлен флаг Автозаполнение. Когда он включен, СКД автоматически анализирует текст запроса и выносит все поля, указанные в секции ВЫБРАТЬ и ГДЕ, в список доступных полей отбора. Если разработчик вручную добавил параметр &СписокТоваров в запрос, а СКД при этом создала еще и поле отбора Номенклатура, возникает дублирование условий. Система объединяет их по правилу "И", и если один из фильтров пуст — результат будет пустым.

Оптимизация: Использование расширения языка запросов СКД

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


ГДЕ
    РасходныйОрдерНаТовары.Дата МЕЖДУ &ДатаНачала И &ДатаКонца
    И РасходныйОрдерНаТовары.Проведен = ИСТИНА
    {ГДЕ РасходныйОрдерНаТоварыТоварыПоРаспоряжениям.Номенклатура.* КАК Номенклатура}

Разберем преимущества этого подхода:

  1. Динамичность: Если пользователь не заполнил отбор по номенклатуре, условие вообще не попадет в итоговый SQL-запрос. Это исключает ошибки типа "В группе пустая ссылка".
  2. Гибкость: Пользователь сможет выбирать вид сравнения сам (Равно, В списке, В иерархии), и СКД автоматически сформирует оптимальный запрос.
  3. Производительность: При использовании фигурных скобок СКД более эффективно строит временные таблицы для иерархических отборов.

Как программно очистить настройки при разработке?

Если вы часто меняете структуру отчета и не хотите каждый раз вручную сбрасывать настройки, можно добавить в модуль объекта отчета код для программной очистки кэша. Посмотрим на пример кода в процедуре ПриКомпоновкеРезультата:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Если структура отчета сильно изменилась, можно форсировать сброс настроек
    // Но будьте осторожны: это удалит все сохраненные варианты пользователя!
    // ХранилищеСистемныхНастроек.Удалить("Отчет.ИмяВашегоОтчета", "", ИмяПользователя());
    
КонецПроцедуры

Рекомендации по настройке параметров в СКД

Чтобы отчет работал стабильно, выполним следующие шаги в конструкторе СКД:

  1. Флаг "Запрещать незаполненные значения": Для критически важных параметров (например, период или список товаров, если отчет очень тяжелый) установите этот флаг на вкладке "Параметры". Это предотвратит случайный запуск отчета по всей базе.
  2. Ограничение доступности: Если вы используете расширение языка запросов (фигурные скобки), сам параметр &СписокТоваров можно скрыть от пользователя (флаг "Ограничение доступности"), оставив только поле в настройках отбора.
  3. Тип значения: Всегда проверяйте, что тип данных параметра соответствует типу поля в базе. Для номенклатуры это должна быть СправочникСсылка.Номенклатура, а для списка — СписокЗначений с соответствующим типом.

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

← На главную