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

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

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

В этой статье мы подробно разберем, почему так происходит, как устроена связь между основными и пользовательскими настройками в СКД, и приведем корректный алгоритм решения этой задачи.

В чем суть проблемы?

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


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

Результат работы этого кода: Отчет действительно отбирает данные за текущий месяц. Но на форме отчета в поле "Период" пустота или старое значение.

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

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

Как работают пользовательские настройки

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

Чтобы программно изменить значение так, чтобы пользователь это увидел, нам нужно:

  1. Найти параметр в основных настройках.
  2. Узнать его уникальный идентификатор (GUID) пользовательской настройки.
  3. Найти соответствующий элемент в коллекции ПользовательскиеНастройки по этому идентификатору.
  4. Присвоить значение именно этому элементу.

Правильный алгоритм решения

Давайте реализуем универсальный подход, который не просто устанавливает параметр "где-то внутри", а корректно обновляет интерфейс (пользовательские настройки).

Ниже приведен подробный код, который решает проблему пустых полей на форме.


// 1. Создаем значение, которое хотим установить
Период = Новый СтандартныйПериод(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));

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

Если ПараметрСКД <> Неопределено Тогда
    
    // Устанавливаем значение в основных настройках (на всякий случай)
    ПараметрСКД.Значение = Период;
    ПараметрСКД.Использование = Истина;
    
    // 3. Проверяем, выведен ли этот параметр в пользовательские настройки
    // Свойство ИдентификаторПользовательскойНастройки содержит GUID, если параметр доступен пользователю
    Если ЗначениеЗаполнено(ПараметрСКД.ИдентификаторПользовательскойНастройки) Тогда
        
        // 4. Ищем элемент в коллекции ПользовательскиеНастройки по этому ID
        ПользовательскийПараметр = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(
            ПараметрСКД.ИдентификаторПользовательскойНастройки
        );
        
        // 5. Проверяем, что нашли именно значение параметра, и устанавливаем его
        Если ТипЗнч(ПользовательскийПараметр) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных") Тогда
            ПользовательскийПараметр.Значение = ПараметрСКД.Значение;
            ПользовательскийПараметр.Использование = Истина;
        КонецЕсли;
        
    КонецЕсли;
    
КонецЕсли;

Разбор ключевых моментов

Давайте проанализируем важные детали этого решения:

  1. Поиск по имени: Сначала мы обращаемся к КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы. Это "базовое" описание настроек. Здесь мы ищем параметр по его имени, заданному в конфигураторе (в схеме компоновки данных), например, "ПериодОтчета".
  2. Связь через ID: Самый важный шаг — получение ПараметрСКД.ИдентификаторПользовательскойНастройки. Если этот идентификатор пуст, значит, параметр не выведен на форму (в пользовательские настройки), и пользователю его обновлять не нужно (он его все равно не видит).
  3. Тип значения в пользовательских настройках: Обратите внимание на проверку типа ЗначениеПараметраНастроекКомпоновкиДанных. В коллекции пользовательских настроек могут лежать не только значения параметров, но и группировки или отборы. Проверка типа гарантирует, что мы меняем именно значение параметра.
  4. Флаг "Использование": Не забывайте устанавливать Использование = Истина. Даже если вы установите правильные даты, но флаг использования будет снят (Ложь), СКД проигнорирует этот параметр при формировании запроса, и пользователь увидит "серую" галочку или её отсутствие.

Где лучше размещать этот код?

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

Если ваша задача — показать период сразу при открытии формы, этот же алгоритм следует поместить в модуль формы отчета, в события:

Используя предложенный подход с поиском по идентификатору, вы гарантируете, что данные в "движке" СКД и данные на экране пользователя будут синхронизированы.

← На главную