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

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

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

Анализ проблемы: почему сбрасываются пользовательские настройки

Проанализируем типовой фрагмент кода обработчика ПриКомпоновкеРезультата, в котором возникает ошибка:


СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;

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

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

Решение: правильное получение настроек через КомпоновщикНастроек

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

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

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

Метод ПолучитьНастройки() возвращает полную копию настроек компоновки данных с учетом следующих механизмов:

  1. К базовым настройкам применяются все пользовательские настройки, измененные на форме отчета.
  2. Автоматически учитываются фиксированные настройки: отбор из фиксированных настроек добавляется к отборам основных настроек, условное оформление объединяется с основным, а параметры устанавливаются в значения по умолчанию.

Важные правила программной компоновки отчета с набором данных Объект

Чтобы избежать других распространенных ошибок при работе с набором данных «Объект» в процедуре ПриКомпоновкеРезультата, разберем по шагам ключевые нюансы реализации:

  1. Отключение стандартной обработки. В самом начале процедуры необходимо установить СтандартнаяОбработка = Ложь;. Если этого не сделать, после завершения вашего кода платформа выполнит стандартную генерацию отчета. Так как во внешнем стандартном процессоре переданная таблица значений отсутствует, возникнет ошибка выполнения либо ваш результат будет перезаписан пустым отчетом.
  2. Использование схемы отчета вместо повторной загрузки макета. Не следует использовать ПолучитьМакет(). Это создает дубликат схемы в памяти. Вместо этого обращаемся напрямую к контексту текущего отчета: СхемаКомпоновкиДанных или ЭтотОбъект.СхемаКомпоновкиДанных.
  3. Корректная обработка расшифровки на управляемых формах. Не создавайте объект расшифровки заново через Новый ДанныеРасшифровкиКомпоновкиДанных, если вы хотите сохранить стандартную функциональность расшифровки платформы. Входящий в процедуру параметр ДанныеРасшифровки уже инициализирован платформой, и его следует напрямую передавать в методы компоновщика макета и процессора компоновки.
  4. Строгая типизация колонок таблицы значений. Если таблица для набора данных формируется кодом, обязательно задавайте точные типы колонок через ОписаниеТипов. При наличии нетипизированных полей СКД может некорректно обрабатывать условия равенства, сравнения со ссылками или обращение через точку к реквизитам объектов (например, Номенклатура.Артикул).
  5. Оптимизация производительности. Помните, что при передаче всей таблицы значений в процессор компоновки фильтрация по отборам выполняется платформой в оперативной памяти после формирования данных. Если выборка из базы огромна, гораздо эффективнее прочитать элементы отбора из настроек компоновки заранее и применить фильтры на уровне первичного запроса к базе данных.

Итоговый правильный пример кода

Посмотрим на готовый и корректный вариант процедуры ПриКомпоновкеРезультата в модуле объекта отчета:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Отключаем стандартную компоновку отчета платформой
    СтандартнаяОбработка = Ложь;
    
    // Получаем настройки с учетом изменений пользователя на форме
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Сформируем или получим внешнюю таблицу значений
    // ТаблЗнч = ПолучитьТаблицуДанных();
    
    // Формируем макет с помощью компоновщика макета
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    // Инициализируем процессор компоновки данными внешнего набора
    ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
    ВнешниеНаборы = Новый Структура("ТаблицаВывода", ТаблЗнч);
    ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборы, ДанныеРасшифровки);
    
    // Очищаем табличный документ и выводим результат
    ДокументРезультат.Очистить();
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
    
КонецПроцедуры

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

← На главную