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