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