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

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

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

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

Почему стандартное сохранение настроек формы работает одинаково для всех объектов

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

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

Кроме того, такие типы данных, как СписокЗначений, Массив, Структура, ТаблицаЗначений и ДеревоЗначений, являются универсальными коллекциями значений. Они предназначены исключительно для алгоритмической обработки данных в оперативной памяти на клиенте или сервере и не поддерживаются СУБД в качестве базовых типов реквизитов объектов.

Рассмотрим основные практические способы сохранения списка значений для конкретного объекта.

Способ 1. Использование табличной части объекта

Наиболее правильным и архитектурно выверенным решением для хранения списка значений, привязанного к объекту, является использование табличной части.

Разберем преимущества данного подхода:

  1. Данные полностью доступны для выборки в языке запросов платформы.
  2. Поддерживается ссылочная целостность: при удалении связанных элементов система предупредит о наличии ссылок.
  3. Информация участвует в транзакции записи объекта и версионировании.
  4. Данные автоматически передаются при обмене в распределенных информационных базах (РИБ).

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


// Загрузка данных из табличной части в СписокЗначений на форме
РеквизитСписок.Очистить();
Для Каждого Стр Из Объект.ТабличнаяЧастьЗначений Цикл
    РеквизитСписок.Добавить(Стр.Значение);
КонецЦикла;

// Выгрузка данных из СпискаЗначений обратно в табличную часть перед записью
Объект.ТабличнаяЧастьЗначений.Очистить();
Для Каждого ЭлементСписка Из РеквизитСписок Цикл
    НоваяСтрока = Объект.ТабличнаяЧастьЗначений.Добавить();
    НоваяСтрока.Значение = ЭлементСписка.Значение;
КонецЦикла;

Способ 2. Реквизит объекта с типом ХранилищеЗначений

Если структура данных не требует выборки через запросы и не должна отображаться в стандартных отчетах, список значений можно упаковать в реквизит объекта с типом ХранилищеЗначений.

Разберем по шагам, как реализовать запись и чтение:

  1. Добавим в объект метаданных (справочник или документ) реквизит с типом ХранилищеЗначений.
  2. В обработчике перед записью объекта сериализуем коллекцию в хранилище со сжатием данных.
  3. В обработчике чтения объекта восстанавливаем исходный список.

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


// Сохранение списка значений в реквизит объекта
Объект.ХранилищеСписка = Новый ХранилищеЗначений(РеквизитСписок, Новый СжатиеДанных(9));

// Извлечение списка значений при открытии или чтении объекта
ЗначениеИзХранилища = Объект.ХранилищеСписка.Получить();
Если ТипЗнч(ЗначениеИзХранилища) = Тип("СписокЗначений") Тогда
    РеквизитСписок = ЗначениеИзХранилища;
Иначе
    РеквизитСписок.Очистить();
КонецЕсли;

Важно помнить: данные внутри ХранилищеЗначений недоступны для языка запросов 1С, а также не поддерживают автоматический контроль ссылочной целостности.

Способ 3. Сохранение в ХранилищеОбщихНастроек с уникальным ключом объекта

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

Рассмотрим пример реализации:


// Сохранение списка значений для конкретной ссылки
КлючОбъекта = Строка(Объект.Ссылка.УникальныйИдентификатор());
ХранилищеОбщихНастроек.Сохранить("НастройкиСпискаФормы", КлючОбъекта, РеквизитСписок);

// Загрузка списка значений по ссылке объекта
КлючОбъекта = Строка(Объект.Ссылка.УникальныйИдентификатор());
ЗагруженныеДанные = ХранилищеОбщихНастроек.Загрузить("НастройкиСпискаФормы", КлючОбъекта);

Если ТипЗнч(ЗагруженныеДанные) = Тип("СписокЗначений") Тогда
    РеквизитСписок = ЗагруженныеДанные;
КонецЕсли;

Обратите внимание на ограничения этого способа:

  1. Настройки привязываются к текущему пользователю и не будут видны другим пользователям информационной базы.
  2. При очистке пользовательского кэша или сбросе настроек базы данные могут быть безвозвратно удалены.
  3. При удалении самого объекта настройка остается в системных таблицах в виде потерянных данных.

Способ 4. Использование подчиненного регистра сведений

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

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

← На главную