Почему не работают отборы в СКД при использовании набора данных — объект и как это исправить?

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

Работа с системой компоновки данных (СКД) при использовании набора данных — запрос обычно не вызывает сложностей, так как платформа берет на себя большую часть работы по трансляции отборов в SQL-запрос. Однако, когда мы переходим к набору данных — объект (например, передаем в отчет готовую ТаблицуЗначений), стандартные механизмы фильтрации могут «отказываться» работать. Разберем по шагам, почему это происходит и как заставить отборы функционировать корректно.

Проблема 1: Отсутствие жесткой типизации в источнике данных

Одной из наиболее частых причин игнорирования отборов является использование колонок с неопределенным типом в передаваемой таблице значений. Если вы добавляете колонку в таблицу программно, не указывая ОписаниеТипов, система компоновки может не сопоставить тип значения в отборе с типом данных в колонке.

Рассмотрим пример того, как неправильно создавать таблицу значений для СКД:


ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Менеджер"); // Тип не определен (Произвольный)
ТЗ.Колонки.Добавить("Сумма");

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


МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Пользователи"));
ОписаниеТипаМенеджер = Новый ОписаниеТипов(МассивТипов);

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Менеджер", ОписаниеТипаМенеджер);
ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));

Проблема 2: Программная инициализация процессора компоновки

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


ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
// ОШИБКА: использование настроек по умолчанию вместо пользовательских
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, ВнешниеИсточники, ДанныеРасшифровки);

Выясним причину: в данном примере в метод Инициализировать не передаются текущие настройки компоновщика, которые включают в себя изменения, сделанные пользователем на форме (те самые отборы). Правильный подход заключается в использовании метода ПолучитьНастройки() у компоновщика настроек:


// Получаем настройки с учетом пользовательских правок
Настройки = КомпоновщикНастроек.ПолучитьНастройки();

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);

ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеИсточники, ДанныеРасшифровки);

Важный момент: если вы используете типовые конфигурации на базе БСП, проверьте, не отключена ли стандартная обработка в ПриКомпоновкеРезультата. Если СтандартнаяОбработка = Ложь, вы полностью отвечаете за применение отборов в коде.

Проблема 3: Наличие значений NULL в данных

Система компоновки данных крайне чувствительна к значениям NULL в колонках, по которым производится фильтрация. Если ваша исходная таблица значений получена в результате сложного соединения (Left Join) и содержит NULL, отборы могут работать «через раз» или игнорировать часть строк.

Посмотрим на пример решения: при формировании таблицы значений в запросе или программно, обязательно обрабатывайте пустые значения. Вместо NULL используйте пустую ссылку соответствующего типа:


// В запросе получения данных для ТЗ
ВЫБРАТЬ
    ЕСТЬNULL(Продажи.Менеджер, ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)) КАК Менеджер
ИЗ
    ...

Это гарантирует, что при наложении фильтра «Менеджер Равно [КонкретныйСсылка]», СКД сможет корректно сравнить значения во всех строках.

Проблема 4: Отборы по вложенным реквизитам (через точку)

Часто пользователи жалуются, что отбор вида Номенклатура.Наименование СОДЕРЖИТ "Текст" не работает для набора данных — объект. Это происходит потому, что СКД «видит» в колонке ТЗ только ссылку, но не всегда может автоматически дотянуться до свойств этой ссылки в базе данных при работе с внешним набором.

Для решения этой проблемы разберем следующий прием:

  1. Откройте Схему компоновки данных.
  2. Перейдите на вкладку «Наборы данных».
  3. Для поля (например, Номенклатура) проверьте колонку «Тип значения». Она не должна быть пустой. Укажите конкретный тип справочника.
  4. Если это не помогло, перейдите в конструкторе на вкладку «Настройки», далее выберите нужный отчет или группировку. В нижней части найдите вкладку «Компоновка данных» -> «Условия». Добавьте туда поле, по которому планируется отбор. Это заставит СКД более внимательно анализировать данное поле при построении макета.

Проблема 5: Роли полей и флаг «Автозаполнение»

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

Посмотрите на колонку «Ограничения» в списке полей набора данных. Убедитесь, что для нужного поля не стоят галочки в столбцах:

Если эти флаги установлены, поле будет доступно для выбора в списке полей отчета, но любые попытки наложить на него фильтр будут игнорироваться системой без вывода ошибок.

Дополнительные рекомендации

Если все вышеперечисленные методы не помогают, попробуйте выполнить следующие действия:

Соблюдение этих правил позволит вам создавать надежные отчеты на базе внешних данных, в которых пользовательские фильтры будут работать так же стабильно, как и в отчетах на базе прямых SQL-запросов.

← На главную