Как программно загрузить настройки, отборы и параметры из неосновной схемы компоновки данных на форме отчета?

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

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

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

Выясним причину: почему простой загрузки настроек недостаточно

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

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

Способ 1. Полная программная инициализация и отключение стандартной загрузки

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

В модуле формы отчета реализуем следующий код:


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

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

&НаСервере
Процедура ПередЗагрузкойПользовательскихНастроекНаСервере(Контекст, Настройки)
    // Отключаем стандартную перезапись настроек из системного хранилища
    СтандартнаяОбработка = Ложь;
КонецПроцедуры

&НаСервере
Процедура ПередЗагрузкойВариантаНаСервере(Контекст, Настройки)
    // Блокируем восстановление стандартного варианта основной схемы
    СтандартнаяОбработка = Ложь;
КонецПроцедуры

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

Способ 2. Загрузка настроек из конкретного варианта альтернативной схемы

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


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

Способ 3. Программный вывод отчета без модификации компоновщика формы

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


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

Важные ограничения и нюансы архитектуры СКД

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

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