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

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

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

Разберем архитектуру настроек СКД: три уровня управления

Для начала проанализируем ситуацию с точки зрения платформы 1С. Объект КомпоновщикНастроек — это не просто хранилище значений, а сложный механизм, который управляет тремя независимыми (хотя и связанными) коллекциями настроек:

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

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

Рассмотрим типичные ошибки при использовании метода ПолучитьНастройки()

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


НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки();
НастройкиОтчета.ПараметрыДанных.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Работник"), Значение);

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

Правильный способ установки параметров через КомпоновщикНастроек

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


// Установка значения в основных настройках
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("РаботникКадровойСлужбы", Работник);

Однако, как мы уже выяснили, если этот параметр вынесен в пользовательские настройки (флажок «Включать в пользовательские настройки» в СКД), то на форме значение может остаться прежним. Чтобы этого избежать, нужно обновить именно пользовательский блок.

Синхронизация с пользовательскими настройками по идентификатору

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

Рассмотрим пошаговый алгоритм решения задачи:

  1. Находим параметр в основной коллекции настроек.
  2. Проверяем наличие идентификатора пользовательской настройки.
  3. Если идентификатор есть, ищем элемент в пользовательских настройках по этому идентификатору.
  4. Устанавливаем значение.

Посмотрим на пример кода, реализующий этот подход:


ИмяПараметра = "РаботникКадровойСлужбы";
ЗначениеПараметра = Справочники.Пользователи.НайтиПоНаименованию("Иванов И.И.");

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

Где лучше выполнять этот код?

Выбор места исполнения кода критически важен для того, чтобы пользователь увидел результат. Проанализируем основные варианты:

  1. ПриКомпоновкеРезультата: Этот обработчик в модуле объекта срабатывает в момент нажатия кнопки «Сформировать». Если вы меняете настройки здесь, пользователь увидит их уже после того, как отчет будет построен. Для визуального обновления до формирования это не лучшее место.
  2. ПриСозданииНаСервере (в модуле формы): Хорошее место для установки начальных значений при открытии отчета.
  3. ПередЗагрузкойНастроекВКомпоновщик (для конфигураций на БСП): В современных типовых решениях это наиболее правильная точка расширения. Система сама позаботится о том, чтобы ваши программные установки попали в компоновщик и корректно отобразились.

Использование метода ЗагрузитьНастройки()

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


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

// Меняем параметр в этой куче
Параметр = Настройки.ПараметрыДанных.Элементы.Найти("ДатаОтчета");
Если Параметр <> Неопределено Тогда
    Параметр.Значение = ТекущаяДата();
КонецЕсли;

// Загружаем обратно, чтобы компоновщик и форма узнали об изменениях
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);

Важный момент: метод ЗагрузитьНастройки() может сбросить пользовательские правки, сделанные вручную, если не соблюдать осторожность. Будьте внимательны при работе с этим методом в интерактивных отчетах.

Особенности кеширования и обновления формы

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


// В контексте управляемой формы
ЭтаФорма.ОбновитьОтображениеДанных();

Также стоит помнить, что если параметр установлен в ФиксированныеНастройки, он вообще исчезнет из доступных для редактирования пользователем полей или станет недоступным. Это полезно, когда нужно жестко ограничить выбор, но мешает, если цель — просто подставить значение «по умолчанию».

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

← На главную