Разработка удобного интерфейса для пользователей часто требует сохранения промежуточных результатов работы. Одним из таких сценариев является сохранение настроек отбора в обработках, использующих систему компоновки данных (СКД). Пользователь тратит время на заполнение сложных фильтров, закрывает форму обработки, а при следующем запуске хочет видеть те же самые настройки.
В этой статье мы подробно разберем, почему возникает популярная ошибка «Ошибка формата объекта настроек» при попытке сохранить компоновщик напрямую, какие решения предлагает платформа 1С:Предприятие 8.3, и как реализовать надежное сохранение настроек с использованием современных стандартов разработки.
Рассмотрим стандартную ситуацию. Разработчик пытается сохранить реквизит формы или объекта, имеющий тип КомпоновщикНастроекКомпоновкиДанных, напрямую в системное хранилище настроек:
ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастроек, Настройки);
В этот момент платформа возвращает ошибку формата. Давайте проанализируем, почему это происходит. Дело в том, что системное хранилище настроек принимает только те типы данных, которые могут быть сериализованы (превращены в поток байтов или строку для записи в базу данных). Сам объект КомпоновщикНастроекКомпоновкиДанных является сложным интерфейсным объектом платформы и не подлежит прямой сериализации.
Попытка упаковать его напрямую в структуру или передать в качестве параметра всегда будет приводить к ошибке формата.
Чтобы обойти это ограничение, нам нужно сохранять не сам компоновщик, а объект настроек, который он внутри себя содержит. Объект типа НастройкиКомпоновкиДанных (получаемый через метод ПолучитьНастройки()) прекрасно сериализуется платформой.
Давайте разберем по шагам, как правильно сохранить и восстановить эти настройки.
Код для сохранения настроек на сервере:
&НаСервере
Процедура СохранитьНастройкиНаСервере()
// Получаем сериализуемый объект настроек из компоновщика
НастройкиДляСохранения = ОтборПересчета.ПолучитьНастройки();
КлючОбъекта = "Обработка_ПересчетТоваров_НастройкиОтбора";
КлючНастроек = "ОсновныеНастройки";
// Прямо сохраняем настройки в системное хранилище
ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастроек, НастройкиДляСохранения);
КонецПроцедуры
Код для загрузки сохраненных настроек при открытии:
&НаСервере
Процедура ВосстановитьНастройкиНаСервере()
КлючОбъекта = "Обработка_ПересчетТоваров_НастройкиОтбора";
КлючНастроек = "ОсновныеНастройки";
// Извлекаем настройки из хранилища
ВосстановленныеНастройки = ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, КлючНастроек);
Если ВосстановленныеНастройки <> Неопределено Тогда
// Загружаем настройки обратно в компоновщик на форме
ОтборПересчета.ЗагрузитьНастройки(ВосстановленныеНастройки);
КонецЕсли;
КонецПроцедуры
В некоторых старых решениях (включая итоговое сообщение на форуме) разработчики используют функции ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр() для преобразования настроек СКД в системную строку. Мы настоятельно не рекомендуем использовать этот подход в современных конфигурациях по следующим причинам:
Если вам необходимо сохранить настройки не в системное хранилище общего назначения, а, например, записать их в текстовый реквизит справочника, регистр сведений или передать по сети, лучшим решением будет использование XML-сериализации с помощью XDTO. Это гарантирует стабильность структуры данных при любых обновлениях 1С.
Рассмотрим пример реализации экспорта и импорта настроек через XML-строку.
Код для сериализации настроек в XML-строку:
&НаСервере
Функция ПолучитьНастройкиВФорматеXML()
Настройки = ОтборПересчета.ПолучитьНастройки();
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
// Сериализуем настройки компоновки данных по стандарту XML-схемы СКД
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Настройки, "settings", "http://v8.1c.ru/8.1/data-composition-system/settings");
Возврат ЗаписьXML.Закрыть();
КонецФункции
Код для десериализации настроек из XML-строки:
&НаСервере
Процедура ВосстановитьНастройкиИзXML(СтрокаXML)
Если ПустаяСтрока(СтрокаXML) Тогда
Возврат;
КонецЕсли;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СтрокаXML);
// Читаем объект настроек из XML
ВосстановленныеНастройки = СериализаторXDTO.ПрочитатьXML(ЧтениеXML, Тип("НастройкиКомпоновкиДанных"));
// Загружаем в наш компоновщик
ОтборПересчета.ЗагрузитьНастройки(ВосстановленныеНастройки);
КонецПроцедуры
При работе с СКД важно разделять два понятия: полные настройки компоновки (НастройкиКомпоновкиДанных) и пользовательские настройки (ПользовательскиеНастройкиКомпоновкиДанных).
Если вы сохраняете полные настройки, вы сохраняете всю структуру отчета/отбора, включая доступные поля, группировки и сортировки. Если в будущем разработчик обновит схему компоновки (добавит новое поле или изменит тип существующего), загрузка старых настроек может вызвать критическую ошибку.
Чтобы избежать этого, рекомендуется сохранять только пользовательские настройки. В них содержатся исключительно те значения фильтров и отборов, которые пользователь вывел на форму и изменил вручную.
Пример работы с пользовательскими настройками:
// Сохранение пользовательских настроек
ПользовательскиеНастройки = КомпоновщикНастроек.ПользовательскиеНастройки;
ХранилищеОбщихНастроек.Сохранить("МойКлюч", "НастройкиПользователя", ПользовательскиеНастройки);
// Восстановление пользовательских настроек
СохраненныеНастройки = ХранилищеОбщихНастроек.Загрузить("МойКлюч", "НастройкиПользователя");
Если СохраненныеНастройки <> Неопределено Тогда
КомпоновщикНастроек.ЗагрузитьПользовательскиеНастройки(СохраненныеНастройки);
КонецЕсли;
Если ваша обработка спроектирована в управляемом приложении, платформа 1С:Предприятие 8.3 позволяет сохранять настройки формы автоматически, вообще без написания программного кода. Давайте настроим этот механизм:
Использовать.КомпоновщикНастроекКомпоновкиДанных).Истина.Теперь платформа самостоятельно при закрытии формы запишет все выбранные данные в системное хранилище настроек текущего пользователя, а при открытии формы — автоматически подтянет их обратно.
Если ваша конфигурация разработана на основе БСП (а это практически все типовые решения от 1С, такие как УТ, ERP, КА, БП), крайне рекомендуется использовать встроенные общие модули БСП. Они содержат оптимизированные методы работы с настройками, учитывающие права доступа пользователей и кэширование данных.
Вместо прямого обращения к ХранилищеОбщихНастроек используйте вызовы функций из общего модуля БСП:
// Сохранение настроек через механизмы БСП
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить(
"МояОбработка_Настройки",
"ОтборПересчета",
ОтборПересчета.ПолучитьНастройки()
);
// Восстановление настроек через механизмы БСП
ВосстановленныеНастройки = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
"МояОбработка_Настройки",
"ОтборПересчета"
);
Если ВосстановленныеНастройки <> Неопределено Тогда
ОтборПересчета.ЗагрузитьНастройки(ВосстановленныеНастройки);
КонецЕсли;
Мы рассмотрели различные варианты решения проблемы сохранения отборов компоновщика настроек. Подведем итоги:
КомпоновщикНастроекКомпоновкиДанных напрямую — он не сериализуется.ПолучитьНастройки() для извлечения сериализуемого объекта НастройкиКомпоновкиДанных.ЗначениеВСтрокуВнутр(), отдавая предпочтение прямой передаче объектов в хранилище, XML-сериализации (XDTO) или механизмам БСП.