Работа с системой компоновки данных (СКД) при использовании набора данных — запрос обычно не вызывает сложностей, так как платформа берет на себя большую часть работы по трансляции отборов в SQL-запрос. Однако, когда мы переходим к набору данных — объект (например, передаем в отчет готовую ТаблицуЗначений), стандартные механизмы фильтрации могут «отказываться» работать. Разберем по шагам, почему это происходит и как заставить отборы функционировать корректно.
Одной из наиболее частых причин игнорирования отборов является использование колонок с неопределенным типом в передаваемой таблице значений. Если вы добавляете колонку в таблицу программно, не указывая ОписаниеТипов, система компоновки может не сопоставить тип значения в отборе с типом данных в колонке.
Рассмотрим пример того, как неправильно создавать таблицу значений для СКД:
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Менеджер"); // Тип не определен (Произвольный)
ТЗ.Колонки.Добавить("Сумма");
Проанализируем ситуацию: когда пользователь устанавливает отбор по менеджеру, СКД пытается сравнить ссылку из настроек с объектом в таблице. Если тип колонки в ТЗ — «Произвольный», механизм сравнения может отработать непредсказуемо. Чтобы решить эту проблему, всегда используйте жесткую типизацию:
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Пользователи"));
ОписаниеТипаМенеджер = Новый ОписаниеТипов(МассивТипов);
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Менеджер", ОписаниеТипаМенеджер);
ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
Если в вашем отчете переопределена процедура ПриКомпоновкеРезультата или отчет формируется полностью программно (например, в модуле обработки), важно проверить, как передаются настройки в процессор компоновки. Рассмотрим типичную ошибку в коде:
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
// ОШИБКА: использование настроек по умолчанию вместо пользовательских
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, ВнешниеИсточники, ДанныеРасшифровки);
Выясним причину: в данном примере в метод Инициализировать не передаются текущие настройки компоновщика, которые включают в себя изменения, сделанные пользователем на форме (те самые отборы). Правильный подход заключается в использовании метода ПолучитьНастройки() у компоновщика настроек:
// Получаем настройки с учетом пользовательских правок
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеИсточники, ДанныеРасшифровки);
Важный момент: если вы используете типовые конфигурации на базе БСП, проверьте, не отключена ли стандартная обработка в ПриКомпоновкеРезультата. Если СтандартнаяОбработка = Ложь, вы полностью отвечаете за применение отборов в коде.
Система компоновки данных крайне чувствительна к значениям NULL в колонках, по которым производится фильтрация. Если ваша исходная таблица значений получена в результате сложного соединения (Left Join) и содержит NULL, отборы могут работать «через раз» или игнорировать часть строк.
Посмотрим на пример решения: при формировании таблицы значений в запросе или программно, обязательно обрабатывайте пустые значения. Вместо NULL используйте пустую ссылку соответствующего типа:
// В запросе получения данных для ТЗ
ВЫБРАТЬ
ЕСТЬNULL(Продажи.Менеджер, ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)) КАК Менеджер
ИЗ
...
Это гарантирует, что при наложении фильтра «Менеджер Равно [КонкретныйСсылка]», СКД сможет корректно сравнить значения во всех строках.
Часто пользователи жалуются, что отбор вида Номенклатура.Наименование СОДЕРЖИТ "Текст" не работает для набора данных — объект. Это происходит потому, что СКД «видит» в колонке ТЗ только ссылку, но не всегда может автоматически дотянуться до свойств этой ссылки в базе данных при работе с внешним набором.
Для решения этой проблемы разберем следующий прием:
Номенклатура) проверьте колонку «Тип значения». Она не должна быть пустой. Укажите конкретный тип справочника.Проанализируем настройки полей в самой схеме СКД. Если вы вручную добавляли поля в набор данных и при этом сняли флаг «Автозаполнение», вам необходимо самостоятельно настроить возможности использования этих полей.
Посмотрите на колонку «Ограничения» в списке полей набора данных. Убедитесь, что для нужного поля не стоят галочки в столбцах:
Если эти флаги установлены, поле будет доступно для выбора в списке полей отчета, но любые попытки наложить на него фильтр будут игнорироваться системой без вывода ошибок.
Если все вышеперечисленные методы не помогают, попробуйте выполнить следующие действия:
Еще -> Установить стандартные настройки. Иногда старые закэшированные настройки варианта конфликтуют с новой структурой схемы.Менеджер для поля МенеджерОтбор). Иногда наложение фильтра на вычисляемое поле «пробивает» проблему с объектным набором данных.ТаблицеЗначений (программный код) в точности совпадает с именем поля в наборе данных СКД (с учетом регистра).Соблюдение этих правил позволит вам создавать надежные отчеты на базе внешних данных, в которых пользовательские фильтры будут работать так же стабильно, как и в отчетах на базе прямых SQL-запросов.