Как сохранить настройки отбора Компоновщика настроек компоновки данных в обработке 1С?

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

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

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

Выясняем причину ошибки: почему падает ХранилищеОбщихНастроек?

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

ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастроек, Настройки);

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

Попытка упаковать его напрямую в структуру или передать в качестве параметра всегда будет приводить к ошибке формата.

Решение 1. Прямая сериализация настроек компоновщика

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

Давайте разберем по шагам, как правильно сохранить и восстановить эти настройки.

Код для сохранения настроек на сервере:


&НаСервере
Процедура СохранитьНастройкиНаСервере()
    
    // Получаем сериализуемый объект настроек из компоновщика
    НастройкиДляСохранения = ОтборПересчета.ПолучитьНастройки();
    
    КлючОбъекта = "Обработка_ПересчетТоваров_НастройкиОтбора";
    КлючНастроек = "ОсновныеНастройки";
    
    // Прямо сохраняем настройки в системное хранилище
    ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастроек, НастройкиДляСохранения);
    
КонецПроцедуры

Код для загрузки сохраненных настроек при открытии:


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

Почему использование ЗначениеВСтрокуВнутр — это плохая практика?

В некоторых старых решениях (включая итоговое сообщение на форуме) разработчики используют функции ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр() для преобразования настроек СКД в системную строку. Мы настоятельно не рекомендуем использовать этот подход в современных конфигурациях по следующим причинам:

  1. Зависимость от версии платформы: Формат внутренней строки генерируется самой платформой 1С. При обновлении версии платформы этот формат может незаметно измениться, из-за чего ранее сохраненные настройки пользователей перестанут считываться и вызовут аварийное завершение работы формы.
  2. Нечитаемость данных: Полученная строка представляет собой сложный массив системных идентификаторов, который невозможно прочесть или отредактировать при отладке или переносе данных между базами.

Решение 2. Современный и надежный способ — сериализация через XML (XDTO)

Если вам необходимо сохранить настройки не в системное хранилище общего назначения, а, например, записать их в текстовый реквизит справочника, регистр сведений или передать по сети, лучшим решением будет использование 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, Тип("НастройкиКомпоновкиДанных"));
    
    // Загружаем в наш компоновщик
    ОтборПересчета.ЗагрузитьНастройки(ВосстановленныеНастройки);
    
КонецПроцедуры

Решение 3. Использование пользовательских настроек вместо полных настроек

При работе с СКД важно разделять два понятия: полные настройки компоновки (НастройкиКомпоновкиДанных) и пользовательские настройки (ПользовательскиеНастройкиКомпоновкиДанных).

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

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

Пример работы с пользовательскими настройками:


// Сохранение пользовательских настроек
ПользовательскиеНастройки = КомпоновщикНастроек.ПользовательскиеНастройки;
ХранилищеОбщихНастроек.Сохранить("МойКлюч", "НастройкиПользователя", ПользовательскиеНастройки);

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

Решение 4. Автоматическое сохранение силами платформы (без кода)

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

  1. Откройте форму вашей обработки в конфигураторе.
  2. Перейдите в палитру свойств самой формы.
  3. Найдите группу свойств «Сохранение настроек».
  4. Установите свойство «Сохранение настроек» в значение Использовать.
  5. В свойстве «Сохраняемые данные» нажмите на ссылку «Открыть» и отметьте галочками те реквизиты, значения которых платформа должна запомнить (например, реквизиты с типом КомпоновщикНастроекКомпоновкиДанных).
  6. Установите свойство «Автоматическое сохранение настроек» в значение Истина.

Теперь платформа самостоятельно при закрытии формы запишет все выбранные данные в системное хранилище настроек текущего пользователя, а при открытии формы — автоматически подтянет их обратно.

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

Если ваша конфигурация разработана на основе БСП (а это практически все типовые решения от 1С, такие как УТ, ERP, КА, БП), крайне рекомендуется использовать встроенные общие модули БСП. Они содержат оптимизированные методы работы с настройками, учитывающие права доступа пользователей и кэширование данных.

Вместо прямого обращения к ХранилищеОбщихНастроек используйте вызовы функций из общего модуля БСП:


// Сохранение настроек через механизмы БСП
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить(
    "МояОбработка_Настройки", 
    "ОтборПересчета", 
    ОтборПересчета.ПолучитьНастройки()
);

// Восстановление настроек через механизмы БСП
ВосстановленныеНастройки = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
    "МояОбработка_Настройки", 
    "ОтборПересчета"
);

Если ВосстановленныеНастройки <> Неопределено Тогда
    ОтборПересчета.ЗагрузитьНастройки(ВосстановленныеНастройки);
КонецЕсли;

Резюме

Мы рассмотрели различные варианты решения проблемы сохранения отборов компоновщика настроек. Подведем итоги:

← На главную