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

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

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

В чем причина рассинхронизации настроек и интерфейса формы

Проанализируем архитектуру работы компоновщика настроек (КомпоновщикНастроекКомпоновкиДанных). В нем параллельно существуют две различные коллекции настроек:

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

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

Способ 1. Прямое изменение элементов пользовательских настроек и почему опасен поиск по индексу

Рассмотрим попытку быстрого решения задачи: обратиться напрямую к элементам коллекции пользовательских настроек по их числовому номеру (индексу).

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


// Пример НЕБЕЗОПАСНОГО подхода с обращением по индексу
Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[5].Использование = Ложь;
Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[5].ПравоеЗначение = Неопределено;

Разберем, почему подобный подход считается крайне опасной практикой:

  1. Порядок элементов в коллекции ПользовательскиеНастройки.Элементы не является фиксированным. Любое добавление нового отбора или параметра разработчиком в конфигураторе сдвинет индексы.
  2. При смене варианта отчета или пользовательских манипуляциях с формой индекс [5] может указывать на совершенно другое поле или вызвать исключение «Индекс находится за границами массива».

Способ 2. Правильный алгоритм: поиск по Идентификатору пользовательской настройки

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

Рассмотрим по шагам универсальный алгоритм для программной установки параметров СКД:


// 1. Получаем параметр из основных настроек
ИмяПараметра = "ПлановыйВидЦен";
ПараметрСКД = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных(ИмяПараметра));

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

Теперь разберем аналогичный алгоритм для программного изменения или отключения элементов отбора СКД:


ПолеОтбора = Новый ПолеКомпоновкиДанных("Номенклатура");

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

Способ 3. Использование типовых методов БСП (Библиотека стандартных подсистем)

Если разработка ведется в типовых конфигурациях (таких как ERP, Управление торговлей 11, Комплексная автоматизация 2, Бухгалтерия предприятия 3.0, ЗУП 3), писать ручной поиск по идентификаторам не требуется. В составе БСП есть готовые и протестированные модули общего назначения.

Посмотрим на примеры работы с типовыми функциями БСП:

  1. Установка параметров отчета:
    
    // Автоматически находит параметр и обновляет как базовые, так и пользовательские настройки
    ОтчетыКлиентСервер.УстановитьПараметр(
        Отчет.КомпоновщикНастроек, 
        "ПлановыйВидЦен", 
        ПлановыйВидЦен, 
        Истина
    );
    
  2. Установка элементов отбора:
    
    // Устанавливает значение существующего отбора либо добавляет новый в пользовательские настройки
    ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(
        Отчет.КомпоновщикНастроек.ПользовательскиеНастройки, 
        "Организация", 
        ВыбраннаяОрганизация, 
        ВидСравненияКомпоновкиДанных.Равно, 
        , 
        Истина
    );
    

Важные нюансы при программном формировании отчета

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

Посмотрим, как правильно получать результирующие настройки:


// НЕПРАВИЛЬНО: берет только базовые настройки, игнорируя то, что ввел пользователь на форме
// НастройкиДляМакета = КомпоновщикНастроек.Настройки;

// ПРАВИЛЬНО: метод объединяет базовые настройки и пользовательские изменения с формы
НастройкиДляМакета = Отчет.КомпоновщикНастроек.ПолучитьНастройки();

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиДляМакета, ДанныеРасшифровки);

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

← На главную