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