Как программно получить список сохраняемых в настройках реквизитов управляемой формы и настроить автосохранение программных реквизитов в 1С

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

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

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

Ограничение платформы: можно ли программно взвести флаг «Сохранение»?

Сразу ответим на ключевой вопрос автора темы: напрямую управлять флажком «Сохранение» в колонке реквизитов формы с помощью встроенного языка нельзя.

Этот флажок относится к метаданным самой формы. В платформе 1С:Предприятие структура метаданных компилируется в момент сохранения конфигурации и в режиме «1С:Предприятие» (в рантайме) доступна только для чтения. Программное изменение метаданных форм не поддерживается.

Здесь важно не путать два похожих по смыслу свойства, с которыми часто возникает путаница у начинающих разработчиков:

  1. Сохранение данных в настройках формы — это свойство всей формы (СохранениеДанныхВНастройках) и конкретных реквизитов (флажок «Сохранение» в конфигураторе). Оно отвечает за запись значений реквизитов в системное системное хранилище настроек при закрытии формы и их автоматическое восстановление при открытии.
  2. Сохраняемые данные реквизита — это свойство конкретного реквизита формы (в конфигураторе отображается как «Сохраняемые данные», а в коде доступно через свойство РеквизитФормы.СохраняемыеДанные). Это свойство имеет тип Булево и отвечает исключительно за модифицированность формы. Если свойство установлено в значение Истина, то при изменении значения этого реквизита пользователем у формы взводится признак модифицированности (появляется звездочка * в заголовке окна), и система предложит сохранить изменения при закрытии. К автоматическому сохранению настроек формы это свойство отношения не имеет.

Таким образом, просто вызвать метод вроде Реквизит.Сохранение = Истина у нас не получится. Но это не значит, что задача не имеет красивого решения.

Как программно получить список реквизитов, для которых включено сохранение?

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

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

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


&НаСервере
Процедура ПриСохраненииДанныхВНастройкахНаСервере(Настройки)
    
    // Получаем список всех реквизитов, которые платформа собралась сохранять
    Для Каждого ЭлементНастройки Из Настройки Цикл
        ИмяРеквизита = ЭлементНастройки.Ключ;
        ЗначениеРеквизита = ЭлементНастройки.Значение;
        
        ЗаписьЖурналаРегистрации("НастройкиФормы", 
            УровеньЖурналаРегистрации.Информация, , , 
            "Сохраняется реквизит: " + ИмяРеквизита + " со значением: " + ЗначениеРеквизита);
    КонецЦикла;
    
КонецПроцедуры

Решение задачи: автосохранение программно созданных реквизитов

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

Рассмотрим проблему подробнее. Если у управляемой формы свойство СохранениеДанныхВНастройках установлено в значение Использовать список, то стандартное событие записи настроек формы сработает только в том случае, если пользователь интерактивно изменил хотя бы один статический реквизит, помеченный в конфигураторе флажком «Сохранение». Если пользователь менял только программно созданные реквизиты, платформа посчитает, что сохранять нечего, и событие сохранения просто не вызовется.

Чтобы обойти это поведение, мы задействуем специальное свойство управляемой формы — СохраняемыеВНастройкахДанныеМодифицированы.

Пошаговый алгоритм реализации

Шаг 1. Оповещение платформы о необходимости сохранения настроек

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


&НаКлиенте
Процедура ПриИзмененииДинамическогоРеквизита(Элемент)
    
    // Платформа теперь знает, что настройки формы изменились и их нужно записать
    ЭтаФорма.СохраняемыеВНастройкахДанныеМодифицированы = Истина;
    
КонецПроцедуры

Шаг 2. Запись программного реквизита в контейнер настроек

В серверном событии формы ПриСохраненииДанныхВНастройкахНаСервере мы вручную добавляем значение нашего программного реквизита в стандартный системный контейнер Настройки. Платформа сама запишет его в системное хранилище вместе со статическими реквизитами.


&НаСервере
Процедура ПриСохраненииДанныхВНастройкахНаСервере(Настройки)
    
    // Вставляем значение программно созданного реквизита в соответствие
    Настройки.Вставить("ИмяМоегоДинамическогоРеквизита", ИмяМоегоДинамическогоРеквизита);
    
КонецПроцедуры

Шаг 3. Восстановление значения при открытии формы

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


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

Полный пример реализации динамического реквизита с автосохранением

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


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

&НаКлиенте
Процедура ПрограммныйРеквизитПриИзменении(Элемент)
    
    // Сигнализируем платформе о необходимости вызвать сохранение настроек при закрытии
    ЭтаФорма.СохраняемыеВНастройкахДанныеМодифицированы = Истина;
    
КонецПроцедуры

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

&НаСервере
Процедура ПриЗагрузкеДанныхИзНастроекНаСервере(Настройки)
    
    // Восстанавливаем сохраненное ранее значение
    Если Настройки.Свойство("ПериодОтрезка") Тогда
        ЭтаФорма["ПериодОтрезка"] = Настройки.ПериодОтрезка;
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Функция ПолучитьЗначениеПрограммногоРеквизита(ИмяРеквизита)
    Возврат ЭтаФорма[ИмяРеквизита];
EndФункции

Преимущества описанного подхода

Использование связки свойства СохраняемыеВНастройкахДанныеМодифицированы и стандартных серверных событий сохранения/загрузки настроек дает разработчику целый ряд преимуществ:

Таким образом, несмотря на жесткое ограничение платформы по программному изменению флажка «Сохранение» у реквизитов, мы можем легко и элегантно встроить программно созданные данные в стандартный жизненный цикл управляемой формы 1С.

← На главную