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

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

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

Разбор основной ошибки: Объект vs ТекущийОбъект

Проанализируем ситуацию, когда в обработчике ПередЗаписьюНаСервере мы пытаемся присвоить значение реквизиту. Ошибка Поле объекта не обнаружено "Объект.Отбор" возникает из-за непонимания разницы между данными формы и прикладным объектом.

На управляемой форме основной реквизит называется Объект (с типом ДанныеФормыСтруктура). В то же время, в процедуре ПередЗаписьюНаСервере платформа передает нам параметр ТекущийОбъект, который является самим прикладным объектом (например, СправочникОбъект.ИмяСправочника). Если реквизит Отбор (тип ХранилищеЗначения) создан в метаданных, но не вынесен на форму как реквизит, то обращение через Объект.Отбор вызовет ошибку, так как в данных формы этого поля просто нет. Правильно обращаться напрямую к загружаемому объекту базы данных.

Посмотрим на правильную реализацию сохранения:


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

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

Инициализация компоновщика настроек

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

Рассмотрим пример инициализации в обработчике создания формы:


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

Восстановление настроек при чтении данных

Запись данных в ХранилищеЗначения — это только половина дела. Чтобы пользователь увидел свои настройки при повторном открытии формы, их нужно извлечь. Проанализируем процедуру загрузки. Мы рекомендуем выносить её в отдельный метод или использовать обработчик ПриЧтенииНаСервере.


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

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

Работа с типизацией и сериализацией

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

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

Использование РеквизитФормыВЗначение

В некоторых сообщениях форума предлагалось использовать РеквизитФормыВЗначение. Этот метод действительно необходим, если логика обработки отбора вынесена в модуль объекта. Рассмотрим этот сценарий:


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

Заключение

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

← На главную