Почему слетают программные настройки компоновщика при переходе на клиент и как это исправить

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

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

Анализируем причину проблемы: Жизненный цикл расширения формы

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

Также важно помнить о связи между Настройками и ПользовательскимиНастройками. Если мы изменили основную структуру настроек, но не синхронизировали её с тем, что видит пользователь на экране, на клиенте мы получим пустые поля или значения по умолчанию.

Решение 1: Использование вспомогательного реквизита формы

Рассмотрим метод, который помог автору темы. Суть заключается в создании «буфера» на форме, который не подвержен автоматической очистке расширением отчета. Мы создаем реквизит формы с типом КомпоновщикНастроекКомпоновкиДанных и используем его для переноса состояния между серверным и клиентским контекстом.

Выполним следующие шаги:

  1. Добавим в форму реквизит, назовем его, например, БуферНастроек с типом КомпоновщикНастроекКомпоновкиДанных.
  2. В обработчике ПриСозданииНаСервере заполним этот реквизит после того, как установим все необходимые параметры в основном объекте.

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


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

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


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    
    // Переносим настройки из буфера обратно в основной компоновщик отчета
    Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(БуферНастроек.Настройки);
    
КонецПроцедуры

Этот метод гарантирует, что настройки «доедут» до клиента в целости и сохранности.

Решение 2: Инициализация через временное хранилище и ИсточникДоступныхНастроек

Проанализируем более «чистый» с точки зрения архитектуры способ. Часто компоновщик теряет данные, потому что на клиенте он «не знает», к какой схеме он привязан, особенно если схема динамическая или внешняя. Чтобы компоновщик корректно работал на клиенте, ему нужен ИсточникДоступныхНастроекКомпоновкиДанных, инициализированный через адрес во временном хранилище.

Разберем этот процесс по шагам:

  1. Помещаем схему компоновки (СКД) во временное хранилище.
  2. Создаем источник доступных настроек, используя полученный адрес.
  3. Инициализируем компоновщик этим источником.

Рассмотрим пример реализации на сервере:


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

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

Решение 3: Использование ФиксированныхНастроек

Выясним причину, по которой нам иногда не подходят обычные настройки. Если мы хотим установить фильтры, которые пользователь не должен менять, и которые гарантированно не должны «слететь», нам следует использовать свойство ФиксированныеНастройки.

Важный нюанс: ФиксированныеНастройки не отображаются в пользовательском интерфейсе (в таблице настроек), они накладываются «сверху» при выполнении отчета. Они хранятся в отдельной структуре и не перетираются стандартными механизмами инициализации формы.

Рассмотрим, как добавить фиксированный отбор:


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

Эти настройки останутся неизменными на протяжении всего сеанса работы с формой, пока вы не очистите их программно.

Синхронизация идентификаторов (UserSettingsID)

Посмотрим на ситуацию глубже. Иногда настройки присутствуют в КомпоновщикНастроек.Настройки, но форма их не отображает. Это происходит из-за потери связи по идентификаторам. Каждый элемент пользовательских настроек имеет свой ИдентификаторПользовательскойНастройки.

Если вы программно создаете новый элемент отбора или параметра на сервере, не забывайте:

Проанализируем пример правильной синхронизации:


&НаСервере
Процедура УстановитьПараметрСОбновлениемПользовательских(ИмяПараметра, ЗначениеПараметра)
    
    Настройки = Отчет.КомпоновщикНастроек.Настройки;
    ЭлементПараметра = Настройки.ПараметрыДанных.Элементы.Найти(ИмяПараметра);
    
    Если ЭлементПараметра <> Неопределено Тогда
        ЭлементПараметра.Значение = ЗначениеПараметра;
        ЭлементПараметра.Использование = Истина;
        
        // Обязательно загружаем обратно, чтобы обновились ПользовательскиеНастройки
        Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
    КонецЕсли;
    
КонецПроцедуры

Подводим итоги

Мы рассмотрели несколько стратегий борьбы с «исчезающими» настройками. Выбор метода зависит от вашей конкретной задачи:

  1. Если нужно просто передать программные настройки с сервера на клиент при открытии — используйте дополнительный реквизит формы как буфер.
  2. Если вы строите сложный интерфейс с динамическими фильтрами — используйте ИсточникДоступныхНастроек через временное хранилище.
  3. Если настройки должны быть неизменными и скрытыми от пользователя — используйте ФиксированныеНастройки.
  4. Если отчет встроен в конфигурацию с БСП (Библиотека Стандартных Подсистем), проверьте, не перекрываются ли ваши настройки механизмами сохранения вариантов отчетов. В таких случаях лучше использовать переопределяемые модули БСП или изучить реализацию сохранения настроек формы для всех пользователей.

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

← На главную