Как программно установить отбор в СКД и обновить его отображение на форме

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

При работе с Системой компоновки данных (СКД), создавая универсальный отчет по метаданным, разработчики часто сталкиваются с ситуацией, когда программно установленный отбор успешно применяется к результату отчета, но визуально на форме отчета (в пользовательских настройках) он не отображается: флажок использования не взводится, а поле значения остается пустым. Это создает неудобства для пользователя, который не видит фактических условий фильтрации. Рассмотрим подробнее, почему это происходит и как правильно синхронизировать программные настройки с интерфейсом, особенно в конфигурациях на базе Библиотеки стандартных подсистем (БСП), таких как 1С:ЗУП 3.1 (для которой пригодится специализированная консоль запросов) или 1С:Бухгалтерия 3.0 — для этого подойдёт специализированная консоль запросов и СКД для разработчика.

Выясним причину проблемы

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

Способ 1: Установка через ПользовательскиеНастройки

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

Рассмотрим пример функции, которая находит нужный элемент отбора по имени поля и устанавливает его значение в пользовательских настройках:


Процедура УстановитьПользовательскуюНастройку(КомпоновщикНастроек, ИмяПоля, Значение)
    
    ПолеДанных = Новый ПолеКомпоновкиДанных(ИмяПоля);
    ЭлементОтбора = Неопределено;

    // 1. Ищем элемент в основных настройках отбора
    Для Каждого Элемент Из КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
        Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") 
            И Элемент.ЛевоеЗначение = ПолеДанных Тогда
            ЭлементОтбора = Элемент;
            Прервать;
        КонецЕсли;
    КонецЦикла;

    Если ЭлементОтбора = Неопределено Тогда
        Возврат; // Отбор не найден в схеме
    КонецЕсли;

    // 2. Ищем связанный элемент в пользовательских настройках по Идентификатору
    Идентификатор = ЭлементОтбора.ИдентификаторПользовательскойНастройки;
    ПользовательскийЭлемент = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Идентификатор);

    Если ПользовательскийЭлемент <> Неопределено Тогда
        ПользовательскийЭлемент.ПравоеЗначение = Значение;
        ПользовательскийЭлемент.Использование = Истина;
        ПользовательскийЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    КонецЕсли;

КонецПроцедуры

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

Способ 2: Обновление формы в конфигурациях на БСП

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

  1. Программно устанавливаем настройки (например, при открытии или при изменении других параметров).
  2. Вызываем метод ОтчетыСервер.ОбновитьЭлементыФормыНастроек.

Посмотрим на пример кода в модуле формы:


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

Способ 3: Принудительная загрузка настроек

Если вы не используете БСП или форма самописная, можно попробовать заставить компоновщик "перечитать" состояние своих настроек. Для этого используется метод ЗагрузитьПользовательскиеНастройки(). Проанализируем ситуацию: мы программно меняем коллекцию, а затем как бы "перезагружаем" её в компоновщик, что инициирует обновление связанных элементов формы.


// После изменения элементов в КомпоновщикНастроек.ПользовательскиеНастройки
КомпоновщикНастроек.ЗагрузитьПользовательскиеНастройки(КомпоновщикНастроек.ПользовательскиеНастройки);

Нюансы программного добавления новых отборов

Если отбора изначально нет в настройках (он не выведен в быстрые настройки в конфигураторе), нам нужно не просто изменить значение, а создать новый элемент. При этом критически важно установить свойство ИдентификаторПользовательскойНастройки, иначе поле не появится в интерфейсе.

Разберем по шагам процесс добавления нового отбора:

  1. Создаем новый ЭлементОтбораКомпоновкиДанных в КомпоновщикНастроек.Настройки.Отбор.Элементы.
  2. Генерируем уникальный идентификатор (GUID) или берем существующий.
  3. Присваиваем этот GUID свойству ИдентификаторПользовательскойНастройки созданного элемента.
  4. Устанавливаем режим отображения (например, БыстрыйДоступ).
  5. Добавляем аналогичный элемент в ПользовательскиеНастройки с тем же идентификатором.

Посмотрим на пример кода:


НовыйИдентификатор = Новый УникальныйИдентификатор;

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

// После этого БСП или метод ЗагрузитьПользовательскиеНастройки подхватят изменение

Важные рекомендации

Проанализировав различные подходы, можно выделить несколько правил:

Таким образом, мы выяснили, что для корректного обновления формы недостаточно просто изменить настройки компоновщика — необходимо работать с коллекцией пользовательских настроек и явно вызывать методы обновления интерфейса, такие как ОтчетыСервер.ОбновитьЭлементыФормыНастроек или ЗагрузитьПользовательскиеНастройки.

← На главную